Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050917075840

Diff

Diff from 1.26 to:

Annotations

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

Annotated File View

ragge
1.26
1 /*      $Id: order.c,v 1.26 2005/09/17 07:58:40 ragge Exp $     */
ragge
1.1
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29
30 # include "pass2.h"
31
32 int canaddr(NODE *);
33
34 /* should we delay the INCR or DECR operation p */
35 int
36 deltest(NODE *p)
37 {
38         return 0;
39 }
40
41 /*
42  * Check if p can be autoincremented.
43  * XXX - nothing can be autoincremented for now.
44  */
45 int
46 autoincr(NODE *p)
47 {
48         return 0;
49 }
50
51 /* is it legal to make an OREG or NAME entry which has an
52  * offset of off, (from a register of r), if the
53  * resulting thing had type t */
54 int
55 notoff(TWORD tint rCONSZ offchar *cp)
56 {
57         return(0);  /* YES */
58 }
59
ragge
1.12
60 /*
61  * Turn a UMUL-referenced node into OREG.
62  */
ragge
1.10
63 int
ragge
1.1
64 offstar(NODE *p)
65 {
66         if (x2debug)
67                 printf("offstar(%p)\n"p);
68
69         ifp->n_op == PLUS || p->n_op == MINUS ){
70                 ifp->n_right->n_op == ICON ){
ragge
1.11
71                         geninsn(p->n_leftINTAREG|INAREG);
ragge
1.10
72                         p->n_su = -1;
73                         return 1;
ragge
1.1
74                 }
75         }
ragge
1.10
76         geninsn(pINTAREG|INAREG);
77         return 0;
ragge
1.1
78 }
79
80 /*
ragge
1.12
81  * Shape matches for UMUL.  Cooperates with offstar().
82  */
83 int
84 shumul(NODE *p)
85 {
86
87         if (x2debug)
88                 printf("shumul(%p)\n"p);
89
90         /* Always turn it into OREG on x86 */
91         return SOREG;
92 }
93
94 /*
ragge
1.1
95  * Rewrite increment/decrement operation.
96  */
97 int
98 setincr(NODE *p)
99 {
100         if (x2debug)
101                 printf("setincr(%p)\n"p);
102
103         return(0);
104 }
105
106 /*
107  * Rewrite operations on binary operators (like +, -, etc...).
108  * Called as a result of table lookup.
109  */
110 int
111 setbin(NODE *p)
112 {
ragge
1.4
113
114         if (x2debug)
115                 printf("setbin(%p)\n"p);
ragge
1.10
116         return 0;
ragge
1.4
117
ragge
1.1
118 }
119
120 /* setup for assignment operator */
121 int
ragge
1.10
122 setasg(NODE *pint cookie)
ragge
1.1
123 {
124         if (x2debug)
125                 printf("setasg(%p)\n"p);
ragge
1.10
126         return(0);
ragge
1.1
127 }
128
ragge
1.10
129 /* setup for unary operator */
ragge
1.1
130 int
ragge
1.10
131 setuni(NODE *pint cookie)
ragge
1.1
132 {
ragge
1.10
133         return 0;
ragge
1.1
134 }
135
ragge
1.24
136 /*
137  * Special handling of some instruction register allocation.
ragge
1.25
138  * - left is the register that left node wants.
139  * - right is the register that right node wants.
140  * - res is in which register the result will end up.
141  * - mask is registers that will be clobbered.
ragge
1.24
142  */
ragge
1.26
143 struct rspecial *
144 nspecial(struct optab *q)
ragge
1.24
145 {
ragge
1.26
146         static int eax[] = { EAX, -1 };
147         static int eaxedx[] = { EAXEDX, -1 };
148         static int edx[] = { EDX, -1 };
149         static struct rspecial div = { eax0eaxedxeax },
150             mod = { eax0eaxedxedx },
151             scconv = { 000eaxedx },
152             ipconv = { eax00eaxedx };
153
ragge
1.24
154         switch (q->op) {
155         case DIV:
ragge
1.26
156                 return ÷
ragge
1.24
157         case MOD:
ragge
1.26
158                 return &mod;
159 #if 0
ragge
1.24
160                 *left = REGBIT(EAX);
161                 *right = 0;
162                 *res = q->op == DIV ? REGBIT(EAX) : REGBIT(EDX);
163                 *mask = REGBIT(EAX)|REGBIT(EDX);
ragge
1.26
164 #endif
ragge
1.25
165         case SCONV:
166                 if ((q->ltype == TSHORT || q->ltype == TCHAR) &&
167                     (q->rtype & (TLONGLONG|TULONGLONG))) {
ragge
1.26
168                         return &scconv;
169 #if 0
ragge
1.25
170                         *mask = *left = *right = 0;
171                         *res = REGBIT(EAX)|REGBIT(EDX);
172                         break;
ragge
1.26
173 #endif
ragge
1.25
174                 } else if ((q->ltype & (TINT|TUNSIGNED|TPOINT)) &&
175                     (q->rtype & (TLONGLONG|TULONGLONG))) {
ragge
1.26
176                         return &ipconv;
177 #if 0
ragge
1.25
178                         *left = REGBIT(EAX);
179                         *mask = *right = 0;
180                         *res = REGBIT(EAX)|REGBIT(EDX);
181                         break;
ragge
1.26
182 #endif
ragge
1.25
183                 }
ragge
1.24
184         default:
ragge
1.25
185                 comperr("nspecial entry %d"q - table);
ragge
1.24
186         }
ragge
1.26
187         return 0/* XXX gcc */
ragge
1.24
188 }
189
ragge
1.15
190 /*
191  * Splitup a function call and give away its arguments first.
192  */
193 void
ragge
1.19
194 gencall(NODE *pNODE *prev)
ragge
1.15
195 {
ragge
1.22
196         NODE *n = 0/* XXX gcc */
ragge
1.15
197         static int storearg(NODE *);
198         int o = p->n_op;
199         int ty = optype(o);
200
201         if (ty == LTYPE)
202                 return;
203
ragge
1.19
204         switch (o) {
205         case CALL:
206                 /* Normal call, just push args and be done with it */
207                 p->n_op = UCALL;
208 //printf("call\n");
209                 gencall(p->n_leftp);
ragge
1.15
210                 p->n_rval = storearg(p->n_right);
ragge
1.19
211 //printf("end call\n");
212                 break;
213
214         case UFORTCALL:
215         case FORTCALL:
216                 comperr("FORTCALL");
217
218         case USTCALL:
219         case STCALL:
220                 /*
221                  * Structure return.  Look at the node above
222                  * to decide about buffer address:
223                  * - FUNARG, allocate space on stack, don't remove.
224                  * - nothing, allocate space on stack and remove.
225                  * - STASG, get the address of the left side as arg.
ragge
1.22
226                  * - FORCE, this ends up in a return, get supplied addr.
ragge
1.19
227                  * (this is not pretty, but what to do?)
228                  */
229                 if (prev == NULL || prev->n_op == FUNARG) {
230                         /* Create nodes to generate stack space */
231                         n = mkbinode(ASSIGNmklnode(REG0STKREGINT),
232                             mkbinode(MINUSmklnode(REG0STKREGINT),
233                             mklnode(ICONp->n_stsize0INT), INT), INT);
234 //printf("stsize %d\n", p->n_stsize);
235                         pass2_compile(ipnode(n));
236                 } else if (prev->n_op == STASG) {
237                         n = prev->n_left;
238                         if (n->n_op == UMUL)
239                                 n = nfree(n);
240                         else if (n->n_op == NAME) {
241                                 n->n_op = ICON/* Constant reference */
242                                 n->n_type = INCREF(n->n_type);
243                         } else
244                                 comperr("gencall stasg");
ragge
1.22
245                 } else if (prev->n_op == FORCE) {
246                         ; /* do nothing here */
ragge
1.21
247                 } else {
ragge
1.19
248                         comperr("gencall bad op %d"prev->n_op);
ragge
1.21
249                 }
ragge
1.19
250
251                 /* Deal with standard arguments */
252                 gencall(p->n_leftp);
253                 if (o == STCALL) {
254                         p->n_op = USTCALL;
255                         p->n_rval = storearg(p->n_right);
256                 } else
257                         p->n_rval = 0;
258                 /* push return struct address */
259                 if (prev == NULL || prev->n_op == FUNARG) {
260                         n = mklnode(REG0STKREGINT);
261                         if (p->n_rval)
262                                 n = mkbinode(PLUSn,
263                                     mklnode(ICONp->n_rval0INT), INT);
264                         pass2_compile(ipnode(mkunode(FUNARGn0INT)));
265                         if (prev == NULL)
266                                 p->n_rval += p->n_stsize/4;
ragge
1.22
267                 } else if (prev->n_op == FORCE) {
268                         /* return value for this function */
269                         n = mklnode(OREG8FPREGINT);
270                         pass2_compile(ipnode(mkunode(FUNARGn0INT)));
271                         p->n_rval++;
ragge
1.19
272                 } else {
273                         pass2_compile(ipnode(mkunode(FUNARGn0INT)));
274                         n = p;
275                         *prev = *p;
276                         nfree(n);
277                 }
278 //printf("end stcall\n");
279                 break;
280
281         default:
282                 if (ty != UTYPE)
283                         gencall(p->n_rightp);
284                 gencall(p->n_leftp);
285                 break;
ragge
1.15
286         }
287 }
288
289 /*
290  * Create separate node trees for function arguments.
291  */
292 static int
293 storearg(NODE *p)
294 {
295         static void storecall(NODE *);
296         struct interpass *ip;
297         NODE *np;
298         int tsz;
299         extern int thisline;
300
ragge
1.19
301 #if 0
ragge
1.15
302         np = (p->n_op == CM ? p->n_right : p);
303         gencall(np);
ragge
1.19
304 #endif
ragge
1.15
305
306         ip = tmpalloc(sizeof(struct interpass));
307         ip->type = IP_NODE;
308         ip->lineno = thisline;
309
310         if (p->n_op == CM) {
311                 np = p->n_left;
312                 if (p->n_right->n_op == STARG) {
313                         NODE *op = p;
314                         p = p->n_right;
315                         nfree(op);
ragge
1.19
316                         tsz = (p->n_stsize+3)/4;
ragge
1.15
317                 } else {
318                         p->n_type = p->n_right->n_type;
319                         p->n_left = p->n_right;
320                         tsz = szty(p->n_type);
321                 }
322                 p->n_op = FUNARG;
323                 ip->ip_node = p;
324                 pass2_compile(ip);
325                 return storearg(np) + tsz;
326         } else {
327                 if (p->n_op != STARG) {
328                         np = talloc();
329                         np->n_type = p->n_type;
330                         np->n_op = FUNARG;
331                         np->n_left = p;
332                         p = np;
333                         tsz = szty(p->n_type);
334                 } else {
335                         p->n_op = FUNARG;
ragge
1.19
336                         tsz = (p->n_stsize+3)/4;
ragge
1.15
337                 }
338                 ip->ip_node = p;
339                 pass2_compile(ip);
340                 return tsz;
341         }
342 }
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-01 01:59 +0200