Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050804063049

Diff

Diff from 1.148 to:

Annotations

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

Annotated File View

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