Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20051204114900

Diff

Diff from 1.159 to:

Annotations

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

Annotated File View

ragge
1.159
1 /*      $Id: reader.c,v 1.159 2005/12/04 11:49:00 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.124
270                 compile2(ip);
271         } else
272                 compile4(ip);
273 }
274
275 void
276 compile2(struct interpass *ip)
277 {
278         DLIST_INIT(&delayqqelem);
279         delay(ip->ip_node);
280         compile3(ip);
281         while (DLIST_NEXT(&delayqqelem) != &delayq) {
282                 ip = DLIST_NEXT(&delayqqelem);
283                 DLIST_REMOVE(ipqelem);
284                 compile3(ip);
285         }
286 }
287
288 void
289 compile3(struct interpass *ip)
290 {
291         NODE *p = ip->ip_node;
292
293         canon(p);
294         if ((p = deluseless(p)) == NULL)
295                 return/* nothing to do */
296 #ifdef PCC_DEBUG
297         walkf(pcktree);
298         if (e2debug) {
ragge
1.149
299                 printf("Entering pass2\n");
ragge
1.124
300                 fwalk(pe2print0);
ragge
1.123
301         }
ragge
1.124
302 #endif
303         ip->ip_node = p;
304         compile4(ip);
305 }
306
ragge
1.149
307 static struct interpass ipole;
308 /*
309  * Save a complete function before doing anything with it in both the
310  * optimized and unoptimized case.
311  */
312 void
313 compile4(struct interpass *ip)
314 {
315         struct interpass_prolog *epp;
316
317         if (ip->type == IP_PROLOG)
318                 DLIST_INIT(&ipoleqelem);
319
320         DLIST_INSERT_BEFORE(&ipoleipqelem);
321
322         if (ip->type != IP_EPILOG)
323                 return;
324
325 #ifdef PCC_DEBUG
326         if (e2debug)
327                 printip(&ipole);
328 #endif
329         epp = (struct interpass_prolog *)DLIST_PREV(&ipoleqelem);
330         p2maxautooff = p2autooff = epp->ipp_autos;
331
332         optimize(&ipole);
333         ngenregs(&ipole);
334
335         DLIST_FOREACH(ip, &ipoleqelem)
336                 emit(ip);
337 }
ragge
1.124
338
339 void
ragge
1.125
340 emit(struct interpass *ip)
ragge
1.124
341 {
342         NODE *p;
ragge
1.149
343         int o;
ragge
1.124
344
ragge
1.125
345         switch (ip->type) {
346         case IP_NODE:
347                 p = ip->ip_node;
ragge
1.124
348
ragge
1.149
349                 nodepole = p;
ragge
1.124
350                 switch (p->n_op) {
351                 case CBRANCH:
352                         /* Only emit branch insn if RESCC */
353                         if (table[TBLIDX(p->n_left->n_su)].rewrite & RESCC) {
354                                 o = p->n_left->n_op;
355                                 gencode(pFORCC);
356                                 cbgen(op->n_right->n_lval);
357                         } else
358                                 gencode(pFORCC);
359                         break;
360                 case FORCE:
ragge
1.151
361                         gencode(p->n_leftINREGS);
ragge
1.124
362                         break;
363                 default:
364                         if (p->n_op != REG || p->n_type != VOID/* XXX */
365                                 gencode(pFOREFF); /* Emit instructions */
366                 }
367
ragge
1.125
368                 tfree(p);
369                 break;
ragge
1.124
370         case IP_PROLOG:
371                 prologue((struct interpass_prolog *)ip);
372                 break;
373         case IP_EPILOG:
374                 eoftn((struct interpass_prolog *)ip);
375                 tmpsave = NULL/* Always forget old nodes */
376                 p2maxautooff = p2autooff = AUTOINIT;
377                 break;
378         case IP_DEFLAB:
379                 deflab(ip->ip_lbl);
380                 break;
381         case IP_ASM:
382                 printf("\t%s\n"ip->ip_asm);
383                 break;
384         default:
385                 cerror("compile4 %d"ip->type);
386         }
ragge
1.123
387 }
ragge
1.124
388
ragge
1.30
389 #ifdef PCC_DEBUG
ragge
1.1
390 char *cnames[] = {
391         "SANY",
392         "SAREG",
393         "SBREG",
ragge
1.153
394         "SCREG",
395         "SDREG",
ragge
1.1
396         "SCC",
397         "SNAME",
398         "SCON",
399         "SFLD",
400         "SOREG",
401         "STARNM",
402         "STARREG",
403         "INTEMP",
404         "FORARG",
405         "SWADD",
406         0,
ragge
1.72
407 };
ragge
1.1
408
ragge
1.2
409 /*
410  * print a nice-looking description of cookie
411  */
ragge
1.70
412 char *
ragge
1.2
413 prcook(int cookie)
414 {
ragge
1.70
415         static char buf[50];
ragge
1.1
416         int iflag;
417
ragge
1.70
418         if (cookie & SPECIAL) {
419                 switch (cookie) {
420                 case SZERO:
421                         return "SZERO";
422                 case SONE:
423                         return "SONE";
424                 case SMONE:
425                         return "SMONE";
426                 default:
427                         sprintf(buf"SPECIAL+%d"cookie & ~SPECIAL);
428                         return buf;
ragge
1.1
429                 }
ragge
1.70
430         }
ragge
1.1
431
432         flag = 0;
ragge
1.70
433         buf[0] = 0;
434         for (i = 0cnames[i]; ++i) {
435                 if (cookie & (1<<i)) {
436                         if (flag)
437                                 strcat(buf"|");
ragge
1.1
438                         ++flag;
ragge
1.70
439                         strcat(bufcnames[i]);
ragge
1.1
440                 }
ragge
1.70
441         }
442         return buf;
443 }
ragge
1.1
444
ragge
1.30
445 #endif
ragge
1.1
446
447 int odebug = 0;
448
ragge
1.151
449 int
ragge
1.69
450 geninsn(NODE *pint cookie)
451 {
ragge
1.71
452         NODE *p1, *p2;
ragge
1.151
453         int orv = 0;
ragge
1.69
454
455 #ifdef PCC_DEBUG
456         if (odebug) {
ragge
1.70
457                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
458                 fwalk(pe2print0);
459         }
460 #endif
461
462 again:  switch (o = p->n_op) {
ragge
1.71
463         case EQ:
464         case NE:
465         case LE:
466         case LT:
467         case GE:
468         case GT:
469         case ULE:
470         case ULT:
471         case UGE:
472         case UGT:
ragge
1.159
473                 rv = relops(p);
474                 break;
ragge
1.71
475
ragge
1.69
476         case PLUS:
477         case MINUS:
478         case MUL:
479         case DIV:
480         case MOD:
481         case AND:
482         case OR:
483         case ER:
484         case LS:
485         case RS:
ragge
1.151
486                 rv = findops(pcookie);
487                 break;
ragge
1.77
488
489         case INCR:
490         case DECR:
491                 if ((rv = findops(pcookie)) < 0) {
492                         if (setbin(p))
493                                 goto again;
ragge
1.96
494                 } else {
495                         /* Do tree rewriting to ensure correct incr */
496                         if ((rv & LMASK) != LREG)
497                                 goto sw;
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                 /*
531                  * Do subnodes conversions (if needed).
532                  */
ragge
1.71
533 sw:             switch (rv & LMASK) {
ragge
1.69
534                 case LREG:
ragge
1.151
535                         geninsn(p->n_leftINREGS);
ragge
1.69
536                         break;
537                 case LOREG:
ragge
1.102
538                         if (p->n_left->n_op == FLD) {
ragge
1.151
539                                 offstar(p->n_left->n_left->n_left0); /* XXX */
ragge
1.102
540                                 p->n_left->n_left->n_su = -1;
541                         } else
ragge
1.151
542                                 offstar(p->n_left->n_left0);
ragge
1.69
543                         p->n_left->n_su = -1;
544                         break;
545                 case LTEMP:
546                         geninsn(p->n_leftINTEMP);
547                         break;
548                 }
549
550                 switch (rv & RMASK) {
551                 case RREG:
ragge
1.151
552                         geninsn(p->n_rightINREGS);
ragge
1.69
553                         break;
554                 case ROREG:
ragge
1.151
555                         offstar(p->n_right->n_left0);
ragge
1.69
556                         p->n_right->n_su = -1;
557                         break;
558                 case RTEMP:
559                         geninsn(p->n_rightINTEMP);
560                         break;
561                 }
562                 p->n_su = rv;
563                 break;
564
565         case REG:
ragge
1.144
566         case TEMP:
ragge
1.72
567         case NAME:
ragge
1.71
568         case ICON:
ragge
1.69
569         case OREG:
ragge
1.83
570 #if 0
ragge
1.69
571                 if ((cookie & (INTAREG|INTBREG)) == 0)
ragge
1.71
572                         comperr("geninsn OREG, node %p"p);
ragge
1.83
573 #endif
ragge
1.152
574                 rv = findleaf(pcookie);
575                 break;
ragge
1.69
576
ragge
1.82
577         case UMUL:
578                 /*
579                  * If we end up here with an UMUL, try to fold it into
580                  * an OREG anyway.
581                  */
ragge
1.86
582                 if (p->n_type == STRTY) {
583                         /* XXX - what to do here? */
584                         geninsn(p->n_leftcookie);
585                         p->n_su = -1;
586                         break;
587                 }
588 #if 0
ragge
1.82
589                 if ((cookie & INTAREG) == 0)
590                         comperr("bad umul!");
ragge
1.86
591 #endif
ragge
1.151
592                 if (offstar(p->n_left0)) {
ragge
1.84
593                         p->n_op = OREG;
594                         if ((rv = findleaf(pcookie)) < 0)
595                                 comperr("bad findleaf"); /* XXX */
596                         p->n_op = UMUL;
597                         p->n_su = rv | LOREG;
598                         break;
599                 }
ragge
1.109
600                 /* FALLTHROUGH */
ragge
1.82
601
ragge
1.86
602         case COMPL:
ragge
1.85
603         case UMINUS:
ragge
1.71
604         case PCONV:
605         case SCONV:
606         case INIT:
ragge
1.70
607         case GOTO:
608         case FUNARG:
ragge
1.72
609         case UCALL:
ragge
1.103
610         case USTCALL:
ragge
1.155
611                 rv = finduni(pcookie);
612                 break;
ragge
1.69
613
ragge
1.71
614         case CBRANCH:
615                 p1 = p->n_left;
616                 p2 = p->n_right;
617                 p1->n_label = p2->n_lval;
618                 o = p1->n_op;
619                 geninsn(p1FORCC);
620                 p->n_su = -1/* su calculations traverse left */
621                 break;
622
623         case FORCE:
ragge
1.151
624                 geninsn(p->n_leftINREGS);
ragge
1.71
625                 p->n_su = -1/* su calculations traverse left */
626                 break;
627
ragge
1.69
628         default:
ragge
1.72
629                 comperr("geninsn: bad op %d, node %p"op);
ragge
1.69
630         }
ragge
1.151
631         switch (o) {
ragge
1.152
632         case REG:
633         case TEMP:
634         case NAME:
635         case ICON:
636         case OREG:
ragge
1.151
637         case ASSIGN:
638         case PLUS:
639         case MINUS:
640         case MUL:
641         case DIV:
642         case MOD:
643         case AND:
644         case OR:
645         case ER:
646         case LS:
647         case RS:
ragge
1.155
648         case COMPL:
649         case UMINUS:
650         case PCONV:
651         case SCONV:
652         case INIT:
653         case GOTO:
654         case FUNARG:
655         case UCALL:
656         case USTCALL:
ragge
1.151
657                 switch (rv) {
658                 case FRETRY:
659                         goto again;
660                 case FFAIL:
661                         goto failed;
662                 }
663         }
ragge
1.153
664         return rv;
ragge
1.69
665
666 failed:
ragge
1.84
667         comperr("Cannot generate code, node %p op %s"popst[p->n_op]);
ragge
1.151
668         return 0/* XXX gcc */
ragge
1.69
669 }
670
ragge
1.72
671 /*
672  * Store a given subtree in a temporary location.
673  * Return an OREG node where it is located.
674  */
675 NODE *
676 store(NODE *p)
ragge
1.2
677 {
ragge
1.130
678         extern struct interpass *storesave;
679         struct interpass *ip;
680         NODE *q, *r;
681         int s;
ragge
1.49
682
ragge
1.130
683         s = BITOOR(freetemp(szty(p->n_type)));
684         q = mklnode(OREGsFPREGp->n_type);
685         r = mklnode(OREGsFPREGp->n_type);
686         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
687
ragge
1.149
688         storesave = ip;
ragge
1.72
689         return r;
ragge
1.8
690 }
ragge
1.1
691
ragge
1.69
692 /*
ragge
1.75
693  * Rewrite node after instruction emit.
694  */
695 static void
696 rewrite(NODE *pint rewrite)
697 {
ragge
1.140
698 //      struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.79
699         NODE *l, *r;
700         int o;
701
ragge
1.75
702         if (p->n_su == -1)
703                 comperr("rewrite");
704
ragge
1.80
705         l = getlr(p'L');
706         r = getlr(p'R');
ragge
1.79
707         o = p->n_op;
ragge
1.75
708         p->n_op = REG;
ragge
1.76
709         p->n_lval = 0;
ragge
1.95
710         p->n_name = "";
ragge
1.158
711
ragge
1.140
712         if (rewrite & RLEFT) {
ragge
1.79
713 #ifdef PCC_DEBUG
714                 if (l->n_op != REG)
715                         comperr("rewrite left");
716 #endif
ragge
1.158
717                 p->n_rval = p->n_reg;
ragge
1.79
718         } else if (rewrite & RRIGHT) {
719 #ifdef PCC_DEBUG
720                 if (r->n_op != REG)
721                         comperr("rewrite right");
722 #endif
ragge
1.158
723                 p->n_rval = p->n_reg;
ragge
1.156
724         } else if (rewrite & RESC1) {
ragge
1.158
725                 p->n_rval = p->n_reg;
ragge
1.156
726         } else if (rewrite & RESC2)
727 #ifdef MULTICLASS
ragge
1.157
728                 p->n_reg = p->n_rval = p->n_reg;
ragge
1.156
729 #else
ragge
1.79
730                 p->n_rval = p->n_rall + szty(p->n_type);
ragge
1.156
731 #endif
ragge
1.75
732         else if (rewrite & RESC3)
ragge
1.156
733 #ifdef MULTICLASS
734                 p->n_rval = 0/* XXX */
735 #else
ragge
1.79
736                 p->n_rval = p->n_rall + 2*szty(p->n_type);
ragge
1.156
737 #endif
ragge
1.99
738         else if (p->n_su == DORIGHT)
ragge
1.156
739 #ifdef MULTICLASS
740                 p->n_reg = p->n_rval = l->n_rval/* XXX special */
741 #else
ragge
1.133
742                 p->n_rall = p->n_rval = l->n_rval/* XXX special */
ragge
1.156
743 #endif
ragge
1.79
744         if (optype(o) != LTYPE)
745                 tfree(l);
746         if (optype(o) == BITYPE)
747                 tfree(r);
ragge
1.75
748 }
749
ragge
1.69
750 void
ragge
1.72
751 gencode(NODE *pint cookie)
ragge
1.69
752 {
753         struct optab *q = &table[TBLIDX(p->n_su)];
754
755         if (p->n_su == -1/* For OREGs and similar */
ragge
1.72
756                 return gencode(p->n_leftcookie);
ragge
1.69
757
ragge
1.156
758         if (p->n_op == REG && p->n_reg == p->n_rval)
759                 return/* meaningless move to itself */
760         if (p->n_op == ASSIGN && p->n_left->n_op == REG &&
761             p->n_left->n_rval == p->n_reg &&
762             (p->n_su & RMASK) &&
763             p->n_right->n_reg == p->n_reg) {
764                 gencode(p->n_rightINREGS);
765                 return/* meaningless assign */
766         }
ragge
1.147
767
ragge
1.69
768         if (p->n_su & DORIGHT) {
ragge
1.151
769                 gencode(p->n_rightINREGS);
ragge
1.69
770                 if ((p->n_su & RMASK) == ROREG)
771                         canon(p);
772         }
773         if (p->n_su & LMASK) {
ragge
1.151
774                 gencode(p->n_leftINREGS);
ragge
1.142
775                 if ((p->n_su & LMASK) == LOREG)
ragge
1.69
776                         canon(p);
777         }
778         if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
ragge
1.151
779                 gencode(p->n_rightINREGS);
ragge
1.69
780                 if ((p->n_su & RMASK) == ROREG)
781                         canon(p);
ragge
1.142
782         }
ragge
1.149
783         if ((p->n_su & RMASK) == RREG) {
ragge
1.142
784                 if (q->needs & NSPECIAL) {
ragge
1.158
785                         int rr = rspecial(qNRIGHT);
ragge
1.142
786
ragge
1.158
787                         if (rr >= 0 && rr != p->n_right->n_reg) {
ragge
1.156
788                                 rmove(p->n_right->n_reg,
ragge
1.158
789                                     rrTCLASS(p->n_right->n_su));
790                                 p->n_right->n_reg = rr;
791                                 p->n_right->n_rval = rr;
ragge
1.142
792                         }
793                 } else if ((q->rewrite & RRIGHT) &&
ragge
1.156
794                     p->n_right->n_reg != p->n_reg) {
795                         rmove(p->n_right->n_regp->n_regTCLASS(p->n_su));
796                         p->n_right->n_reg = p->n_reg;
797                         p->n_right->n_reg = p->n_reg;
ragge
1.142
798                 }
799         }
ragge
1.149
800         if ((p->n_su & LMASK) == LREG) {
ragge
1.142
801                 if (q->needs & NSPECIAL) {
ragge
1.158
802                         int rr = rspecial(qNLEFT);
ragge
1.142
803
ragge
1.158
804                         if (rr >= 0 && rr != p->n_left->n_reg) {
805                                 rmove(p->n_left->n_regrr,
ragge
1.156
806                                     TCLASS(p->n_left->n_su));
ragge
1.158
807                                 p->n_left->n_reg = rr;
808                                 p->n_left->n_rval = rr;
ragge
1.141
809                         }
ragge
1.142
810                 } else if ((q->rewrite & RLEFT) &&
ragge
1.156
811                     p->n_left->n_reg != p->n_reg) {
812                         rmove(p->n_left->n_regp->n_regTCLASS(p->n_su));
813                         p->n_left->n_reg = p->n_reg;
814                         p->n_left->n_rval = p->n_reg;
ragge
1.134
815                 }
ragge
1.69
816         }
ragge
1.147
817
ragge
1.72
818         expand(pcookieq->cstring);
ragge
1.158
819         if (callop(p->n_op) && p->n_reg != RETREG(TCLASS(p->n_su))) {
820                 rmove(RETREG(TCLASS(p->n_su)), p->n_regTCLASS(p->n_su));
ragge
1.156
821         } else if (q->needs & NSPECIAL) {
ragge
1.158
822                 int rr = rspecial(qNRES);
ragge
1.150
823
ragge
1.158
824                 if (rr >= 0 && p->n_reg != rr)
825                         rmove(rrp->n_regTCLASS(p->n_su));
ragge
1.149
826         }
ragge
1.75
827         rewrite(pq->rewrite);
ragge
1.2
828 }
ragge
1.1
829
830 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
831
ragge
1.30
832 #ifdef PCC_DEBUG
ragge
1.87
833 #undef  PRTABLE
ragge
1.2
834 int
ragge
1.8
835 e2print(NODE *pint downint *aint *b)
ragge
1.2
836 {
ragge
1.85
837 #ifdef PRTABLE
838         extern int tablesize;
839 #endif
ragge
1.148
840         FILE *prfil = stdout;
ragge
1.1
841
842         *a = *b = down+1;
843         whiledown >= 2 ){
ragge
1.148
844                 fprintf(prfil"\t");
ragge
1.1
845                 down -= 2;
846                 }
ragge
1.148
847         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
848
849
ragge
1.148
850         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
851         switchp->n_op ) { /* special cases */
ragge
1.1
852
853         case REG:
ragge
1.148
854                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
855                 break;
856
ragge
1.121
857         case TEMP:
ragge
1.148
858                 fprintf(prfil" " CONFMTp->n_lval);
ragge
1.121
859                 break;
860
ragge
1.1
861         case ICON:
862         case NAME:
863         case OREG:
ragge
1.148
864                 fprintf(prfil" " );
865                 adrput(prfilp );
ragge
1.1
866                 break;
867
868         case STCALL:
ragge
1.68
869         case USTCALL:
ragge
1.1
870         case STARG:
871         case STASG:
ragge
1.148
872                 fprintf(prfil" size=%d"p->n_stsize );
873                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
874                 break;
875                 }
876
ragge
1.148
877         fprintf(prfil", " );
878         tprint(prfilp->n_typep->n_qual);
879         fprintf(prfil", " );
ragge
1.156
880 #ifndef MULTICLASS
ragge
1.148
881         ifp->n_rall == NOPREF ) fprintf(prfil"NOPREF" );
ragge
1.156
882         else
883 #endif
884         {
ragge
1.155
885 #ifdef MULTICLASS
ragge
1.156
886                 int gregn(struct regw *);
887                 if (p->n_reg < 100000/* XXX */
888                         fprintf(prfil"REG %s"rnames[DECRD(p->n_reg)]);
ragge
1.155
889                 else
ragge
1.156
890                         fprintf(prfil"TEMP %d"gregn(p->n_regw));
ragge
1.155
891 #else
ragge
1.148
892                 ifp->n_rall & MUSTDO ) fprintf(prfil"MUSTDO " );
893                 else fprintf(prfil"PREF " );
ragge
1.122
894                 if ((p->n_rall&~MUSTDO) > 8/* XXX */
ragge
1.148
895                 fprintf(prfil"(%d)", (p->n_rall&~MUSTDO));
896                 else fprintf(prfil"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.155
897 #endif
ragge
1.1
898                 }
ragge
1.151
899 #ifdef MULTICLASS
900         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
901 #else
ragge
1.148
902         fprintf(prfil", SU= %d(%s,%s,%s,%s)\n",
ragge
1.151
903 #endif
ragge
1.85
904             TBLIDX(p->n_su), 
ragge
1.151
905 #ifdef MULTICLASS
906             TCLASS(p->n_su)+'@',
907 #endif
ragge
1.85
908 #ifdef PRTABLE
909             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
910             table[TBLIDX(p->n_su)].cstring : "",
911 #else
912             "",
913 #endif
914             ltyp[LMASK&p->n_su],
ragge
1.70
915             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
916         return 0;
917 }
ragge
1.30
918 #endif
ragge
1.1
919
920 #ifndef FIELDOPS
ragge
1.7
921 /*
922  * do this if there is no special hardware support for fields
923  */
924 static int
925 ffld(NODE *pint downint *down1int *down2 )
926 {
927         /*
928          * look for fields that are not in an lvalue context,
929          * and rewrite them...
930          */
931         NODE *shp;
932