Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060326071428

Diff

Diff from 1.178 to:

Annotations

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

Annotated File View

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