Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060128072712

Diff

Diff from 1.170 to:

Annotations

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

Annotated File View

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