Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20090813080125

Diff

Diff from 1.251 to:

Annotations

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

Annotated File View

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