Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060204174346

Diff

Diff from 1.172 to:

Annotations

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

Annotated File View

ragge
1.172
1 /*      $Id: reader.c,v 1.172 2006/02/04 17:43:46 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 /*
64  * processing order for nodes:
65  * - myreader()
66  * - gencall()
67  * - delay()
68  * - canon()
69  * - deluseless()
70  * - saves trees here if optimizing
71  */
72
ragge
1.1
73 # include "pass2.h"
74
ragge
1.70
75 #include <string.h>
ragge
1.71
76 #include <stdarg.h>
ragge
1.94
77 #include <stdlib.h>
ragge
1.70
78
ragge
1.1
79 /*      some storage declarations */
80 int nrecur;
81 int lflag;
ragge
1.9
82 int x2debug;
ragge
1.1
83 int udebug = 0;
ragge
1.103
84 int thisline;
ragge
1.72
85 int fregs;
ragge
1.123
86 int p2autooffp2maxautooff;
ragge
1.1
87
ragge
1.72
88 NODE *nodepole;
ragge
1.169
89 FILE *prfil = stdout;
ragge
1.23
90
ragge
1.10
91 int e2print(NODE *pint downint *aint *b);
ragge
1.37
92 void saveip(struct interpass *ip);
93 void deljumps(void);
ragge
1.40
94 void deltemp(NODE *p);
ragge
1.97
95 void mkhardops(NODE *p);
ragge
1.37
96 void optdump(struct interpass *ip);
ragge
1.40
97 void cvtemps(struct interpass *epil);
ragge
1.72
98 NODE *store(NODE *);
ragge
1.104
99 void rcount(void);
ragge
1.124
100 void compile2(struct interpass *ip);
101 void compile3(struct interpass *ip);
102 void compile4(struct interpass *ip);
103 struct interpass delayq;
ragge
1.65
104
ragge
1.72
105 static void gencode(NODE *pint cookie);
ragge
1.69
106
ragge
1.150
107 char *ltyp[] = { """LREG""LOREG""LTEMP" };
108 char *rtyp[] = { """RREG""ROREG""RTEMP" };
ragge
1.37
109
ragge
1.121
110 /* used when removing nodes */
111 struct tmpsave {
112         struct tmpsave *next;
113         CONSZ tempaddr;
114         int tempno;
115 } *tmpsave;
116
ragge
1.46
117 #define DELAYS 20
118 NODE *deltrees[DELAYS];
119 int deli;
ragge
1.26
120
121 #ifdef PCC_DEBUG
122 static void
123 cktree(NODE *p)
124 {
125         if (p->n_op > MAXOP)
126                 cerror("op %d slipped through"p->n_op);
ragge
1.35
127         if (p->n_op == CBRANCH && !logop(p->n_left->n_op))
128                 cerror("not logop branch");
ragge
1.47
129         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
130                 cerror("asgop %d slipped through"p->n_op);
ragge
1.26
131 }
132 #endif
ragge
1.8
133
ragge
1.130
134 /*
135  * See if post-decrement and post-increment operators can be delayed
136  * past this statement.  This is only possible if it do not end up
137  * after a function call.
138  * There may be instructions that will do post-in/decrement, therefore
139  * call special routines to check if we can do this.
140  */
ragge
1.46
141 void
142 delay(NODE *p)
143 {
ragge
1.125
144         struct interpass *ip;
145         NODE *q;
ragge
1.128
146
ragge
1.46
147         int ty = optype(p->n_op);
148
149         switch (p->n_op) {
ragge
1.68
150         case UCALL:
ragge
1.46
151         case STCALL:
ragge
1.68
152         case USTCALL:
ragge
1.46
153         case FORTCALL:
ragge
1.68
154         case UFORTCALL:
ragge
1.46
155         case CBRANCH:
ragge
1.125
156                 /* for the moment, don't delay past a conditional context, or
ragge
1.46
157                  * inside of a call */
158                 return;
159
ragge
1.67
160         case UMUL:
ragge
1.46
161                 /* if *p++, do not rewrite */
162                 ifautoincrp ) ) return;
163                 break;
164
165         case INCR:
166         case DECR:
ragge
1.83
167                 break;
ragge
1.46
168                 ifdeltestp ) ){
ragge
1.125
169                         ip = ipnode(tcopy(p));
170                         DLIST_INSERT_BEFORE(&delayqipqelem);
171                         q = p->n_left;
172                         nfree(p->n_right); /* zap constant */
173                         *p = *q;
174                         nfree(q);
175                         return;
ragge
1.83
176                 }
ragge
1.46
177
ragge
1.83
178         }
ragge
1.46
179
180         if (ty == BITYPE)
181                 delay(p->n_right);
182         if (ty != LTYPE)
183                 delay(p->n_left);
ragge
1.2
184 }
ragge
1.1
185
ragge
1.89
186 /*
187  * Check if a node has side effects.
188  */
189 static int
190 isuseless(NODE *n)
191 {
192         switch (n->n_op) {
193         case FUNARG:
194         case UCALL:
195         case UFORTCALL:
196         case FORCE:
197         case INIT:
198         case ASSIGN:
199         case INCR:
200         case DECR:
201         case CALL:
202         case FORTCALL:
203         case CBRANCH:
204         case RETURN:
205         case GOTO:
206         case STCALL:
207         case USTCALL:
208         case STASG:
209         case STARG:
210                 return 0;
211         default:
212                 return 1;
213         }
214 }
215
ragge
1.130
216 /*
217  * Delete statements with no meaning (like a+b; or 513.4;)
218  */
ragge
1.89
219 static NODE *
220 deluseless(NODE *p)
221 {
222         struct interpass *ip;
223         NODE *l, *r;
224
225         if (optype(p->n_op) == LTYPE) {
226                 nfree(p);
227                 return NULL;
228         }
229         if (isuseless(p) == 0)
230                 return p;
231
232         if (optype(p->n_op) == UTYPE) {
233                 l = p->n_left;
234                 nfree(p);
235                 return deluseless(l);
236         }
237
238         /* Be sure that both leaves may be valid */
239         l = deluseless(p->n_left);
240         r = deluseless(p->n_right);
241         nfree(p);
242         if (l && r) {
243                 /* Put left on queue first */
244                 ip = tmpalloc(sizeof(*ip));
245                 ip->type = IP_NODE;
246                 ip->lineno = 0/* XXX */
247                 ip->ip_node = l;
248                 pass2_compile(ip);
249                 return r;
250         } else if (l)
251                 return l;
252         else if (r)
253                 return r;
254         return NULL;
255 }
256
ragge
1.172
257 static struct interpass ipole;
258 struct interpass_prolog *epp;
259
260 #if 0
261 static NODE *
262 fixargs(NODE *pstruct interpass *ip)
263 {
264         struct interpass *ip2;
265         int num;
266
267         if (canaddr(p))
268                 return p;
269         num = epp->ip_tmpnum++;
270         ip2 = ipnode(mkbinode(ASSIGN
271             mklnode(TEMPnum0p->n_type), pp->n_type));
272         DLIST_INSERT_BEFORE(ipip2qelem);
273         return mklnode(TEMPnum0p->n_type);
274 }
275
276 /*
277  * Gencall() is the first function in pass2.  It cuts out the 
278  * call arguments and replaces them with temp variables.
279  */
280 static void
281 xgencall(NODE *pstruct interpass *ip)
282 {
283         int o = p->n_op;
284         int ty = optype(o);
285
286         if (ty == LTYPE)
287                 return;
288
289         if (ty != UTYPE)
290                 xgencall(p->n_rightip);
291         xgencall(p->n_leftip);
292
293         if (o != CALL)
294                 return;
295
296         if (p->n_right->n_op == CM) {
297                 p = p->n_right;
298                 while (p->n_left->n_op == CM) {
299                         p->n_right = fixargs(p->n_rightip);
300                         p = p->n_left;
301                 }
302                 p->n_right = fixargs(p->n_rightip);
303                 p->n_left = fixargs(p->n_leftip);
304         } else
305                 p->n_right = fixargs(p->n_rightip);
306 }
307 #endif
308
309 /*
310  * Receives interpass structs from pass1.
311  */
312 void
313 pass2_compile(struct interpass *ip)
314 {
315         if (ip->type == IP_PROLOG) {
316                 tmpsave = NULL;
317                 DLIST_INIT(&ipoleqelem);
318         }
319         DLIST_INSERT_BEFORE(&ipoleipqelem);
320         if (ip->type != IP_EPILOG)
321                 return;
322
323 #ifdef PCC_DEBUG
324         if (e2debug) {
325                 printf("Entering pass2\n");
326                 printip(&ipole);
327         }
328 #endif
329         epp = (struct interpass_prolog *)DLIST_PREV(&ipoleqelem);
330         p2maxautooff = p2autooff = epp->ipp_autos;
331         DLIST_FOREACH(ip, &ipoleqelem) {
332                 if (ip->type != IP_NODE)
333                         continue;
334                 myreader(ip->ip_node); /* local massage of input */
335                 if (xtemps == 0)
336                         walkf(ip->ip_nodedeltemp);
337                 DLIST_INIT(&delayqqelem);
338                 delay(ip->ip_node);
339                 while (DLIST_NEXT(&delayqqelem) != &delayq) {
340                         struct interpass *ip2;
341                         ip2 = DLIST_NEXT(&delayqqelem);
342                         DLIST_REMOVE(ip2qelem);
343                         DLIST_INSERT_AFTER(ipip2qelem);
344                         ip = ip2;
345                 }
346
347         }
348         DLIST_FOREACH(ip, &ipoleqelem) {
349                 if (ip->type != IP_NODE)
350                         continue;
351                 canon(ip->ip_node);
352                 walkf(ip->ip_nodecktree);
353                 if ((ip->ip_node = deluseless(ip->ip_node)) == NULL)
354                         DLIST_REMOVE(ipqelem);
355         }
356
357         optimize(&ipole);
358         ngenregs(&ipole);
359
360         DLIST_FOREACH(ip, &ipoleqelem)
361                 emit(ip);
362 }
363
364 #if 0
ragge
1.123
365 /*
366  * Receives interpass structs from pass1.
367  */
368 void
369 pass2_compile(struct interpass *ip)
370 {
371
372         if (ip->type == IP_NODE) {
373                 myreader(ip->ip_node); /* local massage of input */
374                 mkhardops(ip->ip_node);
375                 gencall(ip->ip_nodeNIL);
ragge
1.160
376                 if (xtemps == 0)
377                         walkf(ip->ip_nodedeltemp);
ragge
1.124
378                 compile2(ip);
379         } else
380                 compile4(ip);
381 }
382
383 void
384 compile2(struct interpass *ip)
385 {
386         DLIST_INIT(&delayqqelem);
387         delay(ip->ip_node);
388         compile3(ip);
389         while (DLIST_NEXT(&delayqqelem) != &delayq) {
390                 ip = DLIST_NEXT(&delayqqelem);
391                 DLIST_REMOVE(ipqelem);
392                 compile3(ip);
393         }
394 }
395
396 void
397 compile3(struct interpass *ip)
398 {
399         NODE *p = ip->ip_node;
400
401         canon(p);
402         if ((p = deluseless(p)) == NULL)
403                 return/* nothing to do */
404 #ifdef PCC_DEBUG
405         walkf(pcktree);
406         if (e2debug) {
ragge
1.149
407                 printf("Entering pass2\n");
ragge
1.124
408                 fwalk(pe2print0);
ragge
1.123
409         }
ragge
1.124
410 #endif
411         ip->ip_node = p;
412         compile4(ip);
413 }
414
ragge
1.149
415 /*
416  * Save a complete function before doing anything with it in both the
417  * optimized and unoptimized case.
418  */
419 void
420 compile4(struct interpass *ip)
421 {
422         struct interpass_prolog *epp;
423
ragge
1.160
424         if (ip->type == IP_PROLOG) {
425                 tmpsave = NULL;
ragge
1.149
426                 DLIST_INIT(&ipoleqelem);
ragge
1.160
427         }
ragge
1.149
428
429         DLIST_INSERT_BEFORE(&ipoleipqelem);
430
431         if (ip->type != IP_EPILOG)
432                 return;
433
434 #ifdef PCC_DEBUG
435         if (e2debug)
436                 printip(&ipole);
437 #endif
438         epp = (struct interpass_prolog *)DLIST_PREV(&ipoleqelem);
439         p2maxautooff = p2autooff = epp->ipp_autos;
440
441         optimize(&ipole);
442         ngenregs(&ipole);
443
444         DLIST_FOREACH(ip, &ipoleqelem)
445                 emit(ip);
446 }
ragge
1.172
447 #endif
ragge
1.124
448
449 void
ragge
1.125
450 emit(struct interpass *ip)
ragge
1.124
451 {
452         NODE *p;
ragge
1.149
453         int o;
ragge
1.124
454
ragge
1.125
455         switch (ip->type) {
456         case IP_NODE:
457                 p = ip->ip_node;
ragge
1.124
458
ragge
1.149
459                 nodepole = p;
ragge
1.124
460                 switch (p->n_op) {
461                 case CBRANCH:
462                         /* Only emit branch insn if RESCC */
463                         if (table[TBLIDX(p->n_left->n_su)].rewrite & RESCC) {
464                                 o = p->n_left->n_op;
465                                 gencode(pFORCC);
466                                 cbgen(op->n_right->n_lval);
467                         } else
468                                 gencode(pFORCC);
469                         break;
470                 case FORCE:
ragge
1.151
471                         gencode(p->n_leftINREGS);
ragge
1.124
472                         break;
473                 default:
474                         if (p->n_op != REG || p->n_type != VOID/* XXX */
475                                 gencode(pFOREFF); /* Emit instructions */
476                 }
477
ragge
1.125
478                 tfree(p);
479                 break;
ragge
1.124
480         case IP_PROLOG:
481                 prologue((struct interpass_prolog *)ip);
482                 break;
483         case IP_EPILOG:
484                 eoftn((struct interpass_prolog *)ip);
485                 tmpsave = NULL/* Always forget old nodes */
486                 p2maxautooff = p2autooff = AUTOINIT;
487                 break;
488         case IP_DEFLAB:
489                 deflab(ip->ip_lbl);
490                 break;
491         case IP_ASM:
492                 printf("\t%s\n"ip->ip_asm);
493                 break;
494         default:
495                 cerror("compile4 %d"ip->type);
496         }
ragge
1.123
497 }
ragge
1.124
498
ragge
1.30
499 #ifdef PCC_DEBUG
ragge
1.1
500 char *cnames[] = {
501         "SANY",
502         "SAREG",
503         "SBREG",
ragge
1.153
504         "SCREG",
505         "SDREG",
ragge
1.1
506         "SCC",
507         "SNAME",
508         "SCON",
509         "SFLD",
510         "SOREG",
511         "STARNM",
512         "STARREG",
513         "INTEMP",
514         "FORARG",
515         "SWADD",
516         0,
ragge
1.72
517 };
ragge
1.1
518
ragge
1.2
519 /*
520  * print a nice-looking description of cookie
521  */
ragge
1.70
522 char *
ragge
1.2
523 prcook(int cookie)
524 {
ragge
1.70
525         static char buf[50];
ragge
1.1
526         int iflag;
527
ragge
1.70
528         if (cookie & SPECIAL) {
529                 switch (cookie) {
530                 case SZERO:
531                         return "SZERO";
532                 case SONE:
533                         return "SONE";
534                 case SMONE:
535                         return "SMONE";
536                 default:
537                         sprintf(buf"SPECIAL+%d"cookie & ~SPECIAL);
538                         return buf;
ragge
1.1
539                 }
ragge
1.70
540         }
ragge
1.1
541
542         flag = 0;
ragge
1.70
543         buf[0] = 0;
544         for (i = 0cnames[i]; ++i) {
545                 if (cookie & (1<<i)) {
546                         if (flag)
547                                 strcat(buf"|");
ragge
1.1
548                         ++flag;
ragge
1.70
549                         strcat(bufcnames[i]);
ragge
1.1
550                 }
ragge
1.70
551         }
552         return buf;
553 }
ragge
1.1
554
ragge
1.30
555 #endif
ragge
1.1
556
557 int odebug = 0;
558
ragge
1.151
559 int
ragge
1.69
560 geninsn(NODE *pint cookie)
561 {
ragge
1.71
562         NODE *p1, *p2;
ragge
1.151
563         int orv = 0;
ragge
1.69
564
565 #ifdef PCC_DEBUG
566         if (odebug) {
ragge
1.70
567                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
568                 fwalk(pe2print0);
569         }
570 #endif
571
572 again:  switch (o = p->n_op) {
ragge
1.71
573         case EQ:
574         case NE:
575         case LE:
576         case LT:
577         case GE:
578         case GT:
579         case ULE:
580         case ULT:
581         case UGE:
582         case UGT:
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
599         case INCR:
600         case DECR:
ragge
1.160
601                 rv = findops(pcookie);
602                 if (rv != FFAIL)
603                         break;
604
ragge
1.77
605                 /*
606                  * Rewrite x++ to (x = x + 1) -1;
607                  */
608                 p1 = p->n_left;
609                 p->n_op = o == INCR ? MINUS : PLUS;
610                 /* Assign node */
611                 p2 = talloc();
612                 p2->n_type = p->n_type;
613                 p2->n_name = "";
614                 p2->n_op = ASSIGN;
615                 p->n_left = p2;
616                 p->n_left->n_left = p1;
617                 /* incr/decr node */
618                 p2 = talloc();
619                 p2->n_type = p->n_type;
620                 p2->n_name = "";
621                 p2->n_op = o == INCR ? PLUS : MINUS;
622                 p->n_left->n_right = p2;
623                 /* const one node */
624                 p->n_left->n_right->n_right = tcopy(p->n_right);
625                 /* input tree */
626                 p1 = tcopy(p1);
627                 /* idstrip(p1); */
628                 p->n_left->n_right->n_left = p1;
ragge
1.108
629                 canon(p); /* if fields involved */
ragge
1.77
630                 goto again;
ragge
1.71
631
ragge
1.69
632         case ASSIGN:
ragge
1.151
633                 rv = findasg(pcookie);
634                 break;
ragge
1.159
635
ragge
1.69
636         case REG:
ragge
1.144
637         case TEMP:
ragge
1.72
638         case NAME:
ragge
1.71
639         case ICON:
ragge
1.69
640         case OREG:
ragge
1.152
641                 rv = findleaf(pcookie);
642                 break;
ragge
1.69
643
ragge
1.82
644         case UMUL:
645                 /*
646                  * If we end up here with an UMUL, try to fold it into
647                  * an OREG anyway.
648                  */
ragge
1.86
649                 if (p->n_type == STRTY) {
650                         /* XXX - what to do here? */
651                         geninsn(p->n_leftcookie);
652                         p->n_su = -1;
653                         break;
654                 }
ragge
1.169
655 #if 0
ragge
1.151
656                 if (offstar(p->n_left0)) {
ragge
1.84
657                         p->n_op = OREG;
658                         if ((rv = findleaf(pcookie)) < 0)
659                                 comperr("bad findleaf"); /* XXX */
ragge
1.162
660                         p->n_su |= LOREG;
ragge
1.84
661                         p->n_op = UMUL;
662                         break;
663                 }
ragge
1.109
664                 /* FALLTHROUGH */
ragge
1.169
665 #else
666                 /* create oreg anyway */
667                 (void)offstar(p->n_left0);
668                 p->n_op = OREG;
669                 if ((rv = findleaf(pcookie)) < 0)
670                         comperr("bad findleaf"); /* XXX */
671                 p->n_su |= LOREG;
672                 p->n_op = UMUL;
673                 break;
674 #endif
ragge
1.82
675
ragge
1.172
676         case STCALL:
677         case CALL:
678                 /* CALL arguments are handled special */
679                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
680                         geninsn(p1->n_rightFOREFF);
681                 geninsn(p1FOREFF);
682                 /* FALLTHROUGH */
ragge
1.86
683         case COMPL:
ragge
1.85
684         case UMINUS:
ragge
1.71
685         case PCONV:
686         case SCONV:
687         case INIT:
ragge
1.70
688         case GOTO:
689         case FUNARG:
ragge
1.172
690         case STARG:
ragge
1.72
691         case UCALL:
ragge
1.103
692         case USTCALL:
ragge
1.155
693                 rv = finduni(pcookie);
694                 break;
ragge
1.69
695
ragge
1.71
696         case CBRANCH:
697                 p1 = p->n_left;
698                 p2 = p->n_right;
699                 p1->n_label = p2->n_lval;
700                 o = p1->n_op;
701                 geninsn(p1FORCC);
702                 p->n_su = -1/* su calculations traverse left */
703                 break;
704
705         case FORCE:
ragge
1.151
706                 geninsn(p->n_leftINREGS);
ragge
1.71
707                 p->n_su = -1/* su calculations traverse left */
708                 break;
709
ragge
1.69
710         default:
ragge
1.72
711                 comperr("geninsn: bad op %d, node %p"op);
ragge
1.69
712         }
ragge
1.160
713         if (rv == FFAIL)
714                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
715         if (rv == FRETRY)
716                 goto again;
ragge
1.153
717         return rv;
ragge
1.69
718 }
719
ragge
1.72
720 /*
721  * Store a given subtree in a temporary location.
722  * Return an OREG node where it is located.
723  */
724 NODE *
725 store(NODE *p)
ragge
1.2
726 {
ragge
1.130
727         extern struct interpass *storesave;
728         struct interpass *ip;
729         NODE *q, *r;
730         int s;
ragge
1.49
731
ragge
1.130
732         s = BITOOR(freetemp(szty(p->n_type)));
733         q = mklnode(OREGsFPREGp->n_type);
734         r = mklnode(OREGsFPREGp->n_type);
735         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
736
ragge
1.149
737         storesave = ip;
ragge
1.72
738         return r;
ragge
1.8
739 }
ragge
1.1
740
ragge
1.170
741 #ifdef PCC_DEBUG
742 #define CDEBUG(x) if (c2debug) printf x
743 #else
744 #define CDEBUG(x)
745 #endif
746
ragge
1.69
747 /*
ragge
1.75
748  * Rewrite node after instruction emit.
749  */
750 static void
ragge
1.160
751 rewrite(NODE *pint rewriteint cookie)
ragge
1.75
752 {
ragge
1.140
753 //      struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.79
754         NODE *l, *r;
755         int o;
756
ragge
1.75
757         if (p->n_su == -1)
758                 comperr("rewrite");
759
ragge
1.80
760         l = getlr(p'L');
761         r = getlr(p'R');
ragge
1.79
762         o = p->n_op;
ragge
1.75
763         p->n_op = REG;
ragge
1.76
764         p->n_lval = 0;
ragge
1.95
765         p->n_name = "";
ragge
1.158
766
ragge
1.160
767         if (cookie != FOREFF) {
ragge
1.162
768         if (p->n_su == DORIGHT)
769                 comperr("p->n_su == DORIGHT");
ragge
1.170
770         p->n_rval = DECRA(p->n_reg0);
ragge
1.162
771 #if 0
ragge
1.140
772         if (rewrite & RLEFT) {
ragge
1.79
773 #ifdef PCC_DEBUG
774                 if (l->n_op != REG)
775                         comperr("rewrite left");
776 #endif
ragge
1.170
777                 p->n_rval = DECRA(p->n_reg0);
ragge
1.79
778         } else if (rewrite & RRIGHT) {
779 #ifdef PCC_DEBUG
780                 if (r->n_op != REG)
781                         comperr("rewrite right");
782 #endif
ragge
1.170
783                 p->n_rval = DECRA(p->n_reg0);
ragge
1.156
784         } else if (rewrite & RESC1) {
ragge
1.158
785                 p->n_rval = p->n_reg;
ragge
1.156
786         } else if (rewrite & RESC2)
ragge
1.157
787                 p->n_reg = p->n_rval = p->n_reg;
ragge
1.75
788         else if (rewrite & RESC3)
ragge
1.156
789                 p->n_rval = 0/* XXX */
ragge
1.99
790         else if (p->n_su == DORIGHT)
ragge
1.156
791                 p->n_reg = p->n_rval = l->n_rval/* XXX special */
ragge
1.162
792 #endif
ragge
1.160
793         }
ragge
1.79
794         if (optype(o) != LTYPE)
795                 tfree(l);
796         if (optype(o) == BITYPE)
797                 tfree(r);
ragge
1.75
798 }
799
ragge
1.69
800 void
ragge
1.72
801 gencode(NODE *pint cookie)
ragge
1.69
802 {
803         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.172
804         NODE *p1;
ragge
1.69
805
806         if (p->n_su == -1/* For OREGs and similar */
ragge
1.72
807                 return gencode(p->n_leftcookie);
ragge
1.69
808
ragge
1.170
809         CDEBUG(("gencode: node %p\n"p));
810
811         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
812                 return/* meaningless move to itself */
ragge
1.69
813         if (p->n_su & DORIGHT) {
ragge
1.151
814                 gencode(p->n_rightINREGS);
ragge
1.69
815                 if ((p->n_su & RMASK) == ROREG)
816                         canon(p);
817         }
818         if (p->n_su & LMASK) {
ragge
1.151
819                 gencode(p->n_leftINREGS);
ragge
1.142
820                 if ((p->n_su & LMASK) == LOREG)
ragge
1.69
821                         canon(p);
822         }
823         if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
ragge
1.151
824                 gencode(p->n_rightINREGS);
ragge
1.69
825                 if ((p->n_su & RMASK) == ROREG)
826                         canon(p);
ragge
1.142
827         }
ragge
1.161
828
ragge
1.149
829         if ((p->n_su & RMASK) == RREG) {
ragge
1.142
830                 if (q->needs & NSPECIAL) {
ragge
1.158
831                         int rr = rspecial(qNRIGHT);
ragge
1.142
832
ragge
1.165
833                         if (rr >= 0 && rr != p->n_right->n_rval) {
ragge
1.170
834                                 CDEBUG(("gencode(%p) right nspec move\n"p));
ragge
1.165
835                                 rmove(p->n_right->n_rval,
836                                     rrp->n_right->n_type);
ragge
1.158
837                                 p->n_right->n_reg = rr;
838                                 p->n_right->n_rval = rr;
ragge
1.142
839                         }
840                 } else if ((q->rewrite & RRIGHT) &&
ragge
1.170
841                     DECRA(p->n_right->n_reg0) != DECRA(p->n_reg0)) {
ragge
1.161
842 #ifdef notyet
843                         if (p->n_op == ASSIGN)
844                                 comperr("ASSIGN error");
845 #endif
ragge
1.170
846                         CDEBUG(("gencode(%p) right move\n"p));
ragge
1.165
847                         rmove(p->n_right->n_regp->n_regp->n_type);
ragge
1.156
848                         p->n_right->n_reg = p->n_reg;
ragge
1.167
849                         p->n_right->n_rval = p->n_reg;
ragge
1.142
850                 }
851         }
ragge
1.149
852         if ((p->n_su & LMASK) == LREG) {
ragge
1.142
853                 if (q->needs & NSPECIAL) {
ragge
1.158
854                         int rr = rspecial(qNLEFT);
ragge
1.142
855
ragge
1.170
856                         if (rr >= 0 && rr != DECRA(p->n_left->n_reg0)) {
857                                 CDEBUG(("gencode(%p) left nspec move\n"p));
858                                 rmove(DECRA(p->n_left->n_reg0), rr,
ragge
1.165
859                                     p->n_left->n_type);
ragge
1.158
860                                 p->n_left->n_reg = rr;
861                                 p->n_left->n_rval = rr;
ragge
1.141
862                         }
ragge
1.142
863                 } else if ((q->rewrite & RLEFT) &&
ragge
1.170
864                     DECRA(p->n_left->n_reg0) != DECRA(p->n_reg0)) {
ragge
1.161
865 #ifdef notyet
866                         if (p->n_op == ASSIGN)
867                                 comperr("ASSIGN error");
868 #endif
ragge
1.170
869                         CDEBUG(("gencode(%p) left move\n"p));
ragge
1.165
870                         rmove(p->n_left->n_regp->n_regp->n_type);
ragge
1.156
871                         p->n_left->n_reg = p->n_reg;
872                         p->n_left->n_rval = p->n_reg;
ragge
1.134
873                 }
ragge
1.69
874         }
ragge
1.162
875
876         if (p->n_op == ASSIGN &&
877             p->n_left->n_op == REG && p->n_right->n_op == REG &&
878             p->n_left->n_rval == p->n_right->n_rval){
ragge
1.161
879                 /* do not emit anything */
ragge
1.170
880                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
881                 rewrite(pq->rewritecookie);
882                 return;
883         }
ragge
1.147
884
ragge
1.170
885         CDEBUG(("emitting node %p\n"p));
886
ragge
1.172
887         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
888                 /* Print out arguments first */
889                 lastcall(p); /* last chance before printing out insn */
890                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
891                         gencode(p1->n_rightFOREFF);
892                 gencode(p1FOREFF);
893         }
894
ragge
1.72
895         expand(pcookieq->cstring);
ragge
1.169
896         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
897             DECRA(p->n_reg0) != RETREG(p->n_type)) {
898                 CDEBUG(("gencode(%p) retreg\n"p));
899                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
900         } else if (q->needs & NSPECIAL) {
ragge
1.158
901                 int rr = rspecial(qNRES);
ragge
1.150
902
ragge
1.170
903                 if (rr >= 0 && p->n_reg != rr) {
904                         CDEBUG(("gencode(%p) nspec retreg\n"p));
905                         rmove(rrDECRA(p->n_reg0), p->n_type);
906                 }
ragge
1.162
907         } else if ((q->rewrite & RESC1) &&
ragge
1.170
908             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
909                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
910                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.149
911         }
ragge
1.160
912         rewrite(pq->rewritecookie);
ragge
1.2
913 }
ragge
1.1
914
915 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
916
ragge
1.30
917 #ifdef PCC_DEBUG
ragge
1.87
918 #undef  PRTABLE
ragge
1.2
919 int
ragge
1.8
920 e2print(NODE *pint downint *aint *b)
ragge
1.2
921 {
ragge
1.85
922 #ifdef PRTABLE
923         extern int tablesize;
924 #endif
ragge
1.1
925
926         *a = *b = down+1;
927         whiledown >= 2 ){
ragge
1.148
928                 fprintf(prfil"\t");
ragge
1.1
929                 down -= 2;
930                 }
ragge
1.148
931         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
932
933
ragge
1.148
934         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
935         switchp->n_op ) { /* special cases */
ragge
1.1
936
937         case REG:
ragge
1.148
938                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
939                 break;
940
ragge
1.121
941         case TEMP:
ragge
1.148
942                 fprintf(prfil" " CONFMTp->n_lval);
ragge
1.121
943                 break;
944
ragge
1.1
945         case ICON:
946         case NAME:
947         case OREG:
ragge