Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120925150707

Diff

Diff from 1.16 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/arch/amd64/order.c

Annotated File View

ragge
1.16
1 /*      $Id: order.c,v 1.16 2012/09/25 15:07:07 ragge Exp $     */
mickey
1.1
2 /*
3  * Copyright (c) 2008 Michael Shalayeff
4  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30
31 # include "pass2.h"
32
33 #include <string.h>
34
35 int canaddr(NODE *);
36
37 /* is it legal to make an OREG or NAME entry which has an
38  * offset of off, (from a register of r), if the
39  * resulting thing had type t */
40 int
41 notoff(TWORD tint rCONSZ offchar *cp)
42 {
ragge
1.15
43         if (off > MAX_INT || off < MIN_INT)
44                 return 1/* max signed 32-bit offset */
mickey
1.1
45         return(0);  /* YES */
46 }
47
48 /*
ragge
1.7
49  * Check if LS and try to make it indexable.
50  * Ignore SCONV to long.
51  * Return 0 if failed.
52  */
53 static int
54 findls(NODE *pint check)
55 {
56         CONSZ c;
57
58         if (p->n_op == SCONV && p->n_type == LONG && p->n_left->n_type == INT)
59                 p = p->n_left/* Ignore pointless SCONVs here */
60         if (p->n_op != LS || p->n_right->n_op != ICON)
61                 return 0;
ragge
1.11
62         if ((c = p->n_right->n_lval) != 1 && c != 2 && c != 3)
ragge
1.7
63                 return 0;
64         if (check == 1 && p->n_left->n_op != REG)
65                 return 0;
66         if (!isreg(p->n_left))
67                 (void)geninsn(p->n_leftINAREG);
68         return 1;
69 }
70
71 /*
mickey
1.1
72  * Turn a UMUL-referenced node into OREG.
73  * Be careful about register classes, this is a place where classes change.
ragge
1.7
74  *
75  * AMD64 (and i386) have a quite powerful addressing scheme:
76  *      :       4(%rax)         4 + %rax
77  *      :       4(%rbx,%rax,8)  4 + %rbx + %rax * 8
78  *      :       4(,%rax)        4 + %rax * 8
79  * The 8 above can be 1,2,4 or 8.
mickey
1.1
80  */
81 void
82 offstar(NODE *pint shape)
83 {
ragge
1.7
84         NODE *l;
mickey
1.1
85
ragge
1.7
86         if (x2debug) {
mickey
1.1
87                 printf("offstar(%p)\n"p);
ragge
1.7
88                 fwalk(pe2print0);
89         }
mickey
1.1
90
91         if (isreg(p))
ragge
1.7
92                 return/* Matched (%rax) */
93
94         if (findls(p0))
95                 return/* Matched (,%rax,8) */
mickey
1.1
96
ragge
1.16
97         if ((p->n_op == PLUS || p->n_op == MINUS) &&
98             p->n_left->n_op == ICON &&
99             notoff(00,  p->n_left->n_lval0) == 0) {
ragge
1.7
100                 l = p->n_right;
101                 if (isreg(l))
102                         return/* Matched 4(%rax) */
103                 if (findls(l0))
104                         return/* Matched 4(,%rax,8) */
105                 if (l->n_op == PLUS && isreg(l->n_right)) {
106                         if (findls(l->n_left0))
107                                 return/* Matched 4(%rbx,%rax,8) */
108                         (void)geninsn(l->n_leftINAREG);
109                         return/* Generate 4(%rbx,%rax) */
mickey
1.1
110                 }
ragge
1.7
111                 (void)geninsn(lINAREG);
112                 return/* Generate 4(%rbx) */
113         }
114
115         if (p->n_op == PLUS) {
116                 if (!isreg(p->n_left)) /* ensure right is REG */
117                         (void)geninsn(p->n_leftINAREG);
118                 if (isreg(p->n_right))
119                         return/* Matched (%rax,%rbx) */
120                 if (findls(p->n_right0))
121                         return/* Matched (%rax,%rbx,4) */
122                 (void)geninsn(p->n_rightINAREG);
123                 return/* Generate (%rbx,%rax) */
mickey
1.1
124         }
ragge
1.7
125                 
mickey
1.1
126         (void)geninsn(pINAREG);
127 }
128
129 /*
130  * Do the actual conversion of offstar-found OREGs into real OREGs.
ragge
1.7
131  * For simple OREGs conversion should already be done.
mickey
1.1
132  */
133 void
134 myormake(NODE *q)
135 {
ragge
1.7
136         static int shtbl[] = { 1,2,4,8 };
mickey
1.1
137         NODE *p, *r;
ragge
1.7
138         CONSZ c = 0;
139         int r1r2sh;
140         int mkconv = 0;
141         char *n = "";
mickey
1.1
142
ragge
1.7
143 #define risreg(p)       (p->n_op == REG)
144         if (x2debug) {
mickey
1.1
145                 printf("myormake(%p)\n"q);
ragge
1.7
146                 fwalk(qe2print0);
147         }
148         r1 = r2 = MAXREGS;
149         sh = 1;
150
151         r = p = q->n_left;
152
153         if ((p->n_op == PLUS || p->n_op == MINUS) && p->n_left->n_op == ICON) {
154                 c = p->n_left->n_lval;
155                 n = p->n_left->n_name;
156                 p = p->n_right;
157         }
158
159         if (p->n_op == PLUS && risreg(p->n_left)) {
160                 r1 = regno(p->n_left);
161                 p = p->n_right;
162         }
mickey
1.1
163
ragge
1.7
164         if (findls(p1)) {
165                 if (p->n_op == SCONV)
166                         p = p->n_left;
167                 sh = shtbl[(int)p->n_right->n_lval];
168                 r2 = regno(p->n_left);
169                 mkconv = 1;
170         } else if (risreg(p)) {
171                 r2 = regno(p);
172                 mkconv = 1;
173         } //else
174         //      comperr("bad myormake tree");
175
176         if (mkconv == 0)
177                 return;
178
179         q->n_op = OREG;
180         q->n_lval = c;
181         q->n_rval = R2PACK(r1r2sh);
182         q->n_name = n;
183         tfree(r);
184         if (x2debug) {
185                 printf("myormake converted %p\n"q);
186                 fwalk(qe2print0);
mickey
1.1
187         }
188 }
189
190 /*
191  * Shape matches for UMUL.  Cooperates with offstar().
192  */
193 int
194 shumul(NODE *pint shape)
195 {
196
197         if (x2debug)
198                 printf("shumul(%p)\n"p);
199
200         /* Turns currently anything into OREG on x86 */
201         if (shape & SOREG)
202                 return SROREG;
203         return SRNOPE;
204 }
205
206 /*
207  * Rewrite operations on binary operators (like +, -, etc...).
208  * Called as a result of table lookup.
209  */
210 int
211 setbin(NODE *p)
212 {
213
214         if (x2debug)
215                 printf("setbin(%p)\n"p);
216         return 0;
217
218 }
219
220 /* setup for assignment operator */
221 int
222 setasg(NODE *pint cookie)
223 {
224         if (x2debug)
225                 printf("setasg(%p)\n"p);
226         return(0);
227 }
228
229 /* setup for unary operator */
230 int
231 setuni(NODE *pint cookie)
232 {
233         return 0;
234 }
235
236 /*
237  * Special handling of some instruction register allocation.
238  */
239 struct rspecial *
240 nspecial(struct optab *q)
241 {
ragge
1.5
242         switch (q->op) {
243         case SCONV:
244                 if ((q->ltype & TINT) &&
245                     q->rtype == (TLONGLONG|TULONGLONG|TLONG|TULONG)) {
246                         static struct rspecial s[] = { 
247                                 { NLEFTRAX }, { NRESRAX }, { 0 } };
248                         return s;
249                 }
250                 break;
mickey
1.1
251
ragge
1.6
252         case DIV:
mickey
1.1
253                 {
254                         static struct rspecial s[] = {
ragge
1.6
255                                 { NEVERRAX }, { NEVERRDX },
256                                 { NLEFTRAX }, { NRESRAX },
257                                 { NORIGHTRDX }, { NORIGHTRAX }, { 0 } };
mickey
1.1
258                         return s;
259                 }
ragge
1.6
260                 break;
mickey
1.1
261
ragge
1.6
262         case MOD:
ragge
1.14
263                 if (q->ltype & TUCHAR) {
264                         static struct rspecial s[] = {
265                                 { NEVERRAX },
266                                 { NLEFTRAX }, { NRESRAX },
267                                 { NORIGHTRAX }, { 0 } };
268                         return s;
269                 } else {
mickey
1.1
270                         static struct rspecial s[] = {
271                                 { NEVERRAX }, { NEVERRDX },
ragge
1.6
272                                 { NLEFTRAX }, { NRESRDX },
mickey
1.1
273                                 { NORIGHTRDX }, { NORIGHTRAX }, { 0 } };
274                         return s;
275                 }
276                 break;
ragge
1.6
277
ragge
1.9
278         case STARG:
279                 {
280                         static struct rspecial s[] = {
281                                 { NEVERRDI }, 
282                                 { NLEFTRSI },
283                                 { NEVERRCX }, { 0 } };
284                         return s;
285                 }
286
ragge
1.6
287         case STASG:
288                 {
mickey
1.1
289                         static struct rspecial s[] = {
ragge
1.9
290                                 { NEVERRDI }, 
291                                 { NRIGHTRSI }, { NOLEFTRSI },
292                                 { NOLEFTRCX }, { NORIGHTRCX },
293                                 { NEVERRCX }, { 0 } };
mickey
1.1
294                         return s;
ragge
1.6
295                 }
296
mickey
1.1
297         case MUL:
ragge
1.12
298                 if (q->lshape == SAREG) {
mickey
1.1
299                         static struct rspecial s[] = {
ragge
1.12
300                                 { NEVERRAX },
301                                 { NLEFTRAX }, { NRESRAX }, { 0 } };
mickey
1.1
302                         return s;
303                 }
304                 break;
ragge
1.12
305
mickey
1.1
306         case LS:
307         case RS:
mickey
1.2
308                 {
309                         static struct rspecial s[] = {
ragge
1.5
310                                 { NRIGHTRCX }, { NOLEFTRCX }, { 0 } };
mickey
1.2
311                         return s;
312                 }
mickey
1.1
313                 break;
314
315         default:
316                 break;
317         }
318         comperr("nspecial entry %d"q - table);
319         return 0/* XXX gcc */
320 }
321
322 /*
323  * Set evaluation order of a binary node if it differs from default.
324  */
325 int
326 setorder(NODE *p)
327 {
328         return 0/* nothing differs on x86 */
329 }
330
331 /*
332  * set registers in calling conventions live.
333  */
334 int *
335 livecall(NODE *p)
336 {
ragge
1.10
337         static int r[NTEMPREG+1];
338         NODE *q;
339         int cr = 0;
340
341         if (optype(p->n_op) != BITYPE)
342                 return r[0] = -1r;
343
344         for (q = p->n_rightq->n_op == CMq = q->n_left) {
345                 if (q->n_right->n_op == ASSIGN &&
346                     q->n_right->n_left->n_op == REG)
347                         r[cr++] = regno(q->n_right->n_left);
348         }
349         if (q->n_op == ASSIGN && q->n_left->n_op == REG)
350                 r[cr++] = regno(q->n_left);
351         r[cr++] = -1;
ragge
1.4
352         return r;
mickey
1.1
353 }
354
355 /*
356  * Signal whether the instruction is acceptable for this target.
357  */
358 int
359 acceptable(struct optab *op)
360 {
361         return 1;
362 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-10-31 15:20 +0100