Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060226184405

Diff

Diff from 1.176 to:

Annotations

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

Annotated File View

ragge
1.176
1 /*      $Id: reader.c,v 1.176 2006/02/26 18:44:05 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.69
590         case REG:
ragge
1.144
591         case TEMP:
ragge
1.72
592         case NAME:
ragge
1.71
593         case ICON:
ragge
1.69
594         case OREG:
ragge
1.152
595                 rv = findleaf(pcookie);
596                 break;
ragge
1.69
597
ragge
1.82
598         case UMUL:
599                 /*
600                  * If we end up here with an UMUL, try to fold it into
601                  * an OREG anyway.
602                  */
ragge
1.86
603                 if (p->n_type == STRTY) {
604                         /* XXX - what to do here? */
605                         geninsn(p->n_leftcookie);
606                         p->n_su = -1;
607                         break;
608                 }
ragge
1.169
609 #if 0
ragge
1.151
610                 if (offstar(p->n_left0)) {
ragge
1.84
611                         p->n_op = OREG;
612                         if ((rv = findleaf(pcookie)) < 0)
613                                 comperr("bad findleaf"); /* XXX */
ragge
1.162
614                         p->n_su |= LOREG;
ragge
1.84
615                         p->n_op = UMUL;
616                         break;
617                 }
ragge
1.109
618                 /* FALLTHROUGH */
ragge
1.169
619 #else
620                 /* create oreg anyway */
621                 (void)offstar(p->n_left0);
622                 p->n_op = OREG;
623                 if ((rv = findleaf(pcookie)) < 0)
624                         comperr("bad findleaf"); /* XXX */
625                 p->n_su |= LOREG;
626                 p->n_op = UMUL;
627                 break;
628 #endif
ragge
1.82
629
ragge
1.172
630         case STCALL:
631         case CALL:
632                 /* CALL arguments are handled special */
633                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
634                         geninsn(p1->n_rightFOREFF);
635                 geninsn(p1FOREFF);
636                 /* FALLTHROUGH */
ragge
1.86
637         case COMPL:
ragge
1.85
638         case UMINUS:
ragge
1.71
639         case PCONV:
640         case SCONV:
641         case INIT:
ragge
1.70
642         case GOTO:
643         case FUNARG:
ragge
1.172
644         case STARG:
ragge
1.72
645         case UCALL:
ragge
1.103
646         case USTCALL:
ragge
1.155
647                 rv = finduni(pcookie);
648                 break;
ragge
1.69
649
ragge
1.71
650         case CBRANCH:
651                 p1 = p->n_left;
652                 p2 = p->n_right;
653                 p1->n_label = p2->n_lval;
654                 o = p1->n_op;
655                 geninsn(p1FORCC);
656                 p->n_su = -1/* su calculations traverse left */
657                 break;
658
659         case FORCE:
ragge
1.151
660                 geninsn(p->n_leftINREGS);
ragge
1.71
661                 p->n_su = -1/* su calculations traverse left */
662                 break;
663
ragge
1.69
664         default:
ragge
1.174
665                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
666         }
ragge
1.160
667         if (rv == FFAIL)
668                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
669         if (rv == FRETRY)
670                 goto again;
ragge
1.153
671         return rv;
ragge
1.69
672 }
673
ragge
1.72
674 /*
675  * Store a given subtree in a temporary location.
676  * Return an OREG node where it is located.
677  */
678 NODE *
679 store(NODE *p)
ragge
1.2
680 {
ragge
1.130
681         extern struct interpass *storesave;
682         struct interpass *ip;
683         NODE *q, *r;
684         int s;
ragge
1.49
685
ragge
1.130
686         s = BITOOR(freetemp(szty(p->n_type)));
687         q = mklnode(OREGsFPREGp->n_type);
688         r = mklnode(OREGsFPREGp->n_type);
689         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
690
ragge
1.149
691         storesave = ip;
ragge
1.72
692         return r;
ragge
1.8
693 }
ragge
1.1
694
ragge
1.170
695 #ifdef PCC_DEBUG
696 #define CDEBUG(x) if (c2debug) printf x
697 #else
698 #define CDEBUG(x)
699 #endif
700
ragge
1.69
701 /*
ragge
1.75
702  * Rewrite node after instruction emit.
703  */
704 static void
ragge
1.160
705 rewrite(NODE *pint rewriteint cookie)
ragge
1.75
706 {
ragge
1.140
707 //      struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.79
708         NODE *l, *r;
709         int o;
710
ragge
1.75
711         if (p->n_su == -1)
712                 comperr("rewrite");
713
ragge
1.80
714         l = getlr(p'L');
715         r = getlr(p'R');
ragge
1.79
716         o = p->n_op;
ragge
1.75
717         p->n_op = REG;
ragge
1.76
718         p->n_lval = 0;
ragge
1.95
719         p->n_name = "";
ragge
1.158
720
ragge
1.160
721         if (cookie != FOREFF) {
ragge
1.162
722         if (p->n_su == DORIGHT)
723                 comperr("p->n_su == DORIGHT");
ragge
1.170
724         p->n_rval = DECRA(p->n_reg0);
ragge
1.162
725 #if 0
ragge
1.140
726         if (rewrite & RLEFT) {
ragge
1.79
727 #ifdef PCC_DEBUG
728                 if (l->n_op != REG)
729                         comperr("rewrite left");
730 #endif
ragge
1.170
731                 p->n_rval = DECRA(p->n_reg0);
ragge
1.79
732         } else if (rewrite & RRIGHT) {
733 #ifdef PCC_DEBUG
734                 if (r->n_op != REG)
735                         comperr("rewrite right");
736 #endif
ragge
1.170
737                 p->n_rval = DECRA(p->n_reg0);
ragge
1.156
738         } else if (rewrite & RESC1) {
ragge
1.158
739                 p->n_rval = p->n_reg;
ragge
1.156
740         } else if (rewrite & RESC2)
ragge
1.157
741                 p->n_reg = p->n_rval = p->n_reg;
ragge
1.75
742         else if (rewrite & RESC3)
ragge
1.156
743                 p->n_rval = 0/* XXX */
ragge
1.99
744         else if (p->n_su == DORIGHT)
ragge
1.156
745                 p->n_reg = p->n_rval = l->n_rval/* XXX special */
ragge
1.162
746 #endif
ragge
1.160
747         }
ragge
1.79
748         if (optype(o) != LTYPE)
749                 tfree(l);
750         if (optype(o) == BITYPE)
751                 tfree(r);
ragge
1.75
752 }
753
ragge
1.69
754 void
ragge
1.72
755 gencode(NODE *pint cookie)
ragge
1.69
756 {
757         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.172
758         NODE *p1;
ragge
1.69
759
760         if (p->n_su == -1/* For OREGs and similar */
ragge
1.72
761                 return gencode(p->n_leftcookie);
ragge
1.69
762
ragge
1.170
763         CDEBUG(("gencode: node %p\n"p));
764
765         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
766                 return/* meaningless move to itself */
ragge
1.175
767
768         if (callop(p->n_op))
769                 lastcall(p); /* last chance before function args */
770         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
771                 /* Print out arguments first */
772                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
773                         gencode(p1->n_rightFOREFF);
774                 gencode(p1FOREFF);
775         }
776
ragge
1.69
777         if (p->n_su & DORIGHT) {
ragge
1.151
778                 gencode(p->n_rightINREGS);
ragge
1.69
779                 if ((p->n_su & RMASK) == ROREG)
780                         canon(p);
781         }
782         if (p->n_su & LMASK) {
ragge
1.151
783                 gencode(p->n_leftINREGS);
ragge
1.142
784                 if ((p->n_su & LMASK) == LOREG)
ragge
1.69
785                         canon(p);
786         }
787         if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
ragge
1.151
788                 gencode(p->n_rightINREGS);
ragge
1.69
789                 if ((p->n_su & RMASK) == ROREG)
790                         canon(p);
ragge
1.142
791         }
ragge
1.161
792
ragge
1.149
793         if ((p->n_su & RMASK) == RREG) {
ragge
1.142
794                 if (q->needs & NSPECIAL) {
ragge
1.158
795                         int rr = rspecial(qNRIGHT);
ragge
1.142
796
ragge
1.165
797                         if (rr >= 0 && rr != p->n_right->n_rval) {
ragge
1.170
798                                 CDEBUG(("gencode(%p) right nspec move\n"p));
ragge
1.165
799                                 rmove(p->n_right->n_rval,
800                                     rrp->n_right->n_type);
ragge
1.158
801                                 p->n_right->n_reg = rr;
802                                 p->n_right->n_rval = rr;
ragge
1.142
803                         }
804                 } else if ((q->rewrite & RRIGHT) &&
ragge
1.170
805                     DECRA(p->n_right->n_reg0) != DECRA(p->n_reg0)) {
ragge
1.161
806 #ifdef notyet
807                         if (p->n_op == ASSIGN)
808                                 comperr("ASSIGN error");
809 #endif
ragge
1.170
810                         CDEBUG(("gencode(%p) right move\n"p));
ragge
1.173
811                         rmove(DECRA(p->n_right->n_reg0),
812                             DECRA(p->n_reg0), p->n_type);
ragge
1.156
813                         p->n_right->n_reg = p->n_reg;
ragge
1.167
814                         p->n_right->n_rval = p->n_reg;
ragge
1.142
815                 }
816         }
ragge
1.149
817         if ((p->n_su & LMASK) == LREG) {
ragge
1.142
818                 if (q->needs & NSPECIAL) {
ragge
1.158
819                         int rr = rspecial(qNLEFT);
ragge
1.142
820
ragge
1.170
821                         if (rr >= 0 && rr != DECRA(p->n_left->n_reg0)) {
822                                 CDEBUG(("gencode(%p) left nspec move\n"p));
823                                 rmove(DECRA(p->n_left->n_reg0), rr,
ragge
1.165
824                                     p->n_left->n_type);
ragge
1.158
825                                 p->n_left->n_reg = rr;
826                                 p->n_left->n_rval = rr;
ragge
1.141
827                         }
ragge
1.142
828                 } else if ((q->rewrite & RLEFT) &&
ragge
1.170
829                     DECRA(p->n_left->n_reg0) != DECRA(p->n_reg0)) {
ragge
1.161
830 #ifdef notyet
831                         if (p->n_op == ASSIGN)
832                                 comperr("ASSIGN error");
833 #endif
ragge
1.170
834                         CDEBUG(("gencode(%p) left move\n"p));
ragge
1.173
835                         rmove(DECRA(p->n_left->n_reg0),
836                             DECRA(p->n_reg0), p->n_type);
ragge
1.156
837                         p->n_left->n_reg = p->n_reg;
838                         p->n_left->n_rval = p->n_reg;
ragge
1.134
839                 }
ragge
1.69
840         }
ragge
1.162
841
842         if (p->n_op == ASSIGN &&
843             p->n_left->n_op == REG && p->n_right->n_op == REG &&
844             p->n_left->n_rval == p->n_right->n_rval){
ragge
1.161
845                 /* do not emit anything */
ragge
1.170
846                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
847                 rewrite(pq->rewritecookie);
848                 return;
849         }
ragge
1.147
850
ragge
1.170
851         CDEBUG(("emitting node %p\n"p));
ragge
1.173
852         if (p->n_su == 0)
853                 return;
ragge
1.170
854
ragge
1.72
855         expand(pcookieq->cstring);
ragge
1.169
856         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
857             DECRA(p->n_reg0) != RETREG(p->n_type)) {
858                 CDEBUG(("gencode(%p) retreg\n"p));
859                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
860         } else if (q->needs & NSPECIAL) {
ragge
1.158
861                 int rr = rspecial(qNRES);
ragge
1.150
862
ragge
1.170
863                 if (rr >= 0 && p->n_reg != rr) {
864                         CDEBUG(("gencode(%p) nspec retreg\n"p));
865                         rmove(rrDECRA(p->n_reg0), p->n_type);
866                 }
ragge
1.162
867         } else if ((q->rewrite & RESC1) &&
ragge
1.170
868             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
869                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
870                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.176
871         } else if (p->n_op == ASSIGN) {
872                 /* may need move added if RLEFT/RRIGHT */
873                 /* XXX should be handled in sucomp() */
874                 if ((q->rewrite & RLEFT) && (p->n_left->n_op == REG) &&
875                     (p->n_left->n_rval != DECRA(p->n_reg0)) &&
876                     TCLASS(p->n_su)) {
877                         rmove(p->n_left->n_rvalDECRA(p->n_reg0), p->n_type);
878                 } else if ((q->rewrite & RRIGHT) && (p->n_right->n_op == REG) &&
879                     (p->n_right->n_rval != DECRA(p->n_reg0)) &&
880                     TCLASS(p->n_su)) {
881                         rmove(p->n_right->n_rvalDECRA(p->n_reg0), p->n_type);
882                 }
ragge
1.149
883         }
ragge
1.160
884         rewrite(pq->rewritecookie);
ragge
1.2
885 }
ragge
1.1
886
887 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
888
ragge
1.30
889 #ifdef PCC_DEBUG
ragge
1.87
890 #undef  PRTABLE
ragge
1.174
891 void
ragge
1.8
892 e2print(NODE *pint downint *aint *b)
ragge
1.2
893 {
ragge
1.85
894 #ifdef PRTABLE
895         extern int tablesize;
896 #endif
ragge
1.1
897
898         *a = *b = down+1;
899         whiledown >= 2 ){
ragge
1.148
900                 fprintf(prfil"\t");
ragge
1.1
901                 down -= 2;
902                 }
ragge
1.148
903         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
904
905
ragge
1.148
906         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
907         switchp->n_op ) { /* special cases */
ragge
1.1
908
909         case REG:
ragge
1.148
910                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
911                 break;
912
ragge
1.121
913         case TEMP:
ragge
1.148
914                 fprintf(prfil" " CONFMTp->n_lval);
ragge
1.121
915                 break;
916
ragge
1.1
917         case ICON:
918         case NAME:
919         case OREG:
ragge
1.148
920                 fprintf(prfil" " );
921                 adrput(prfilp );
ragge
1.1
922                 break;
923
924         case STCALL:
ragge
1.68
925         case USTCALL:
ragge
1.1
926         case STARG:
927         case STASG:
ragge
1.148