Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060525144301

Diff

Diff from 1.185 to:

Annotations

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

Annotated File View

ragge
1.185
1 /*      $Id: reader.c,v 1.185 2006/05/25 14:43:01 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
ragge
1.124
317 void
ragge
1.125
318 emit(struct interpass *ip)
ragge
1.124
319 {
320         NODE *p;
ragge
1.149
321         int o;
ragge
1.124
322
ragge
1.125
323         switch (ip->type) {
324         case IP_NODE:
325                 p = ip->ip_node;
ragge
1.124
326
ragge
1.149
327                 nodepole = p;
ragge
1.180
328 //printf("bu:\n");
329 //fwalk(p, e2print, 0);
330                 canon(p); /* may convert stuff after genregs */
331 //fwalk(p, e2print, 0);
ragge
1.124
332                 switch (p->n_op) {
333                 case CBRANCH:
334                         /* Only emit branch insn if RESCC */
335                         if (table[TBLIDX(p->n_left->n_su)].rewrite & RESCC) {
336                                 o = p->n_left->n_op;
337                                 gencode(pFORCC);
338                                 cbgen(op->n_right->n_lval);
339                         } else
340                                 gencode(pFORCC);
341                         break;
342                 case FORCE:
ragge
1.151
343                         gencode(p->n_leftINREGS);
ragge
1.124
344                         break;
345                 default:
346                         if (p->n_op != REG || p->n_type != VOID/* XXX */
347                                 gencode(pFOREFF); /* Emit instructions */
348                 }
349
ragge
1.125
350                 tfree(p);
351                 break;
ragge
1.124
352         case IP_PROLOG:
353                 prologue((struct interpass_prolog *)ip);
354                 break;
355         case IP_EPILOG:
356                 eoftn((struct interpass_prolog *)ip);
357                 tmpsave = NULL/* Always forget old nodes */
ragge
1.174
358                 p2maxautooff = p2autooff = AUTOINIT/SZCHAR;
ragge
1.124
359                 break;
360         case IP_DEFLAB:
361                 deflab(ip->ip_lbl);
362                 break;
363         case IP_ASM:
364                 printf("\t%s\n"ip->ip_asm);
365                 break;
366         default:
367                 cerror("compile4 %d"ip->type);
368         }
ragge
1.123
369 }
ragge
1.124
370
ragge
1.30
371 #ifdef PCC_DEBUG
ragge
1.1
372 char *cnames[] = {
373         "SANY",
374         "SAREG",
375         "SBREG",
ragge
1.153
376         "SCREG",
377         "SDREG",
ragge
1.1
378         "SCC",
379         "SNAME",
380         "SCON",
381         "SFLD",
382         "SOREG",
383         "STARNM",
384         "STARREG",
385         "INTEMP",
386         "FORARG",
387         "SWADD",
388         0,
ragge
1.72
389 };
ragge
1.1
390
ragge
1.2
391 /*
392  * print a nice-looking description of cookie
393  */
ragge
1.70
394 char *
ragge
1.2
395 prcook(int cookie)
396 {
ragge
1.70
397         static char buf[50];
ragge
1.1
398         int iflag;
399
ragge
1.70
400         if (cookie & SPECIAL) {
401                 switch (cookie) {
402                 case SZERO:
403                         return "SZERO";
404                 case SONE:
405                         return "SONE";
406                 case SMONE:
407                         return "SMONE";
408                 default:
409                         sprintf(buf"SPECIAL+%d"cookie & ~SPECIAL);
410                         return buf;
ragge
1.1
411                 }
ragge
1.70
412         }
ragge
1.1
413
414         flag = 0;
ragge
1.70
415         buf[0] = 0;
416         for (i = 0cnames[i]; ++i) {
417                 if (cookie & (1<<i)) {
418                         if (flag)
419                                 strcat(buf"|");
ragge
1.1
420                         ++flag;
ragge
1.70
421                         strcat(bufcnames[i]);
ragge
1.1
422                 }
ragge
1.70
423         }
424         return buf;
425 }
ragge
1.1
426
ragge
1.30
427 #endif
ragge
1.1
428
429 int odebug = 0;
430
ragge
1.151
431 int
ragge
1.69
432 geninsn(NODE *pint cookie)
433 {
ragge
1.71
434         NODE *p1, *p2;
ragge
1.151
435         int orv = 0;
ragge
1.69
436
437 #ifdef PCC_DEBUG
438         if (odebug) {
ragge
1.70
439                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
440                 fwalk(pe2print0);
441         }
442 #endif
443
444 again:  switch (o = p->n_op) {
ragge
1.71
445         case EQ:
446         case NE:
447         case LE:
448         case LT:
449         case GE:
450         case GT:
451         case ULE:
452         case ULT:
453         case UGE:
454         case UGT:
ragge
1.159
455                 rv = relops(p);
456                 break;
ragge
1.71
457
ragge
1.69
458         case PLUS:
459         case MINUS:
460         case MUL:
461         case DIV:
462         case MOD:
463         case AND:
464         case OR:
465         case ER:
466         case LS:
467         case RS:
ragge
1.151
468                 rv = findops(pcookie);
469                 break;
ragge
1.77
470
471         case INCR:
472         case DECR:
ragge
1.160
473                 rv = findops(pcookie);
474                 if (rv != FFAIL)
475                         break;
476
ragge
1.77
477                 /*
478                  * Rewrite x++ to (x = x + 1) -1;
479                  */
480                 p1 = p->n_left;
481                 p->n_op = o == INCR ? MINUS : PLUS;
482                 /* Assign node */
483                 p2 = talloc();
484                 p2->n_type = p->n_type;
485                 p2->n_name = "";
486                 p2->n_op = ASSIGN;
487                 p->n_left = p2;
488                 p->n_left->n_left = p1;
489                 /* incr/decr node */
490                 p2 = talloc();
491                 p2->n_type = p->n_type;
492                 p2->n_name = "";
493                 p2->n_op = o == INCR ? PLUS : MINUS;
494                 p->n_left->n_right = p2;
495                 /* const one node */
496                 p->n_left->n_right->n_right = tcopy(p->n_right);
497                 /* input tree */
498                 p1 = tcopy(p1);
499                 /* idstrip(p1); */
500                 p->n_left->n_right->n_left = p1;
ragge
1.108
501                 canon(p); /* if fields involved */
ragge
1.77
502                 goto again;
ragge
1.71
503
ragge
1.69
504         case ASSIGN:
ragge
1.174
505         case STASG:
ragge
1.151
506                 rv = findasg(pcookie);
507                 break;
ragge
1.159
508
ragge
1.178
509         case UMUL/* May turn into an OREG */
ragge
1.179
510                 rv = findumul(pcookie);
511                 break;
512
ragge
1.69
513         case REG:
ragge
1.144
514         case TEMP:
ragge
1.72
515         case NAME:
ragge
1.71
516         case ICON:
ragge
1.69
517         case OREG:
ragge
1.152
518                 rv = findleaf(pcookie);
519                 break;
ragge
1.69
520
ragge
1.172
521         case STCALL:
522         case CALL:
523                 /* CALL arguments are handled special */
524                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
525                         geninsn(p1->n_rightFOREFF);
526                 geninsn(p1FOREFF);
527                 /* FALLTHROUGH */
ragge
1.86
528         case COMPL:
ragge
1.85
529         case UMINUS:
ragge
1.71
530         case PCONV:
531         case SCONV:
532         case INIT:
ragge
1.70
533         case GOTO:
534         case FUNARG:
ragge
1.172
535         case STARG:
ragge
1.72
536         case UCALL:
ragge
1.103
537         case USTCALL:
ragge
1.155
538                 rv = finduni(pcookie);
539                 break;
ragge
1.69
540
ragge
1.71
541         case CBRANCH:
542                 p1 = p->n_left;
543                 p2 = p->n_right;
544                 p1->n_label = p2->n_lval;
545                 o = p1->n_op;
546                 geninsn(p1FORCC);
ragge
1.178
547                 p->n_su = DOWNL/* su calculations traverse left */
ragge
1.71
548                 break;
549
550         case FORCE:
ragge
1.151
551                 geninsn(p->n_leftINREGS);
ragge
1.178
552                 p->n_su = DOWNL/* su calculations traverse left */
ragge
1.71
553                 break;
554
ragge
1.69
555         default:
ragge
1.174
556                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
557         }
ragge
1.160
558         if (rv == FFAIL)
559                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
560         if (rv == FRETRY)
561                 goto again;
ragge
1.153
562         return rv;
ragge
1.69
563 }
564
ragge
1.72
565 /*
566  * Store a given subtree in a temporary location.
567  * Return an OREG node where it is located.
568  */
569 NODE *
570 store(NODE *p)
ragge
1.2
571 {
ragge
1.130
572         extern struct interpass *storesave;
573         struct interpass *ip;
574         NODE *q, *r;
575         int s;
ragge
1.49
576
ragge
1.130
577         s = BITOOR(freetemp(szty(p->n_type)));
578         q = mklnode(OREGsFPREGp->n_type);
579         r = mklnode(OREGsFPREGp->n_type);
580         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
581
ragge
1.149
582         storesave = ip;
ragge
1.72
583         return r;
ragge
1.8
584 }
ragge
1.1
585
ragge
1.170
586 #ifdef PCC_DEBUG
587 #define CDEBUG(x) if (c2debug) printf x
588 #else
589 #define CDEBUG(x)
590 #endif
591
ragge
1.69
592 /*
ragge
1.75
593  * Rewrite node after instruction emit.
594  */
595 static void
ragge
1.160
596 rewrite(NODE *pint rewriteint cookie)
ragge
1.75
597 {
ragge
1.140
598 //      struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.79
599         NODE *l, *r;
600         int o;
601
ragge
1.178
602         if (p->n_su == DOWNL)
ragge
1.75
603                 comperr("rewrite");
604
ragge
1.80
605         l = getlr(p'L');
606         r = getlr(p'R');
ragge
1.79
607         o = p->n_op;
ragge
1.75
608         p->n_op = REG;
ragge
1.76
609         p->n_lval = 0;
ragge
1.95
610         p->n_name = "";
ragge
1.158
611
ragge
1.160
612         if (cookie != FOREFF) {
ragge
1.162
613         if (p->n_su == DORIGHT)
614                 comperr("p->n_su == DORIGHT");
ragge
1.170
615         p->n_rval = DECRA(p->n_reg0);
ragge
1.162
616 #if 0
ragge
1.140
617         if (rewrite & RLEFT) {
ragge
1.79
618 #ifdef PCC_DEBUG
619                 if (l->n_op != REG)
620                         comperr("rewrite left");
621 #endif
ragge
1.170
622                 p->n_rval = DECRA(p->n_reg0);
ragge
1.79
623         } else if (rewrite & RRIGHT) {
624 #ifdef PCC_DEBUG
625                 if (r->n_op != REG)
626                         comperr("rewrite right");
627 #endif
ragge
1.170
628                 p->n_rval = DECRA(p->n_reg0);
ragge
1.156
629         } else if (rewrite & RESC1) {
ragge
1.158
630                 p->n_rval = p->n_reg;
ragge
1.156
631         } else if (rewrite & RESC2)
ragge
1.157
632                 p->n_reg = p->n_rval = p->n_reg;
ragge
1.75
633         else if (rewrite & RESC3)
ragge
1.156
634                 p->n_rval = 0/* XXX */
ragge
1.99
635         else if (p->n_su == DORIGHT)
ragge
1.156
636                 p->n_reg = p->n_rval = l->n_rval/* XXX special */
ragge
1.162
637 #endif
ragge
1.160
638         }
ragge
1.79
639         if (optype(o) != LTYPE)
640                 tfree(l);
641         if (optype(o) == BITYPE)
642                 tfree(r);
ragge
1.75
643 }
644
ragge
1.69
645 void
ragge
1.72
646 gencode(NODE *pint cookie)
ragge
1.69
647 {
648         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.172
649         NODE *p1;
ragge
1.69
650
ragge
1.185
651 #ifdef ragge
652         if (p->n_su == 0) {
653                 /* XXX - check DORIGHT */
654                 if (optype(p->n_op) == BITYPE)
655                         gencode(p->n_right0);
656                 if (optype(p->n_op) != LTYPE)
657                         gencode(p->n_left0);
658                 return;
659         }
660 #else
ragge
1.178
661         if (p->n_su == DOWNL/* For OREGs and similar */
ragge
1.72
662                 return gencode(p->n_leftcookie);
ragge
1.185
663 #endif
ragge
1.69
664
ragge
1.170
665         CDEBUG(("gencode: node %p\n"p));
666
667         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
668                 return/* meaningless move to itself */
ragge
1.175
669
670         if (callop(p->n_op))
671                 lastcall(p); /* last chance before function args */
672         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
673                 /* Print out arguments first */
674                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
675                         gencode(p1->n_rightFOREFF);
676                 gencode(p1FOREFF);
677         }
678
ragge
1.185
679 #ifdef ragge
680         if (optype(p->n_op) == BITYPE && (p->n_su & DORIGHT))
681                 gencode(p->n_rightINREGS);
682 #else
ragge
1.69
683         if (p->n_su & DORIGHT) {
ragge
1.151
684                 gencode(p->n_rightINREGS);
ragge
1.69
685                 if ((p->n_su & RMASK) == ROREG)
686                         canon(p);
ragge
1.185
687         }
ragge
1.184
688 #endif
ragge
1.185
689
690 #ifdef ragge
691         if (optype(p->n_op) != LTYPE)
692                 gencode(p->n_leftINREGS);
693 #else
ragge
1.69
694         if (p->n_su & LMASK) {
ragge
1.151
695                 gencode(p->n_leftINREGS);
ragge
1.142
696                 if ((p->n_su & LMASK) == LOREG)
ragge
1.69
697                         canon(p);
ragge
1.185
698         }
ragge
1.184
699 #endif
ragge
1.185
700
701 #ifdef ragge
702         if (optype(p->n_op) == BITYPE && !(p->n_su & DORIGHT))
703                 gencode(p->n_rightINREGS);
704 #else
ragge
1.69
705         if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
ragge
1.151
706                 gencode(p->n_rightINREGS);
ragge
1.69
707                 if ((p->n_su & RMASK) == ROREG)
708                         canon(p);
ragge
1.185
709         }
ragge
1.184
710 #endif
ragge
1.161
711
ragge
1.149
712         if ((p->n_su & RMASK) == RREG) {
ragge
1.142
713                 if (q->needs & NSPECIAL) {
ragge
1.158
714                         int rr = rspecial(qNRIGHT);
ragge
1.142
715
ragge
1.165
716                         if (rr >= 0 && rr != p->n_right->n_rval) {
ragge
1.170
717                                 CDEBUG(("gencode(%p) right nspec move\n"p));
ragge
1.165
718                                 rmove(p->n_right->n_rval,
719                                     rrp->n_right->n_type);
ragge
1.158
720                                 p->n_right->n_reg = rr;
721                                 p->n_right->n_rval = rr;
ragge
1.142
722                         }
723                 } else if ((q->rewrite & RRIGHT) &&
ragge
1.170
724                     DECRA(p->n_right->n_reg0) != DECRA(p->n_reg0)) {
ragge
1.161
725 #ifdef notyet
726                         if (p->n_op == ASSIGN)
727                                 comperr("ASSIGN error");
728 #endif
ragge
1.170
729                         CDEBUG(("gencode(%p) right move\n"p));
ragge
1.173
730                         rmove(DECRA(p->n_right->n_reg0),
731                             DECRA(p->n_reg0), p->n_type);
ragge
1.156
732                         p->n_right->n_reg = p->n_reg;
ragge
1.167
733                         p->n_right->n_rval = p->n_reg;
ragge
1.142
734                 }
735         }
ragge
1.149
736         if ((p->n_su & LMASK) == LREG) {
ragge
1.142
737                 if (q->needs & NSPECIAL) {
ragge
1.158
738                         int rr = rspecial(qNLEFT);
ragge
1.142
739
ragge
1.170
740                         if (rr >= 0 && rr != DECRA(p->n_left->n_reg0)) {
741                                 CDEBUG(("gencode(%p) left nspec move\n"p));
742                                 rmove(DECRA(p->n_left->n_reg0), rr,
ragge
1.165
743                                     p->n_left->n_type);
ragge
1.158
744                                 p->n_left->n_reg = rr;
745                                 p->n_left->n_rval = rr;
ragge
1.141
746                         }
ragge
1.142
747                 } else if ((q->rewrite & RLEFT) &&
ragge
1.170
748                     DECRA(p->n_left->n_reg0) != DECRA(p->n_reg0)) {
ragge
1.161
749 #ifdef notyet
750                         if (p->n_op == ASSIGN)
751                                 comperr("ASSIGN error");
752 #endif
ragge
1.170
753                         CDEBUG(("gencode(%p) left move\n"p));
ragge
1.173
754                         rmove(DECRA(p->n_left->n_reg0),
755                             DECRA(p->n_reg0), p->n_type);
ragge
1.156
756                         p->n_left->n_reg = p->n_reg;
757                         p->n_left->n_rval = p->n_reg;
ragge
1.134
758                 }
ragge
1.69
759         }
ragge
1.162
760
761         if (p->n_op == ASSIGN &&
762             p->n_left->n_op == REG && p->n_right->n_op == REG &&
763             p->n_left->n_rval == p->n_right->n_rval){
ragge
1.161
764                 /* do not emit anything */
ragge
1.170
765                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
766                 rewrite(pq->rewritecookie);
767                 return;
768         }
ragge
1.147
769
ragge
1.170
770         CDEBUG(("emitting node %p\n"p));
ragge
1.173
771         if (p->n_su == 0)
772                 return;
ragge
1.170
773
ragge
1.181
774 canon(p); /* XXX */
ragge
1.183
775 //fwalk(p, e2print, 0);
ragge
1.72
776         expand(pcookieq->cstring);
ragge
1.169
777         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
778             DECRA(p->n_reg0) != RETREG(p->n_type)) {
779                 CDEBUG(("gencode(%p) retreg\n"p));
780                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
781         } else if (q->needs & NSPECIAL) {
ragge
1.158
782                 int rr = rspecial(qNRES);
ragge
1.150
783
ragge
1.170
784                 if (rr >= 0 && p->n_reg != rr) {
785                         CDEBUG(("gencode(%p) nspec retreg\n"p));
786                         rmove(rrDECRA(p->n_reg0), p->n_type);
787                 }
ragge
1.162
788         } else if ((q->rewrite & RESC1) &&
ragge
1.170
789             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
790                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
791                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.176
792         } else if (p->n_op == ASSIGN) {
793                 /* may need move added if RLEFT/RRIGHT */
794                 /* XXX should be handled in sucomp() */
795                 if ((q->rewrite & RLEFT) && (p->n_left->n_op == REG) &&
796                     (p->n_left->n_rval != DECRA(p->n_reg0)) &&
797                     TCLASS(p->n_su)) {
798                         rmove(p->n_left->n_rvalDECRA(p->n_reg0), p->n_type);
799                 } else if ((q->rewrite & RRIGHT) && (p->n_right->n_op == REG) &&
800                     (p->n_right->n_rval != DECRA(p->n_reg0)) &&
801                     TCLASS(p->n_su)) {
802                         rmove(p->n_right->n_rvalDECRA(p->n_reg0), p->n_type);
803                 }
ragge
1.149
804         }
ragge
1.160
805         rewrite(pq->rewritecookie);
ragge
1.2
806 }
ragge
1.1
807
808 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
809
ragge
1.30
810 #ifdef PCC_DEBUG
ragge
1.87
811 #undef  PRTABLE
ragge
1.174
812 void
ragge
1.8
813 e2print(NODE *pint downint *aint *b)
ragge
1.2
814 {
ragge
1.85
815 #ifdef PRTABLE
816         extern int tablesize;
817 #endif
ragge
1.1
818
819         *a = *b = down+1;
820         whiledown >= 2 ){
ragge
1.148
821                 fprintf(prfil"\t");
ragge
1.1
822                 down -= 2;
823                 }
ragge
1.148
824         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
825
826
ragge
1.148
827         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
828         switchp->n_op ) { /* special cases */
ragge
1.1
829
830         case REG:
ragge
1.148
831                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
832                 break;
833
ragge
1.121
834         case TEMP:
ragge
1.148
835                 fprintf(prfil" " CONFMTp->n_lval);
ragge
1.121
836                 break;
837
ragge
1.1
838         case ICON:
839         case NAME:
840         case OREG:
ragge
1.148
841                 fprintf(prfil" " );
842                 adrput(prfilp );
ragge
1.1
843                 break;
844
845         case STCALL:
ragge
1.68
846         case USTCALL:
ragge
1.1
847         case STARG:
848         case STASG:
ragge
1.148
849                 fprintf(prfil" size=%d"p->n_stsize );
850                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
851                 break;
852                 }
853
ragge
1.148
854         fprintf(prfil", " );
855         tprint(prfilp->n_typep->n_qual);
856         fprintf(prfil", " );
ragge
1.156
857         {
858                 int gregn(struct regw *);
859                 if (p->n_reg < 100000/* XXX */
ragge
1.170
860                         fprintf(prfil"REG %s"rnames[DECRA(p->n_reg0)]);
ragge
1.155
861                 else
ragge
1.156
862                         fprintf(prfil"TEMP %d"gregn(p->n_regw));
ragge
1.1
863                 }
ragge
1.151
864         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
ragge
1.85
865             TBLIDX(p->n_su), 
ragge
1.151
866             TCLASS(p->n_su)+'@',
ragge
1.85
867 #ifdef PRTABLE
868             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
869             table[TBLIDX(p->n_su)].cstring : "",
870 #else
871             "",
872 #endif
873             ltyp[LMASK&p->n_su],
ragge
1.70
874             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
875 }
ragge
1.30
876 #endif
ragge
1.1
877
878 #ifndef FIELDOPS
ragge
1.7
879 /*
880  * do this if there is no special hardware support for fields
881  */
ragge
1.174
882 static void
ragge
1.7
883 ffld(NODE *pint downint *down1int *down2 )
884 {
885         /*
886          * look for fields that are not in an lvalue context,
887          * and rewrite them...
888          */
889         NODE *shp;
890         int sovty;
ragge
1.1
891
ragge
1.13
892         *down1 =  asgopp->n_op );
ragge
1.1
893         *down2 = 0;
894
ragge
1.13
895         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
896
ragge
1.174
897                 if( !rewfld(p) ) return;
ragge
1.1
898
ragge
1.173
899                 ty = p->n_type;
ragge
1.13
900                 v = p->n_rval;
ragge
1.1
901                 s = UPKFSZ(v);
902 # ifdef RTOLBYTES
903                 o = UPKFOFF(v);  /* amount to shift */