Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060318081833

Diff

Diff from 1.177 to:

Annotations

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

Annotated File View

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