Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20051222095728

Diff

Diff from 1.162 to:

Annotations

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

Annotated File View

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