Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040505063311

Diff

Diff from 1.85 to:

Annotations

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

Annotated File View

ragge
1.85
1 /*      $Id: reader.c,v 1.85 2004/05/05 06:33:12 ragge Exp $    */
ragge
1.72
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
ragge
1.31
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
ragge
1.1
62
63 # include "pass2.h"
ragge
1.49
64 #include "external.h"
ragge
1.1
65
ragge
1.70
66 #include <string.h>
ragge
1.71
67 #include <stdarg.h>
ragge
1.70
68
ragge
1.1
69 /*      some storage declarations */
70 int nrecur;
71 int lflag;
ragge
1.9
72 int x2debug;
ragge
1.1
73 int udebug = 0;
ragge
1.32
74 int ftnno;
ragge
1.71
75 static int thisline;
ragge
1.72
76 int fregs;
ragge
1.1
77
ragge
1.72
78 NODE *nodepole;
ragge
1.37
79 static int saving;
ragge
1.1
80
ragge
1.23
81 static struct templst {
82         struct templst *next;
83         int tempnr;
84         int tempoff;
85 } *templst;
86
ragge
1.10
87 int e2print(NODE *pint downint *aint *b);
ragge
1.37
88 void saveip(struct interpass *ip);
89 void deljumps(void);
ragge
1.40
90 void deltemp(NODE *p);
ragge
1.37
91 void optdump(struct interpass *ip);
ragge
1.40
92 void cvtemps(struct interpass *epil);
ragge
1.69
93 int findops(NODE *pint);
94 int findasg(NODE *pint);
95 int finduni(NODE *pint);
96 int findleaf(NODE *pint);
ragge
1.65
97 int relops(NODE *p);
98 int asgops(NODE *pint);
ragge
1.72
99 NODE *store(NODE *);
ragge
1.65
100
ragge
1.72
101 static void gencode(NODE *pint cookie);
ragge
1.69
102
103 static char *ltyp[] = { """LREG""LOREG""LTEMP" };
104 static char *rtyp[] = { """RREG""ROREG""RTEMP" };
ragge
1.37
105
ragge
1.46
106 #define DELAYS 20
107 NODE *deltrees[DELAYS];
108 int deli;
ragge
1.26
109
110 #ifdef PCC_DEBUG
111 static void
112 cktree(NODE *p)
113 {
114         if (p->n_op > MAXOP)
115                 cerror("op %d slipped through"p->n_op);
ragge
1.35
116         if (p->n_op == CBRANCH && !logop(p->n_left->n_op))
117                 cerror("not logop branch");
ragge
1.47
118         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
119                 cerror("asgop %d slipped through"p->n_op);
ragge
1.78
120         if (p->n_op ==CALL)
121                 cerror("non-UCALL node");
ragge
1.26
122 }
123 #endif
ragge
1.8
124
ragge
1.17
125 static void
ragge
1.2
126 p2compile(NODE *p)
127 {
ragge
1.46
128         int i;
129
ragge
1.15
130 #if !defined(MULTIPASS)
131         extern char *ftitle;
132 #endif
ragge
1.1
133
ragge
1.14
134         if (lflag)
135                 lineid(linenoftitle);
136
ragge
1.1
137         /* generate code for the tree p */
ragge
1.26
138 #ifdef PCC_DEBUG
139         walkf(pcktree);
ragge
1.79
140         if (e2debug) {
141                 fprintf(stderr"Entering pass2\n");
ragge
1.26
142                 fwalk(pe2print0);
ragge
1.79
143         }
ragge
1.26
144 #endif
ragge
1.25
145
ragge
1.1
146 # ifdef MYREADER
147         MYREADER(p);  /* do your own laundering of the input */
148 # endif
149         nrecur = 0;
ragge
1.46
150         deli = 0;
151         delay(p);
ragge
1.25
152         codgen(pFOREFF);
ragge
1.46
153         for (i = 0i < deli; ++i)
154                 codgen(deltrees[i], FOREFF);  /* do the rest */
ragge
1.75
155         tfree(p);
ragge
1.46
156 }
157
158 /* look for delayable ++ and -- operators */
159 void
160 delay(NODE *p)
161 {
162         int ty = optype(p->n_op);
163
164         switch (p->n_op) {
ragge
1.68
165         case UCALL:
ragge
1.46
166         case STCALL:
ragge
1.68
167         case USTCALL:
ragge
1.46
168         case FORTCALL:
ragge
1.68
169         case UFORTCALL:
ragge
1.46
170         case CBRANCH:
171                 /* for the moment, don7t delay past a conditional context, or
172                  * inside of a call */
173                 return;
174
ragge
1.67
175         case UMUL:
ragge
1.46
176                 /* if *p++, do not rewrite */
177                 ifautoincrp ) ) return;
178                 break;
179
180         case INCR:
181         case DECR:
ragge
1.83
182                 break;
ragge
1.46
183                 ifdeltestp ) ){
184                         ifdeli < DELAYS ){
185                                 register NODE *q;
186                                 deltrees[deli++] = tcopy(p);
187                                 q = p->n_left;
ragge
1.58
188                                 nfree(p->n_right); /* zap constant */
ragge
1.46
189                                 *p = *q;
ragge
1.58
190                                 nfree(q);
ragge
1.46
191                                 return;
192                         }
ragge
1.83
193                 }
ragge
1.46
194
ragge
1.83
195         }
ragge
1.46
196
197         if (ty == BITYPE)
198                 delay(p->n_right);
199         if (ty != LTYPE)
200                 delay(p->n_left);
ragge
1.2
201 }
ragge
1.1
202
ragge
1.17
203 static void newblock(int myregint aoff);
204 static void epilogue(int regsint autosint retlab);
205
ragge
1.2
206 void
ragge
1.17
207 pass2_compile(struct interpass *ip)
208 {
ragge
1.37
209         if (Oflag) {
210                 if (ip->type == IP_PROLOG)
211                         saving++;
212                 if (saving)
213                         return saveip(ip);
214         }
ragge
1.17
215         switch (ip->type) {
216         case IP_NODE:
ragge
1.71
217                 thisline = ip->lineno;
ragge
1.17
218                 p2compile(ip->ip_node);
ragge
1.21
219                 tfree(ip->ip_node);
ragge
1.17
220                 break;
221         case IP_PROLOG:
222                 prologue(ip->ip_regsip->ip_auto);
223                 break;
224         case IP_NEWBLK:
225                 newblock(ip->ip_regsip->ip_auto);
226                 break;
227         case IP_EPILOG:
228                 epilogue(ip->ip_regsip->ip_autoip->ip_retl);
ragge
1.18
229                 break;
230         case IP_LOCCTR:
231                 setlocc(ip->ip_locc);
232                 break;
233         case IP_DEFLAB:
234                 deflab(ip->ip_lbl);
235                 break;
236         case IP_DEFNAM:
237                 defname(ip->ip_nameip->ip_vis);
ragge
1.39
238                 break;
239         case IP_ASM:
240                 printf("%s\n"ip->ip_asm);
ragge
1.18
241                 break;
ragge
1.17
242         default:
243                 cerror("pass2_compile %d"ip->type);
244         }
245 }
246
247 static void
ragge
1.16
248 newblock(int myregint aoff)
ragge
1.2
249 {
ragge
1.1
250         setregs();
ragge
1.2
251 }
ragge
1.1
252
ragge
1.17
253 static void
ragge
1.16
254 epilogue(int regsint autosint retlab)
ragge
1.2
255 {
ragge
1.23
256         templst = NULL;
ragge
1.16
257         eoftn(regsautosretlab);
ragge
1.2
258 }
ragge
1.1
259
ragge
1.2
260 /*
261  * generate the code for p;
ragge
1.72
262  * store may call codgen recursively
ragge
1.2
263  * cookie is used to describe the context
264  */
265 void
266 codgen(NODE *pint cookie)
267 {
ragge
1.71
268         int o;
ragge
1.70
269
ragge
1.71
270         nodepole = p;
ragge
1.69
271         canon(p);  /* creats OREG from * if possible and does sucomp */
272 #ifdef PCC_DEBUG
273         if (e2debug) {
274                 printf("geninsn called on:\n");
275                 fwalk(pe2print0);
276         }
277 #endif
ragge
1.70
278         do {
279                 geninsn(pcookie); /* Assign instructions for tree */
ragge
1.78
280 #ifdef PCC_DEBUG
281                 if (udebug) {
282                         printf("sucomp called on:\n");
283                         fwalk(pe2print0);
284                 }
285 #endif
ragge
1.72
286         } while (sucomp(p) < 0);  /* Calculate sub-tree evaluation order */
ragge
1.69
287 #ifdef PCC_DEBUG
288         if (udebug) {
289                 printf("genregs called on:\n");
290                 fwalk(pe2print0);
291         }
292 #endif
ragge
1.72
293         /*
294          * When here it is known that the tree can be evaluated.
295          * Assign registers for all instructions.
296          */
ragge
1.69
297         genregs(p); /* allocate registers for instructions */
ragge
1.72
298 #ifdef PCC_DEBUG
299         if (udebug) {
300                 printf("gencode called on:\n");
301                 fwalk(pe2print0);
302         }
303 #endif
ragge
1.71
304         switch (p->n_op) {
305         case CBRANCH:
306                 o = p->n_left->n_op;
ragge
1.72
307                 gencode(pFORCC);
ragge
1.71
308                 cbgen(op->n_right->n_lval);
309                 break;
310         case FORCE:
ragge
1.72
311                 gencode(p->n_leftINTAREG|INTBREG);
ragge
1.71
312                 break;
313         default:
314                 if (p->n_op != REG || p->n_type != VOID/* XXX */
ragge
1.72
315                         gencode(pFOREFF); /* Emit instructions */
ragge
1.71
316         }
ragge
1.2
317 }
ragge
1.1
318
ragge
1.30
319 #ifdef PCC_DEBUG
ragge
1.1
320 char *cnames[] = {
321         "SANY",
322         "SAREG",
323         "STAREG",
324         "SBREG",
325         "STBREG",
326         "SCC",
327         "SNAME",
328         "SCON",
329         "SFLD",
330         "SOREG",
331         "STARNM",
332         "STARREG",
333         "INTEMP",
334         "FORARG",
335         "SWADD",
336         0,
ragge
1.72
337 };
ragge
1.1
338
ragge
1.2
339 /*
340  * print a nice-looking description of cookie
341  */
ragge
1.70
342 char *
ragge
1.2
343 prcook(int cookie)
344 {
ragge
1.70
345         static char buf[50];
ragge
1.1
346         int iflag;
347
ragge
1.70
348         if (cookie & SPECIAL) {
349                 switch (cookie) {
350                 case SZERO:
351                         return "SZERO";
352                 case SONE:
353                         return "SONE";
354                 case SMONE:
355                         return "SMONE";
356                 default:
357                         sprintf(buf"SPECIAL+%d"cookie & ~SPECIAL);
358                         return buf;
ragge
1.1
359                 }
ragge
1.70
360         }
ragge
1.1
361
362         flag = 0;
ragge
1.70
363         buf[0] = 0;
364         for (i = 0cnames[i]; ++i) {
365                 if (cookie & (1<<i)) {
366                         if (flag)
367                                 strcat(buf"|");
ragge
1.1
368                         ++flag;
ragge
1.70
369                         strcat(bufcnames[i]);
ragge
1.1
370                 }
ragge
1.70
371         }
372         return buf;
373 }
ragge
1.1
374
ragge
1.30
375 #endif
ragge
1.1
376
377 int odebug = 0;
378
ragge
1.2
379 void
ragge
1.69
380 geninsn(NODE *pint cookie)
381 {
ragge
1.71
382         NODE *p1, *p2;
ragge
1.69
383         int orv;
384
385 #ifdef PCC_DEBUG
386         if (odebug) {
ragge
1.70
387                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
388                 fwalk(pe2print0);
389         }
390 #endif
391
392 again:  switch (o = p->n_op) {
ragge
1.71
393         case EQ:
394         case NE:
395         case LE:
396         case LT:
397         case GE:
398         case GT:
399         case ULE:
400         case ULT:
401         case UGE:
402         case UGT:
403                 if ((rv = relops(p)) < 0) {
404                         if (setbin(p))
405                                 goto again;
406                         goto failed;
407                 }
408                 goto sw;
409
ragge
1.69
410         case PLUS:
411         case MINUS:
412         case MUL:
413         case DIV:
414         case MOD:
415         case AND:
416         case OR:
417         case ER:
418         case LS:
419         case RS:
420                 if ((rv = findops(pcookie)) < 0) {
421                         if (setbin(p))
422                                 goto again;
423                         goto failed;
424                 }
ragge
1.71
425                 goto sw;
ragge
1.77
426
427         case INCR:
428         case DECR:
429                 if ((rv = findops(pcookie)) < 0) {
430                         if (setbin(p))
431                                 goto again;
432                 } else
433                         goto sw;
434
435                 /*
436                  * Rewrite x++ to (x = x + 1) -1;
437                  */
438                 p1 = p->n_left;
439                 p->n_op = o == INCR ? MINUS : PLUS;
440                 /* Assign node */
441                 p2 = talloc();
442                 p2->n_type = p->n_type;
443                 p2->n_name = "";
444                 p2->n_op = ASSIGN;
445                 p->n_left = p2;
446                 p->n_left->n_left = p1;
447                 /* incr/decr node */
448                 p2 = talloc();
449                 p2->n_type = p->n_type;
450                 p2->n_name = "";
451                 p2->n_op = o == INCR ? PLUS : MINUS;
452                 p->n_left->n_right = p2;
453                 /* const one node */
454                 p->n_left->n_right->n_right = tcopy(p->n_right);
455                 /* input tree */
456                 p1 = tcopy(p1);
457                 /* idstrip(p1); */
458                 p->n_left->n_right->n_left = p1;
459                 goto again;
ragge
1.71
460
ragge
1.69
461         case ASSIGN:
ragge
1.71
462                 if ((rv = findasg(pcookie)) < 0) {
ragge
1.69
463                         if (setasg(pcookie))
464                                 goto again;
465                         goto failed;
466                 }
467                 /*
468                  * Do subnodes conversions (if needed).
469                  */
ragge
1.71
470 sw:             switch (rv & LMASK) {
ragge
1.69
471                 case LREG:
472                         geninsn(p->n_leftINTAREG|INTBREG);
473                         break;
474                 case LOREG:
475                         offstar(p->n_left->n_left);
476                         p->n_left->n_su = -1;
477                         break;
478                 case LTEMP:
479                         geninsn(p->n_leftINTEMP);
480                         break;
481                 }
482
483                 switch (rv & RMASK) {
484                 case RREG:
485                         geninsn(p->n_rightINTAREG|INTBREG);
486                         break;
487                 case ROREG:
488                         offstar(p->n_right->n_left);
489                         p->n_right->n_su = -1;
490                         break;
491                 case RTEMP:
492                         geninsn(p->n_rightINTEMP);
493                         break;
494                 }
495                 p->n_su = rv;
496                 break;
497
498         case REG:
499                 if (istnode(p))
ragge
1.71
500                         comperr("geninsn REG");
ragge
1.69
501                 /* FALLTHROUGH */
ragge
1.72
502         case NAME:
ragge
1.71
503         case ICON:
ragge
1.69
504         case OREG:
ragge
1.83
505 #if 0
ragge
1.69
506                 if ((cookie & (INTAREG|INTBREG)) == 0)
ragge
1.71
507                         comperr("geninsn OREG, node %p"p);
ragge
1.83
508 #endif
ragge
1.69
509                 if ((rv = findleaf(pcookie)) < 0) {
510                         if (setasg(pcookie))
511                                 goto again;
512                         goto failed;
513                 }
514                 p->n_su = rv;
515                 break;
516
ragge
1.82
517         case UMUL:
518                 /*
519                  * If we end up here with an UMUL, try to fold it into
520                  * an OREG anyway.
521                  */
522                 if ((cookie & INTAREG) == 0)
523                         comperr("bad umul!");
ragge
1.84
524                 if (offstar(p->n_left)) {
525                         p->n_op = OREG;
526                         if ((rv = findleaf(pcookie)) < 0)
527                                 comperr("bad findleaf"); /* XXX */
528                         p->n_op = UMUL;
529                         p->n_su = rv | LOREG;
530                         break;
531                 }
ragge
1.82
532
ragge
1.85
533         case UMINUS:
ragge
1.71
534         case PCONV:
535         case SCONV:
536         case INIT:
ragge
1.70
537         case GOTO:
538         case FUNARG:
ragge
1.72
539         case UCALL:
ragge
1.69
540                 if ((rv = finduni(pcookie)) < 0) {
541                         if (setuni(pcookie))
542                                 goto again;
543                         goto failed;
544                 }
545                 switch (rv & LMASK) {
546                 case LREG:
547                         geninsn(p->n_leftINTAREG|INTBREG);
548                         break;
ragge
1.70
549                 case LOREG:
550                         offstar(p->n_left->n_left);
551                         p->n_left->n_su = -1;
552                         break;
553                 case LTEMP:
554                         geninsn(p->n_leftINTEMP);
555                         break;
ragge
1.69
556                 }
557                 p->n_su = rv;
558                 break;
559
ragge
1.71
560         case CBRANCH:
561                 p1 = p->n_left;
562                 p2 = p->n_right;
563                 p1->n_label = p2->n_lval;
564                 o = p1->n_op;
565                 geninsn(p1FORCC);
566                 p->n_su = -1/* su calculations traverse left */
567                 break;
568
569         case FORCE:
570                 geninsn(p->n_leftINTAREG|INTBREG);
571                 p->n_su = -1/* su calculations traverse left */
572                 break;
573
ragge
1.69
574         default:
ragge
1.72
575                 comperr("geninsn: bad op %d, node %p"op);
ragge
1.69
576         }
577         return;
578
579 failed:
ragge
1.84
580         comperr("Cannot generate code, node %p op %s"popst[p->n_op]);
581
ragge
1.69
582 }
583
ragge
1.72
584 /*
585  * Store a given subtree in a temporary location.
586  * Return an OREG node where it is located.
587  */
588 NODE *
589 store(NODE *p)
ragge
1.2
590 {
ragge
1.72
591         NODE *q, *r, *s;
ragge
1.49
592
ragge
1.72
593         q = talloc();
594         r = talloc();
595         s = talloc();
596         q->n_op = OREG;
597         q->n_type = p->n_type;
598         q->n_name = "";
599         q->n_rval = FPREG;
600         q->n_lval = BITOOR(freetemp(szty(p->n_type)));
601         *r = *q;
602         s->n_op = ASSIGN;
603         s->n_type = p->n_type;
604         s->n_name = "";
605         s->n_left = q;
606         s->n_right = p;
607         codgen(sFOREFF);
ragge
1.80
608         tfree(s);
ragge
1.72
609         return r;
ragge
1.8
610 }
ragge
1.1
611
ragge
1.69
612 /*
613  * Count the number of registers needed to evaluate a tree.
614  * This is the trivial implementation, for machines with symmetric
615  * registers. Machines with difficult register assignment strategies
616  * will need to define this function themselves.
617  * Return value is the number of registers used so far.
618  */
619 int
620 sucomp(NODE *p
621 {
622         struct optab *q = &table[TBLIDX(p->n_su)];
623         int leftright;
624         int nreg;
625
626         if (p->n_su == -1)
627                 return sucomp(p->n_left);
628
ragge
1.72
629         if (p->n_op == UCALL) {
ragge
1.78
630                 if ((p->n_su & LMASK) && sucomp(p->n_left) < 0)
ragge
1.72
631                         return -1;
632                 return fregs;
633         }
634
ragge
1.69
635         nreg = (q->needs & NACOUNT) * szty(p->n_type);
636
637         switch (p->n_su & RMASK) {
638         case RREG:
639         case ROREG:
ragge
1.72
640                 if ((right = sucomp(p->n_right)) < 0)
641                         return right;
ragge
1.69
642                 break;
643         case RTEMP:
644                 cerror("sucomp RTEMP");
645         default:
646                 right = 0;
647         }
648         switch (p->n_su & LMASK) {
649         case LREG:
650         case LOREG:
ragge
1.72
651                 if ((left = sucomp(p->n_left)) < 0)
652                         return left;
ragge
1.69
653                 break;
654         case LTEMP:
655                 cerror("sucomp LTEMP");
656         default:
657                 left = 0;
658         }
ragge
1.72
659 //printf("sucomp: node %p right %d left %d\n", p, right, left);
660         if ((p->n_su & RMASK) && (p->n_su & LMASK) &&
661             right + szty(p->n_left->n_type) > fregs &&
662             left + szty(p->n_right->n_type) > fregs) {
663                 /*
664                  * Must store one subtree. Store the tree
665                  * with highest SU, or left.
666                  */
667                 if (right > left)
668                         p->n_right = store(p->n_right);
669                 else
670                         p->n_left = store(p->n_left);
671                 return -1;
672         }
ragge
1.81
673         if ((right+left) > fregs) {
674                 /* Almost out of regs, traverse the highest SU first */
675                 if (right > left)
676                         p->n_su |= DORIGHT;
677         } else if (right && (q->needs & NASL) && (q->rewrite & RLEFT)) {
678                 /* Make it easier to share regs */
ragge
1.69
679                 p->n_su |= DORIGHT;
ragge
1.81
680         } else if (right > left) {
ragge
1.72
681                 p->n_su |= DORIGHT;
ragge
1.81
682         }
ragge
1.69
683         if (right > nreg)
684                 nreg = right;
685         if (left > nreg)
ragge
1.72
686                 nreg = left;
ragge
1.69
687         return nreg;
ragge
1.72
688 }
689
ragge
1.75
690 /*
691  * Rewrite node after instruction emit.
692  */
693 static void
694 rewrite(NODE *pint rewrite)
695 {
ragge
1.79
696         NODE *l, *r;
697         int o;
698
ragge
1.75
699         if (p->n_su == -1)
700                 comperr("rewrite");
701
ragge
1.80
702         l = getlr(p'L');
703         r = getlr(p'R');
ragge
1.79
704         o = p->n_op;
ragge
1.75
705         p->n_op = REG;
ragge
1.76
706         p->n_lval = 0;
ragge
1.79
707         if (rewrite & RLEFT) {
708 #ifdef PCC_DEBUG
709                 if (l->n_op != REG)
710                         comperr("rewrite left");
711 #endif
712                 p->n_rval = l->n_rval;
713         } else if (rewrite & RRIGHT) {
714 #ifdef PCC_DEBUG
715                 if (r->n_op != REG)
716                         comperr("rewrite right");
717 #endif
718                 p->n_rval = r->n_rval;
719         } else if (rewrite & RESC1)
720                 p->n_rval = p->n_rall;
721         else if (rewrite & RESC2)
722                 p->n_rval = p->n_rall + szty(p->n_type);
ragge
1.75
723         else if (rewrite & RESC3)
ragge
1.79
724                 p->n_rval = p->n_rall + 2*szty(p->n_type);
725         if (optype(o) != LTYPE)
726                 tfree(l);
727         if (optype(o) == BITYPE)
728                 tfree(r);
ragge
1.75
729 }
730
ragge
1.69
731 void
ragge
1.72
732 gencode(NODE *pint cookie)
ragge
1.69
733 {
734         struct optab *q = &table[TBLIDX(p->n_su)];
735
736         if (p->n_su == -1/* For OREGs and similar */
ragge
1.72
737                 return gencode(p->n_leftcookie);
ragge
1.69
738
739         if (p->n_su & DORIGHT) {
ragge
1.72
740                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
741                 if ((p->n_su & RMASK) == ROREG)
742                         canon(p);
743         }
744         if (p->n_su & LMASK) {
ragge
1.72
745                 gencode(p->n_leftINTAREG|INTBREG);
ragge
1.69
746                 if ((p->n_su & LMASK) == LOREG)
747                         canon(p);
748         }
749         if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
ragge
1.72
750                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
751                 if ((p->n_su & RMASK) == ROREG)
752                         canon(p);
753         }
ragge
1.72
754         expand(pcookieq->cstring);
ragge
1.75
755         rewrite(pq->rewrite);
ragge
1.2
756 }
ragge
1.1
757
758 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
759
ragge
1.2
760 void
761 rcount()
762 /* count recursions */
ragge
1.1
763         if( ++nrecur > NRECUR ){
764                 cerror"expression causes compiler loop: try simplifying" );
765         }
ragge
1.2
766 }
ragge
1.1
767
ragge
1.30
768 #ifdef PCC_DEBUG
ragge
1.2
769 int
ragge
1.8
770 e2print(NODE *pint downint *aint *b)
ragge
1.2
771 {
ragge
1.85
772 #ifdef PRTABLE
773         extern int tablesize;
774 #endif
ragge
1.1
775
776         *a = *b = down+1;
777         whiledown >= 2 ){
ragge
1.71
778                 fprintf(stderr"\t");
ragge
1.1
779                 down -= 2;
780                 }
ragge
1.71
781         ifdown-- ) fprintf(stderr"    " );
ragge
1.1
782
783
ragge
1.71
784         fprintf(stderr"%p) %s"popst[p->n_op] );
ragge
1.13
785         switchp->n_op ) { /* special cases */
ragge
1.1
786
787         case REG:
ragge
1.71
788                 fprintf(stderr" %s"rnames[p->n_rval] );
ragge
1.1
789                 break;
790
ragge
1.23
791         case TEMP:
ragge
1.71
792                 fprintf(stderr," %d", (int)p->n_lval);
ragge
1.23
793                 break;
794
ragge
1.1
795         case ICON:
796         case NAME:
797         case OREG:
ragge
1.71
798                 fprintf(stderr" " );
799                 adrput(stderrp );
ragge
1.1
800                 break;
801
802         case STCALL:
ragge
1.68
803         case USTCALL:
ragge
1.1
804         case STARG:
805         case STASG:
ragge
1.71
806                 fprintf(stderr" size=%d"p->n_stsize );
807                 fprintf(stderr" align=%d"p->n_stalign );
ragge
1.1
808                 break;
809                 }
810
ragge
1.71
811         fprintf(stderr", " );
812         tprint(stderrp->n_typep->n_qual);
813         fprintf(stderr", " );
814         ifp->n_rall == NOPREF ) fprintf(stderr"NOPREF" );
ragge
1.1
815         else {
ragge
1.71
816                 ifp->n_rall & MUSTDO ) fprintf(stderr"MUSTDO " );
817                 else fprintf(stderr"PREF " );
818                 fprintf(stderr"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
819                 }
ragge
1.85
820         fprintf(stderr", SU= %d(%s,%s,%s,%s)\n",
821             TBLIDX(p->n_su), 
822 #ifdef PRTABLE
823             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
824             table[TBLIDX(p->n_su)].cstring : "",
825 #else
826             "",
827 #endif
828             ltyp[LMASK&p->n_su],
ragge
1.70
829             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
830         return 0;
831 }
ragge
1.30
832 #endif
ragge
1.1
833
834 #ifndef FIELDOPS
ragge
1.7
835 /*
836  * do this if there is no special hardware support for fields
837  */
838 static int
839 ffld(NODE *pint downint *down1int *down2 )
840 {
841         /*
842          * look for fields that are not in an lvalue context,
843          * and rewrite them...
844          */
845         NODE *shp;
846         int sovty;
ragge
1.1
847
ragge
1.13
848         *down1 =  asgopp->n_op );
ragge
1.1
849         *down2 = 0;
850
ragge
1.13
851         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
852
ragge
1.7
853                 if( !rewfld(p) ) return 0;
ragge
1.1
854
ragge
1.48
855                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
856                 v = p->n_rval;
ragge
1.1
857                 s = UPKFSZ(v);
858 # ifdef RTOLBYTES
859                 o = UPKFOFF(v);  /* amount to shift */
860 # else
ragge
1.13
861                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
862 #endif
863
864                 /* make & mask part */
865
ragge
1.13
866                 p->n_left->n_type = ty;
ragge
1.1
867
ragge
1.13
868                 p->n_op = AND;
869                 p->n_right = talloc();
870                 p->n_right->n_op = ICON;
871                 p->n_right->n_rall = NOPREF;
872                 p->n_right->n_type = ty;
873                 p->n_right->n_lval = 1;
874                 p->n_right->n_rval = 0;
875                 p->n_right->n_name = "";
876                 p->n_right->n_lval <<= s;
877                 p->n_right->n_lval--;
ragge
1.1
878
879                 /* now, if a shift is needed, do it */
880
881                 ifo != 0 ){
882                         shp = talloc();
ragge
1.13
883                         shp->n_op = RS;
884                         shp->n_rall = NOPREF;
885                         shp->n_type = ty;
886                         shp->n_left = p->n_left;
887                         shp->n_right = talloc();
888                         shp->n_right->n_op = ICON;
889                         shp->n_right->n_rall = NOPREF;
890                         shp->n_right->n_type = ty;
891                         shp->n_right->n_rval = 0;
892                         shp->n_right->n_lval = o;  /* amount to shift */
893                         shp->n_right->n_name = "";
894                         p->n_left = shp;
ragge
1.1
895                         /* whew! */
896                 }
897         }
ragge
1.7
898         return 0;
899 }
ragge
1.1
900 #endif
901
ragge
1.23
902 /*
903  * change left TEMPs into OREGs
ragge
1.40
904  */
905 void
906 deltemp(NODE *p)
907 {
908         struct templst *w = templst;
909
910         if (p->n_op != TEMP)
911                 return;
912         /*
913          * the size of a TEMP is in multiples of the reg size.
914          */
915         p->n_op = OREG;
916         p->n_rval = FPREG;
917         while (w != NULL) {
918                 if (w->tempnr == p->n_lval)
919                         break;
920                 w = w->next;
921         }
922         if (w == NULL) {
923                 w = tmpalloc(sizeof(struct templst));
924                 w->tempnr = p->n_lval;
925                 w->tempoff = BITOOR(freetemp(szty(p->n_type)));
926                 w->next = templst;
927                 templst = w;
928         }
929         p->n_lval = w->tempoff;
930         p->n_name = "";
931 }
932
933 /*
ragge
1.48
934  * for pointer/integer arithmetic, set pointer at left node
935  */
936 static void
937 setleft(NODE *p)          
938 {        
939         NODE *q;
940
941         /* only additions for now */
942         if (p->n_op != PLUS)
943                 return;
944         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
945                 q = p->n_right;
946                 p->n_right = p->n_left;
947                 p->n_left = q;
948         }
949 }
950
951 /*
ragge
1.23
952  * look for situations where we can turn * into OREG
953