Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100612082813

Diff

Diff from 1.261 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/mip/reader.c

Annotated File View

ragge
1.261
1 /*      $Id: reader.c,v 1.261 2010/06/12 08:28:13 ragge Exp $   */
ragge
1.72
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
ragge
1.31
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
ragge
1.1
62
ragge
1.123
63 /*
ragge
1.236
64  * Everything is entered via pass2_compile().  No functions are 
65  * allowed to recurse back into pass2_compile().
ragge
1.123
66  */
67
ragge
1.1
68 # include "pass2.h"
69
ragge
1.70
70 #include <string.h>
ragge
1.71
71 #include <stdarg.h>
ragge
1.94
72 #include <stdlib.h>
ragge
1.70
73
ragge
1.1
74 /*      some storage declarations */
75 int nrecur;
76 int lflag;
mickey
1.258
77 int x2debugudebugodebug;
ragge
1.103
78 int thisline;
ragge
1.72
79 int fregs;
ragge
1.123
80 int p2autooffp2maxautooff;
ragge
1.1
81
ragge
1.72
82 NODE *nodepole;
ragge
1.197
83 FILE *prfil;
ragge
1.238
84 struct interpass prepole;
ragge
1.23
85
ragge
1.37
86 void saveip(struct interpass *ip);
ragge
1.243
87 void deltemp(NODE *pvoid *);
ragge
1.232
88 static void cvtemps(struct interpass *ipoleint opint off);
ragge
1.72
89 NODE *store(NODE *);
ragge
1.242
90 static void fixxasm(struct p2env *);
ragge
1.65
91
ragge
1.72
92 static void gencode(NODE *pint cookie);
ragge
1.216
93 static void genxasm(NODE *p);
ragge
1.69
94
ragge
1.246
95 struct p2env p2env;
ragge
1.121
96
ragge
1.246
97 int
98 getlab2(void)
99 {
100         extern int getlab(void);
101         int rv = getlab();
102 #ifdef PCC_DEBUG
103         if (p2env.epp->ip_lblnum != rv)
104                 comperr("getlab2 error: %d != %d"p2env.epp->ip_lblnumrv);
105 #endif
106         p2env.epp->ip_lblnum++;
107         return rv;
108 }
ragge
1.241
109
ragge
1.26
110 #ifdef PCC_DEBUG
ragge
1.241
111 static int *lbldef, *lbluse;
ragge
1.26
112 static void
ragge
1.243
113 cktree(NODE *pvoid *arg)
ragge
1.26
114 {
ragge
1.241
115         int i;
116
ragge
1.26
117         if (p->n_op > MAXOP)
ragge
1.218
118                 cerror("%p) op %d slipped through"pp->n_op);
ragge
1.199
119         if (BTYPE(p->n_type) > MAXTYPES)
ragge
1.218
120                 cerror("%p) type %x slipped through"pp->n_type);
ragge
1.241
121         if (p->n_op == CBRANCH) {
122                  if (!logop(p->n_left->n_op))
123                         cerror("%p) not logop branch"p);
gmcgarry
1.251
124                 i = (int)p->n_right->n_lval;
ragge
1.242
125                 if (i < p2env.ipp->ip_lblnum || i >= p2env.epp->ip_lblnum)
ragge
1.241
126                         cerror("%p) label %d outside boundaries %d-%d",
ragge
1.242
127                             pip2env.ipp->ip_lblnump2env.epp->ip_lblnum);
128                 lbluse[i-p2env.ipp->ip_lblnum] = 1;
ragge
1.241
129         }
ragge
1.47
130         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
ragge
1.218
131                 cerror("%p) asgop %d slipped through"pp->n_op);
ragge
1.241
132         if (p->n_op == TEMP &&
ragge
1.242
133             (regno(p) < p2env.ipp->ip_tmpnum || regno(p) >= p2env.epp->ip_tmpnum))
ragge
1.241
134                 cerror("%p) temporary %d outside boundaries %d-%d",
ragge
1.242
135                     pregno(p), p2env.ipp->ip_tmpnump2env.epp->ip_tmpnum);
ragge
1.249
136         if (p->n_op == GOTO && p->n_left->n_op == ICON) {
gmcgarry
1.251
137                 i = (int)p->n_left->n_lval;
ragge
1.242
138                 if (i < p2env.ipp->ip_lblnum || i >= p2env.epp->ip_lblnum)
ragge
1.241
139                         cerror("%p) label %d outside boundaries %d-%d",
ragge
1.242
140                             pip2env.ipp->ip_lblnump2env.epp->ip_lblnum);
141                 lbluse[i-p2env.ipp->ip_lblnum] = 1;
ragge
1.241
142         }
143 }
144
145 /*
146  * Check that the trees are in a suitable state for pass2.
147  */
148 static void
ragge
1.244
149 sanitychecks(struct p2env *p2e)
ragge
1.241
150 {
151         struct interpass *ip;
152         int i;
153 #ifdef notyet
154         TMPMARK();
155 #endif
ragge
1.244
156         lbldef = tmpcalloc(sizeof(int) * (p2e->epp->ip_lblnum - p2e->ipp->ip_lblnum));
157         lbluse = tmpcalloc(sizeof(int) * (p2e->epp->ip_lblnum - p2e->ipp->ip_lblnum));
ragge
1.241
158
ragge
1.242
159         DLIST_FOREACH(ip, &p2env.ipoleqelem) {
ragge
1.241
160                 if (ip->type == IP_DEFLAB) {
161                         i = ip->ip_lbl;
ragge
1.244
162                         if (i < p2e->ipp->ip_lblnum || i >= p2e->epp->ip_lblnum)
ragge
1.241
163                                 cerror("label %d outside boundaries %d-%d",
ragge
1.244
164                                     ip2e->ipp->ip_lblnump2e->epp->ip_lblnum);
165                         lbldef[i-p2e->ipp->ip_lblnum] = 1;
ragge
1.241
166                 }
167                 if (ip->type == IP_NODE)
ragge
1.243
168                         walkf(ip->ip_nodecktree0);
ragge
1.241
169         }
ragge
1.244
170         for (i = 0i < (p2e->epp->ip_lblnum - p2e->ipp->ip_lblnum); i++)
ragge
1.241
171                 if (lbluse[i] != 0 && lbldef[i] == 0)
172                         cerror("internal label %d not defined",
ragge
1.244
173                             i + p2e->ipp->ip_lblnum);
ragge
1.241
174
175 #ifdef notyet
176         TMPFREE();
177 #endif
ragge
1.26
178 }
179 #endif
ragge
1.8
180
ragge
1.130
181 /*
ragge
1.244
182  * Look if a temporary comes from a on-stack argument, in that case
183  * use the already existing stack position instead of moving it to
184  * a new place, and remove the move-to-temp statement.
185  */
186 static int
187 stkarg(int tnrint *soff)
188 {
189         struct p2env *p2e = &p2env;
190         struct interpass *ip;
191         NODE *p;
192
ragge
1.248
193         ip = DLIST_NEXT((struct interpass *)p2e->ippqelem);
194         while (ip->type != IP_DEFLAB/* search for first DEFLAB */
195                 ip = DLIST_NEXT(ipqelem);
196
ragge
1.244
197         ip = DLIST_NEXT(ipqelem); /* first NODE */
198
199         for (; ip->type != IP_DEFLABip = DLIST_NEXT(ipqelem)) {
200                 if (ip->type != IP_NODE)
201                         continue;
202
203                 p = ip->ip_node;
ragge
1.247
204                 if (p->n_op == XASM)
205                         continue/* XXX - hack for x86 PIC */
ragge
1.244
206 #ifdef PCC_DEBUG
207                 if (p->n_op != ASSIGN || p->n_left->n_op != TEMP)
208                         comperr("temparg");
209 #endif
210                 if (p->n_right->n_op != OREG && p->n_right->n_op != UMUL)
211                         continue/* arg in register */
212                 if (tnr != regno(p->n_left))
213                         continue/* wrong assign */
214                 p = p->n_right;
215                 if (p->n_op == UMUL &&
216                     p->n_left->n_op == PLUS &&
217                     p->n_left->n_left->n_op == REG &&
218                     p->n_left->n_right->n_op == ICON)
gmcgarry
1.251
219                         *soff = (int)p->n_left->n_right->n_lval;
ragge
1.244
220                 else if (p->n_op == OREG)
gmcgarry
1.251
221                         *soff = (int)p->n_lval;
ragge
1.244
222                 else
223                         comperr("stkarg: bad arg");
224                 tfree(ip->ip_node);
225                 DLIST_REMOVE(ipqelem);
226                 return 1;
227         }
228         return 0;
229 }
230
231 /*
232  * See if an ADDROF is somewhere inside the expression tree.
233  * If so, fill in the offset table.
234  */
235 static void
236 findaof(NODE *pvoid *arg)
237 {
238         int *aof = arg;
239         int tnr;
240
241         if (p->n_op != ADDROF)
242                 return;
243         tnr = regno(p->n_left);
244         if (aof[tnr])
245                 return/* already gotten stack address */
246         if (stkarg(tnr, &aof[tnr]))
247                 return/* argument was on stack */
248         aof[tnr] = BITOOR(freetemp(szty(p->n_left->n_type)));
249 }
250
251 /*
ragge
1.89
252  * Check if a node has side effects.
253  */
254 static int
255 isuseless(NODE *n)
256 {
257         switch (n->n_op) {
ragge
1.216
258         case XASM:
ragge
1.89
259         case FUNARG:
260         case UCALL:
261         case UFORTCALL:
262         case FORCE:
263         case ASSIGN:
264         case CALL:
265         case FORTCALL:
266         case CBRANCH:
267         case RETURN:
268         case GOTO:
269         case STCALL:
270         case USTCALL:
271         case STASG:
272         case STARG:
273                 return 0;
274         default:
275                 return 1;
276         }
277 }
278
ragge
1.130
279 /*
280  * Delete statements with no meaning (like a+b; or 513.4;)
281  */
ragge
1.238
282 NODE *
ragge
1.89
283 deluseless(NODE *p)
284 {
285         struct interpass *ip;
286         NODE *l, *r;
287
288         if (optype(p->n_op) == LTYPE) {
289                 nfree(p);
290                 return NULL;
291         }
292         if (isuseless(p) == 0)
293                 return p;
294
295         if (optype(p->n_op) == UTYPE) {
296                 l = p->n_left;
297                 nfree(p);
298                 return deluseless(l);
299         }
300
301         /* Be sure that both leaves may be valid */
302         l = deluseless(p->n_left);
303         r = deluseless(p->n_right);
304         nfree(p);
305         if (l && r) {
ragge
1.201
306                 ip = ipnode(l);
307                 DLIST_INSERT_AFTER(&prepoleipqelem);
ragge
1.89
308                 return r;
309         } else if (l)
310                 return l;
311         else if (r)
312                 return r;
313         return NULL;
314 }
315
ragge
1.172
316 /*
317  * Receives interpass structs from pass1.
318  */
319 void
320 pass2_compile(struct interpass *ip)
321 {
ragge
1.260
322         void deljumps(struct p2env *);
ragge
1.244
323         struct p2env *p2e = &p2env;
324         int *addrp;
ragge
1.245
325         MARK mark;
ragge
1.244
326
ragge
1.172
327         if (ip->type == IP_PROLOG) {
ragge
1.244
328                 memset(p2e0sizeof(struct p2env));
329                 p2e->ipp = (struct interpass_prolog *)ip;
330                 DLIST_INIT(&p2e->ipoleqelem);
ragge
1.172
331         }
ragge
1.244
332         DLIST_INSERT_BEFORE(&p2e->ipoleipqelem);
ragge
1.172
333         if (ip->type != IP_EPILOG)
334                 return;
335
336 #ifdef PCC_DEBUG
337         if (e2debug) {
338                 printf("Entering pass2\n");
ragge
1.244
339                 printip(&p2e->ipole);
ragge
1.172
340         }
341 #endif
ragge
1.174
342
ragge
1.244
343         p2e->epp = (struct interpass_prolog *)DLIST_PREV(&p2e->ipoleqelem);
344         p2maxautooff = p2autooff = p2e->epp->ipp_autos;
ragge
1.174
345
ragge
1.241
346 #ifdef PCC_DEBUG
ragge
1.244
347         sanitychecks(p2e);
ragge
1.241
348 #endif
ragge
1.244
349         myreader(&p2e->ipole); /* local massage of input */
ragge
1.174
350
ragge
1.244
351         /*
352          * Do initial modification of the trees.  Two loops;
353          * - first, search for ADDROF of TEMPs, these must be
354          *   converterd to OREGs on stack.
355          * - second, do the actual conversions, in case of not xtemps
356          *   convert all temporaries to stack references.
357          */
ragge
1.245
358         markset(&mark);
ragge
1.244
359         if (p2e->epp->ip_tmpnum != p2e->ipp->ip_tmpnum) {
360                 addrp = tmpcalloc(sizeof(int) *
361                     (p2e->epp->ip_tmpnum - p2e->ipp->ip_tmpnum));
362                 addrp -= p2e->ipp->ip_tmpnum;
363         } else
364                 addrp = NULL;
365         if (xtemps) {
366                 DLIST_FOREACH(ip, &p2e->ipoleqelem) {
367                         if (ip->type == IP_NODE)
368                                 walkf(ip->ip_nodefindaofaddrp);
369                 }
370         }
ragge
1.246
371         DLIST_FOREACH(ip, &p2e->ipoleqelem)
ragge
1.244
372                 if (ip->type == IP_NODE)
373                         walkf(ip->ip_nodedeltempaddrp);
ragge
1.245
374         markfree(&mark);
ragge
1.244
375
376 #ifdef PCC_DEBUG
377         if (e2debug) {
378                 printf("Efter ADDROF/TEMP\n");
379                 printip(&p2e->ipole);
380         }
381 #endif
382
ragge
1.201
383         DLIST_INIT(&prepoleqelem);
ragge
1.244
384         DLIST_FOREACH(ip, &p2e->ipoleqelem) {
ragge
1.172
385                 if (ip->type != IP_NODE)
386                         continue;
387                 canon(ip->ip_node);
ragge
1.201
388                 if ((ip->ip_node = deluseless(ip->ip_node)) == NULL) {
ragge
1.172
389                         DLIST_REMOVE(ipqelem);
ragge
1.201
390                 } else while (!DLIST_ISEMPTY(&prepoleqelem)) {
gmcgarry
1.224
391                         struct interpass *tipp;
ragge
1.201
392
gmcgarry
1.224
393                         tipp = DLIST_NEXT(&prepoleqelem);
394                         DLIST_REMOVE(tippqelem);
395                         DLIST_INSERT_BEFORE(iptippqelem);
ragge
1.201
396                 }
ragge
1.172
397         }
398
ragge
1.244
399         fixxasm(p2e); /* setup for extended asm */
ragge
1.216
400
ragge
1.244
401         optimize(p2e);
402         ngenregs(p2e);
ragge
1.172
403
ragge
1.260
404         if (xssaflag && xtemps && xdeljumps)
405                 deljumps(p2e);
406
ragge
1.244
407         DLIST_FOREACH(ip, &p2e->ipoleqelem)
ragge
1.172
408                 emit(ip);
409 }
410
ragge
1.124
411 void
ragge
1.125
412 emit(struct interpass *ip)
ragge
1.124
413 {
gmcgarry
1.208
414         NODE *p, *r;
415         struct optab *op;
ragge
1.149
416         int o;
ragge
1.124
417
ragge
1.125
418         switch (ip->type) {
419         case IP_NODE:
420                 p = ip->ip_node;
ragge
1.124
421
ragge
1.149
422                 nodepole = p;
ragge
1.180
423                 canon(p); /* may convert stuff after genregs */
ragge
1.240
424                 if (c2debug > 1) {
425                         printf("emit IP_NODE:\n");
426                         fwalk(pe2print0);
427                 }
ragge
1.124
428                 switch (p->n_op) {
429                 case CBRANCH:
430                         /* Only emit branch insn if RESCC */
gmcgarry
1.208
431                         /* careful when an OPLOG has been elided */
432                         if (p->n_left->n_su == 0 && p->n_left->n_left != NULL) {
433                                 op = &table[TBLIDX(p->n_left->n_left->n_su)];
434                                 r = p->n_left;
435                         } else {
436                                 op = &table[TBLIDX(p->n_left->n_su)];
437                                 r = p;
438                         }
439                         if (op->rewrite & RESCC) {
ragge
1.124
440                                 o = p->n_left->n_op;
gmcgarry
1.208
441                                 gencode(rFORCC);
ragge
1.124
442                                 cbgen(op->n_right->n_lval);
gmcgarry
1.208
443                         } else {
444                                 gencode(rFORCC);
445                         }
ragge
1.124
446                         break;
447                 case FORCE:
ragge
1.151
448                         gencode(p->n_leftINREGS);
ragge
1.124
449                         break;
ragge
1.216
450                 case XASM:
451                         genxasm(p);
452                         break;
ragge
1.124
453                 default:
454                         if (p->n_op != REG || p->n_type != VOID/* XXX */
455                                 gencode(pFOREFF); /* Emit instructions */
456                 }
457
ragge
1.125
458                 tfree(p);
459                 break;
ragge
1.124
460         case IP_PROLOG:
461                 prologue((struct interpass_prolog *)ip);
462                 break;
463         case IP_EPILOG:
464                 eoftn((struct interpass_prolog *)ip);
ragge
1.174
465                 p2maxautooff = p2autooff = AUTOINIT/SZCHAR;
ragge
1.124
466                 break;
467         case IP_DEFLAB:
468                 deflab(ip->ip_lbl);
469                 break;
470         case IP_ASM:
gmcgarry
1.229
471                 printf("%s"ip->ip_asm);
ragge
1.124
472                 break;
473         default:
ragge
1.216
474                 cerror("emit %d"ip->type);
ragge
1.124
475         }
ragge
1.123
476 }
ragge
1.124
477
ragge
1.30
478 #ifdef PCC_DEBUG
ragge
1.1
479 char *cnames[] = {
480         "SANY",
481         "SAREG",
482         "SBREG",
ragge
1.153
483         "SCREG",
484         "SDREG",
ragge
1.1
485         "SCC",
486         "SNAME",
487         "SCON",
488         "SFLD",
489         "SOREG",
490         "STARNM",
491         "STARREG",
492         "INTEMP",
493         "FORARG",
494         "SWADD",
495         0,
ragge
1.72
496 };
ragge
1.1
497
ragge
1.2
498 /*
499  * print a nice-looking description of cookie
500  */
ragge
1.70
501 char *
ragge
1.2
502 prcook(int cookie)
503 {
ragge
1.70
504         static char buf[50];
ragge
1.1
505         int iflag;
506
ragge
1.70
507         if (cookie & SPECIAL) {
508                 switch (cookie) {
509                 case SZERO:
510                         return "SZERO";
511                 case SONE:
512                         return "SONE";
513                 case SMONE:
514                         return "SMONE";
515                 default:
ragge
1.200
516                         snprintf(bufsizeof(buf), "SPECIAL+%d"cookie & ~SPECIAL);
ragge
1.70
517                         return buf;
ragge
1.1
518                 }
ragge
1.70
519         }
ragge
1.1
520
521         flag = 0;
ragge
1.70
522         buf[0] = 0;
523         for (i = 0cnames[i]; ++i) {
524                 if (cookie & (1<<i)) {
525                         if (flag)
ragge
1.200
526                                 strlcat(buf"|"sizeof(buf));
ragge
1.1
527                         ++flag;
ragge
1.200
528                         strlcat(bufcnames[i], sizeof(buf));
ragge
1.1
529                 }
ragge
1.70
530         }
531         return buf;
532 }
ragge
1.30
533 #endif
ragge
1.1
534
ragge
1.151
535 int
ragge
1.69
536 geninsn(NODE *pint cookie)
537 {
ragge
1.71
538         NODE *p1, *p2;
ragge
1.236
539         int qorv = 0;
ragge
1.69
540
541 #ifdef PCC_DEBUG
542         if (odebug) {
ragge
1.70
543                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
544                 fwalk(pe2print0);
545         }
546 #endif
547
ragge
1.236
548         q = cookie & QUIET;
549         cookie &= ~QUIET/* XXX - should not be necessary */
550
ragge
1.69
551 again:  switch (o = p->n_op) {
ragge
1.71
552         case EQ:
553         case NE:
554         case LE:
555         case LT:
556         case GE:
557         case GT:
558         case ULE:
559         case ULT:
560         case UGE:
561         case UGT:
gmcgarry
1.208
562                 p1 = p->n_left;
563                 p2 = p->n_right;
ragge
1.210
564                 if (p2->n_op == ICON && p2->n_lval == 0 &&
ragge
1.256
565                     (dope[p1->n_op] & (FLOFLG|DIVFLG|SIMPFLG|SHFFLG))) {
ragge
1.236
566 #ifdef mach_pdp11 /* XXX all targets? */
567                         if ((rv = geninsn(p1FORCC|QUIET)) != FFAIL)
568                                 break;
569 #else
570                         if (findops(p1FORCC) > 0)
gmcgarry
1.208
571                                 break;
ragge
1.236
572 #endif
gmcgarry
1.208
573                 }
ragge
1.159
574                 rv = relops(p);
575                 break;
ragge
1.71
576
ragge
1.69
577         case PLUS:
578         case MINUS:
579         case MUL:
580         case DIV:
581         case MOD:
582         case AND:
583         case OR:
584         case ER:
585         case LS:
586         case RS:
ragge
1.151
587                 rv = findops(pcookie);
588                 break;
ragge
1.77
589
ragge
1.69
590         case ASSIGN:
ragge
1.236
591 #ifdef FINDMOPS
592                 if ((rv = findmops(pcookie)) != FFAIL)
593                         break;
594                 /* FALLTHROUGH */
595 #endif
ragge
1.174
596         case STASG:
ragge
1.151
597                 rv = findasg(pcookie);
598                 break;
ragge
1.159
599
ragge
1.178
600         case UMUL/* May turn into an OREG */
ragge
1.179
601                 rv = findumul(pcookie);
602                 break;
603
ragge
1.69
604         case REG:
ragge
1.144
605         case TEMP:
ragge
1.72
606         case NAME:
ragge
1.71
607         case ICON:
ragge
1.213
608         case FCON:
ragge
1.69
609         case OREG:
ragge
1.152
610                 rv = findleaf(pcookie);
611                 break;
ragge
1.69
612
ragge
1.172
613         case STCALL:
614         case CALL:
615                 /* CALL arguments are handled special */
616                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
ragge
1.239
617                         (void)geninsn(p1->n_rightFOREFF);
618                 (void)geninsn(p1FOREFF);
ragge
1.172
619                 /* FALLTHROUGH */
ragge
1.206
620         case FLD:
ragge
1.86
621         case COMPL:
ragge
1.85
622         case UMINUS:
ragge
1.71
623         case PCONV:
624         case SCONV:
ragge
1.198
625 /*      case INIT: */
ragge
1.70
626         case GOTO:
627         case FUNARG:
ragge
1.172
628         case STARG:
ragge
1.72
629         case UCALL:
ragge
1.103
630         case USTCALL:
ragge
1.207
631         case ADDROF:
ragge
1.155
632                 rv = finduni(pcookie);
633                 break;
ragge
1.69
634
ragge
1.71
635         case CBRANCH:
636                 p1 = p->n_left;
637                 p2 = p->n_right;
gmcgarry
1.251
638                 p1->n_label = (int)p2->n_lval;
ragge
1.239
639                 (void)geninsn(p1FORCC);
ragge
1.187
640                 p->n_su = 0;
ragge
1.71
641                 break;
642
ragge
1.187
643         case FORCE/* XXX needed? */
ragge
1.239
644                 (void)geninsn(p->n_leftINREGS);
ragge
1.187
645                 p->n_su = 0/* su calculations traverse left */
ragge
1.71
646                 break;
647
ragge
1.216
648         case XASM:
649                 for (p1 = p->n_leftp1->n_op == CMp1 = p1->n_left)
ragge
1.239
650                         (void)geninsn(p1->n_rightFOREFF);
651                 (void)geninsn(p1FOREFF);
ragge
1.216
652                 break;  /* all stuff already done? */
653
654         case XARG:
655                 /* generate code for correct class here */
gmcgarry
1.250
656 #if 0
657                 geninsn(p->n_left1 << p->n_label);
658 #endif
ragge
1.216
659                 break;
660
ragge
1.69
661         default:
ragge
1.174
662                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
663         }
ragge
1.236
664         if (rv == FFAIL && !q)
ragge
1.160
665                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
666         if (rv == FRETRY)
667                 goto again;
ragge
1.236
668 #ifdef PCC_DEBUG
669         if (odebug) {
670                 printf("geninsn(%p, %s) rv %d\n"pprcook(cookie), rv);
671                 fwalk(pe2print0);
672         }
673 #endif
ragge
1.153
674         return rv;
ragge
1.69
675 }
676
ragge
1.72
677 /*
678  * Store a given subtree in a temporary location.
679  * Return an OREG node where it is located.
680  */
681 NODE *
682 store(NODE *p)
ragge
1.2
683 {
ragge
1.130
684         extern struct interpass *storesave;
685         struct interpass *ip;
686         NODE *q, *r;
687         int s;
ragge
1.49
688
ragge
1.130
689         s = BITOOR(freetemp(szty(p->n_type)));
690         q = mklnode(OREGsFPREGp->n_type);
691         r = mklnode(OREGsFPREGp->n_type);
692         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
693
ragge
1.149
694         storesave = ip;
ragge
1.72
695         return r;
ragge
1.8
696 }
ragge
1.1
697
ragge
1.170
698 #ifdef PCC_DEBUG
699 #define CDEBUG(x) if (c2debug) printf x
700 #else
701 #define CDEBUG(x)
702 #endif
703
ragge
1.69
704 /*
ragge
1.188
705  * Do a register-register move if necessary.
706  */
707 static void
708 ckmove(NODE *pNODE *q)
709 {
ragge
1.189
710         if (q->n_op != REG || p->n_reg == -1)
ragge
1.188
711                 return/* no register */
712         if (DECRA(p->n_reg0) == DECRA(q->n_reg0))
713                 return/* no move necessary */
ragge
1.190
714         CDEBUG(("rmove: node %p, %s -> %s\n"prnames[DECRA(q->n_reg0)],
715             rnames[DECRA(p->n_reg0)]));
ragge
1.188
716         rmove(DECRA(q->n_reg0), DECRA(p->n_reg0), p->n_type);
717         q->n_reg = q->n_rval = DECRA(p->n_reg0);
718 }
719
720 /*
721  * Rewrite node to register after instruction emit.
ragge
1.75
722  */
723 static void
gmcgarry
1.224
724 rewrite(NODE *pint dorewriteint cookie)
ragge
1.75
725 {
ragge
1.79
726         NODE *l, *r;
727         int o;
728
ragge
1.80
729         l = getlr(p'L');
730         r = getlr(p'R');
ragge
1.79
731         o = p->n_op;
ragge
1.75
732         p->n_op = REG;
ragge
1.76
733         p->n_lval = 0;
ragge
1.95
734         p->n_name = "";
ragge
1.158
735
ragge
1.257
736         if (o == ASSIGN || o == STASG) {
ragge
1.190
737                 /* special rewrite care */
738                 int reg = DECRA(p->n_reg0);
ragge
1.191
739 #define TL(x) (TBLIDX(x->n_su) || x->n_op == REG)
ragge
1.190
740                 if (p->n_reg == -1)
741                         ;
ragge
1.191
742                 else if (TL(l) && (DECRA(l->n_reg0) == reg))
ragge
1.190
743                         ;
ragge
1.191
744                 else if (TL(r) && (DECRA(r->n_reg0) == reg))
ragge
1.190
745                         ;
ragge
1.191
746                 else if (TL(l))
ragge
1.190
747                         rmove(DECRA(l->n_reg0), regp->n_type);
ragge
1.191
748                 else if (TL(r))
ragge
1.190
749                         rmove(DECRA(r->n_reg0), regp->n_type);
750 #if 0
751                 else
752                         comperr("rewrite");
753 #endif
ragge
1.191
754 #undef TL
ragge
1.190
755         }
ragge
1.79
756         if (optype(o) != LTYPE)
757                 tfree(l);
758         if (optype(o) == BITYPE)
759                 tfree(r);
gmcgarry
1.224
760         if (dorewrite == 0)
ragge
1.190
761                 return;
mickey
1.205
762         CDEBUG(("rewrite: %p, reg %s\n"p,
763             p->n_reg == -1"<none>" : rnames[DECRA(p->n_reg0)]));
ragge
1.187
764         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
765 }
766
ragge
1.228
767 #ifndef XASM_TARGARG
768 #define XASM_TARGARG(x,y) 0
769 #endif
770
ragge
1.216
771 /*
772  * printout extended assembler.
773  */
774 void
775 genxasm(NODE *p)
776 {
777         NODE *q, **nary;
778         int n = 1o = 0;
779         char *w;
780
ragge
1.228
781         if (p->n_left->n_op != ICON || p->n_left->n_type != STRTY) {
782                 for (q = p->n_leftq->n_op == CMq = q->n_left)
783                         n++;
ragge
1.254
784                 nary = tmpcalloc(sizeof(NODE *)*(n+1));
ragge
1.228
785                 o = n;
786                 for (q = p->n_leftq->n_op == CMq = q->n_left) {
787                         gencode(q->n_right->n_leftINREGS);
788                         nary[--o] = q->n_right;
789                 }
790                 gencode(q->n_leftINREGS);
791                 nary[--o] = q;
792         } else
793                 nary = 0;
ragge
1.216
794
795         w = p->n_name;
796         putchar('\t');
797         while (*w != 0) {
798                 if (*w == '%') {
ragge
1.225
799                         if (w[1] == '%')
800                                 putchar('%');
ragge
1.228
801                         else if (XASM_TARGARG(wnary))
802                                 ; /* handled by target */
ragge
1.225
803                         else if (w[1] < '0' || w[1] > (n + '0'))
ragge
1.228
804                                 uerror("bad xasm arg number %c"w[1]);
ragge
1.253
805                         else {
806                                 if (w[1] == (n + '0'))
807                                         q = nary[(int)w[1]-'0' - 1]; /* XXX */
808                                 else
809                                         q = nary[(int)w[1]-'0'];
810                                 adrput(stdoutq->n_left);
811                         }
ragge
1.216
812                         w++;
ragge
1.228
813                 } else if (*w == '\\') { /* Always 3-digit octal */
814                         int num = *++w - '0';
815                         num = (num << 3) + *++w - '0';
816                         num = (num << 3) + *++w - '0';
817                         putchar(num);
ragge
1.216
818                 } else
819                         putchar(*w);
820                 w++;
821         }
822         putchar('\n');
823 }
824
ragge
1.69
825 void
ragge
1.72
826 gencode(NODE *pint cookie)
ragge
1.69
827 {
828         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
829         NODE *p1, *l, *r;
ragge
1.190
830         int o = optype(p->n_op);
ragge
1.240
831 #ifdef FINDMOPS
832         int ismops = (p->n_op == ASSIGN && (p->n_flags & 1));
833 #endif
ragge
1.188
834
835         l = p->n_left;
836         r = p->n_right;
ragge
1.69
837
ragge
1.186
838         if (TBLIDX(p->n_su) == 0) {
839                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
840                         gencode(r0);
ragge
1.185
841                 if (optype(p->n_op) != LTYPE)
ragge
1.188
842                         gencode(l0);
ragge
1.186
843                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
844                         gencode(r0);
ragge
1.185
845                 return;
846         }
ragge
1.69
847
ragge
1.170
848         CDEBUG(("gencode: node %p\n"p));
849
850         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
851                 return/* meaningless move to itself */
ragge
1.175
852
853         if (callop(p->n_op))
854                 lastcall(p); /* last chance before function args */
855         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
856                 /* Print out arguments first */
ragge
1.188
857                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
858                         gencode(p1->n_rightFOREFF);
859                 gencode(p1FOREFF);
ragge
1.190
860                 o = UTYPE/* avoid going down again */
ragge
1.175
861         }
862
ragge
1.190
863         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
864                 gencode(rINREGS);
865                 if (q->rewrite & RRIGHT)
866                         ckmove(pr);
867         }
ragge
1.190
868         if (o != LTYPE) {
ragge
1.188
869                 gencode(lINREGS);
ragge
1.240
870 #ifdef FINDMOPS
871                 if (ismops)
872                         ;
873                 else
874 #endif
875                      if (q->rewrite & RLEFT)
ragge
1.188
876                         ckmove(pl);
877         }
ragge
1.190
878         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
879                 gencode(rINREGS);
880                 if (q->rewrite & RRIGHT)
881                         ckmove(pr);
882         }
ragge
1.185
883
ragge
1.236
884 #ifdef FINDMOPS
ragge
1.240
885         if (ismops) {
ragge
1.236
886                 /* reduce right tree to make expand() work */
887                 if (optype(r->n_op) != LTYPE) {
ragge
1.240
888                         p->n_op = r->n_op;