Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060401131915

Diff

Diff from 1.179 to:

Annotations

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

Annotated File View

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