Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060112213522

Diff

Diff from 1.169 to:

Annotations

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

Annotated File View

ragge
1.169
1 /*      $Id: reader.c,v 1.169 2006/01/12 21:35:23 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.69
628 /*
ragge
1.75
629  * Rewrite node after instruction emit.
630  */
631 static void
ragge
1.160
632 rewrite(NODE *pint rewriteint cookie)
ragge
1.75
633 {
ragge
1.140
634 //      struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.79
635         NODE *l, *r;
636         int o;
637
ragge
1.75
638         if (p->n_su == -1)
639                 comperr("rewrite");
640
ragge
1.80
641         l = getlr(p'L');
642         r = getlr(p'R');
ragge
1.79
643         o = p->n_op;
ragge
1.75
644         p->n_op = REG;
ragge
1.76
645         p->n_lval = 0;
ragge
1.95
646         p->n_name = "";
ragge
1.158
647
ragge
1.160
648         if (cookie != FOREFF) {
ragge
1.162
649         if (p->n_su == DORIGHT)
650                 comperr("p->n_su == DORIGHT");
651         p->n_rval = DECRD(p->n_reg);
652 #if 0
ragge
1.140
653         if (rewrite & RLEFT) {
ragge
1.79
654 #ifdef PCC_DEBUG
655                 if (l->n_op != REG)
656                         comperr("rewrite left");
657 #endif
ragge
1.162
658                 p->n_rval = DECRD(p->n_reg);
ragge
1.79
659         } else if (rewrite & RRIGHT) {
660 #ifdef PCC_DEBUG
661                 if (r->n_op != REG)
662                         comperr("rewrite right");
663 #endif
ragge
1.162
664                 p->n_rval = DECRD(p->n_reg);
ragge
1.156
665         } else if (rewrite & RESC1) {
ragge
1.158
666                 p->n_rval = p->n_reg;
ragge
1.156
667         } else if (rewrite & RESC2)
ragge
1.157
668                 p->n_reg = p->n_rval = p->n_reg;
ragge
1.75
669         else if (rewrite & RESC3)
ragge
1.156
670                 p->n_rval = 0/* XXX */
ragge
1.99
671         else if (p->n_su == DORIGHT)
ragge
1.156
672                 p->n_reg = p->n_rval = l->n_rval/* XXX special */
ragge
1.162
673 #endif
ragge
1.160
674         }
ragge
1.79
675         if (optype(o) != LTYPE)
676                 tfree(l);
677         if (optype(o) == BITYPE)
678                 tfree(r);
ragge
1.75
679 }
680
ragge
1.69
681 void
ragge
1.72
682 gencode(NODE *pint cookie)
ragge
1.69
683 {
684         struct optab *q = &table[TBLIDX(p->n_su)];
685
686         if (p->n_su == -1/* For OREGs and similar */
ragge
1.72
687                 return gencode(p->n_leftcookie);
ragge
1.69
688
ragge
1.162
689         if (p->n_op == REG && DECRD(p->n_reg) == p->n_rval)
ragge
1.156
690                 return/* meaningless move to itself */
ragge
1.69
691         if (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);
695         }
696         if (p->n_su & LMASK) {
ragge
1.151
697                 gencode(p->n_leftINREGS);
ragge
1.142
698                 if ((p->n_su & LMASK) == LOREG)
ragge
1.69
699                         canon(p);
700         }
701         if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
ragge
1.151
702                 gencode(p->n_rightINREGS);
ragge
1.69
703                 if ((p->n_su & RMASK) == ROREG)
704                         canon(p);
ragge
1.142
705         }
ragge
1.161
706
ragge
1.149
707         if ((p->n_su & RMASK) == RREG) {
ragge
1.142
708                 if (q->needs & NSPECIAL) {
ragge
1.158
709                         int rr = rspecial(qNRIGHT);
ragge
1.142
710
ragge
1.165
711                         if (rr >= 0 && rr != p->n_right->n_rval) {
712                                 rmove(p->n_right->n_rval,
713                                     rrp->n_right->n_type);
ragge
1.158
714                                 p->n_right->n_reg = rr;
715                                 p->n_right->n_rval = rr;
ragge
1.142
716                         }
717                 } else if ((q->rewrite & RRIGHT) &&
ragge
1.162
718                     DECRD(p->n_right->n_reg) != DECRD(p->n_reg)) {
ragge
1.161
719 #ifdef notyet
720                         if (p->n_op == ASSIGN)
721                                 comperr("ASSIGN error");
722 #endif
ragge
1.165
723                         rmove(p->n_right->n_regp->n_regp->n_type);
ragge
1.156
724                         p->n_right->n_reg = p->n_reg;
ragge
1.167
725                         p->n_right->n_rval = p->n_reg;
ragge
1.142
726                 }
727         }
ragge
1.149
728         if ((p->n_su & LMASK) == LREG) {
ragge
1.142
729                 if (q->needs & NSPECIAL) {
ragge
1.158
730                         int rr = rspecial(qNLEFT);
ragge
1.142
731
ragge
1.158
732                         if (rr >= 0 && rr != p->n_left->n_reg) {
ragge
1.162
733                                 rmove(DECRD(p->n_left->n_reg), rr,
ragge
1.165
734                                     p->n_left->n_type);
ragge
1.158
735                                 p->n_left->n_reg = rr;
736                                 p->n_left->n_rval = rr;
ragge
1.141
737                         }
ragge
1.142
738                 } else if ((q->rewrite & RLEFT) &&
ragge
1.162
739                     DECRD(p->n_left->n_reg) != DECRD(p->n_reg)) {
ragge
1.161
740 #ifdef notyet
741                         if (p->n_op == ASSIGN)
742                                 comperr("ASSIGN error");
743 #endif
ragge
1.165
744                         rmove(p->n_left->n_regp->n_regp->n_type);
ragge
1.156
745                         p->n_left->n_reg = p->n_reg;
746                         p->n_left->n_rval = p->n_reg;
ragge
1.134
747                 }
ragge
1.69
748         }
ragge
1.162
749
750         if (p->n_op == ASSIGN &&
751             p->n_left->n_op == REG && p->n_right->n_op == REG &&
752             p->n_left->n_rval == p->n_right->n_rval){
ragge
1.161
753                 /* do not emit anything */
754                 rewrite(pq->rewritecookie);
755                 return;
756         }
ragge
1.147
757
ragge
1.72
758         expand(pcookieq->cstring);
ragge
1.169
759         if (callop(p->n_op) && cookie != FOREFF &&
760             p->n_reg != RETREG(p->n_type)) {
ragge
1.164
761                 rmove(RETREG(p->n_type), DECRD(p->n_reg), p->n_type);
ragge
1.156
762         } else if (q->needs & NSPECIAL) {
ragge
1.158
763                 int rr = rspecial(qNRES);
ragge
1.150
764
ragge
1.158
765                 if (rr >= 0 && p->n_reg != rr)
ragge
1.165
766                         rmove(rrDECRD(p->n_reg), p->n_type);
ragge
1.162
767         } else if ((q->rewrite & RESC1) &&
768             (DECRA1(p->n_reg) != DECRD(p->n_reg))) {
ragge
1.165
769                 rmove(DECRA1(p->n_reg), DECRD(p->n_reg), p->n_type);
ragge
1.149
770         }
ragge
1.160
771         rewrite(pq->rewritecookie);
ragge
1.2
772 }
ragge
1.1
773
774 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
775
ragge
1.30
776 #ifdef PCC_DEBUG
ragge
1.87
777 #undef  PRTABLE
ragge
1.2
778 int
ragge
1.8
779 e2print(NODE *pint downint *aint *b)
ragge
1.2
780 {
ragge
1.85
781 #ifdef PRTABLE
782         extern int tablesize;
783 #endif
ragge
1.1
784
785         *a = *b = down+1;
786         whiledown >= 2 ){
ragge
1.148
787                 fprintf(prfil"\t");
ragge
1.1
788                 down -= 2;
789                 }
ragge
1.148
790         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
791
792
ragge
1.148
793         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
794         switchp->n_op ) { /* special cases */
ragge
1.1
795
796         case REG:
ragge
1.148
797                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
798                 break;
799
ragge
1.121
800         case TEMP:
ragge
1.148
801                 fprintf(prfil" " CONFMTp->n_lval);
ragge
1.121
802                 break;
803
ragge
1.1
804         case ICON:
805         case NAME:
806         case OREG:
ragge
1.148
807                 fprintf(prfil" " );
808                 adrput(prfilp );
ragge
1.1
809                 break;
810
811         case STCALL:
ragge
1.68
812         case USTCALL:
ragge
1.1
813         case STARG:
814         case STASG:
ragge
1.148
815                 fprintf(prfil" size=%d"p->n_stsize );
816                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
817                 break;
818                 }
819
ragge
1.148
820         fprintf(prfil", " );
821         tprint(prfilp->n_typep->n_qual);
822         fprintf(prfil", " );
ragge
1.156
823 #ifndef MULTICLASS
ragge
1.148
824         ifp->n_rall == NOPREF ) fprintf(prfil"NOPREF" );
ragge
1.156
825         else
826 #endif
827         {
ragge
1.155
828 #ifdef MULTICLASS
ragge
1.156
829                 int gregn(struct regw *);
830                 if (p->n_reg < 100000/* XXX */
831                         fprintf(prfil"REG %s"rnames[DECRD(p->n_reg)]);
ragge
1.155
832                 else
ragge
1.156
833                         fprintf(prfil"TEMP %d"gregn(p->n_regw));
ragge
1.155
834 #else
ragge
1.148
835                 ifp->n_rall & MUSTDO ) fprintf(prfil"MUSTDO " );
836                 else fprintf(prfil"PREF " );
ragge
1.122
837                 if ((p->n_rall&~MUSTDO) > 8/* XXX */
ragge
1.148
838                 fprintf(prfil"(%d)", (p->n_rall&~MUSTDO));
839                 else fprintf(prfil"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.155
840 #endif
ragge
1.1
841                 }
ragge
1.151
842 #ifdef MULTICLASS
843         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
844 #else
ragge
1.148
845         fprintf(prfil", SU= %d(%s,%s,%s,%s)\n",
ragge
1.151
846 #endif
ragge
1.85
847             TBLIDX(p->n_su), 
ragge
1.151
848 #ifdef MULTICLASS
849             TCLASS(p->n_su)+'@',
850 #endif
ragge
1.85
851 #ifdef PRTABLE
852             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
853             table[TBLIDX(p->n_su)].cstring : "",
854 #else
855             "",
856 #endif
857             ltyp[LMASK&p->n_su],
ragge
1.70
858             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
859         return 0;
860 }
ragge
1.30
861 #endif
ragge
1.1
862
863 #ifndef FIELDOPS
ragge
1.7
864 /*
865  * do this if there is no special hardware support for fields
866  */
867 static int
868 ffld(NODE *pint downint *down1int *down2 )
869 {
870         /*
871          * look for fields that are not in an lvalue context,
872          * and rewrite them...
873          */
874         NODE *shp;
875         int sovty;
ragge
1.1
876
ragge
1.13
877         *down1 =  asgopp->n_op );
ragge
1.1
878         *down2 = 0;
879
ragge
1.13
880         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
881
ragge
1.7
882                 if( !rewfld(p) ) return 0;
ragge
1.1
883
ragge
1.48
884                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
885                 v = p->n_rval;
ragge
1.1
886                 s = UPKFSZ(v);
887 # ifdef RTOLBYTES
888                 o = UPKFOFF(v);  /* amount to shift */
889 # else
ragge
1.13
890                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
891 #endif
892
893                 /* make & mask part */
894
ragge
1.13
895                 p->n_left->n_type = ty;
ragge
1.1
896
ragge
1.13
897                 p->n_op = AND;
ragge
1.130
898                 p->n_right = mklnode(ICON, (1 << s)-10ty);
ragge
1.1
899
900                 /* now, if a shift is needed, do it */
901
902                 ifo != 0 ){
ragge
1.130
903                         shp = mkbinode(RSp->n_left,
904                             mklnode(ICONo0ty), ty);
ragge
1.13
905                         p->n_left = shp;
ragge
1.1
906                         /* whew! */
907                 }
908         }
ragge
1.7
909         return 0;
910 }
ragge
1.1
911 #endif
912
ragge
1.23
913 /*
914  * change left TEMPs into OREGs
ragge
1.40
915