Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040418121435

Diff

Diff from 1.73 to:

Annotations

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

Annotated File View

ragge
1.73
1 /*      $Id: reader.c,v 1.73 2004/04/18 12:14:35 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.26
120 }
121 #endif
ragge
1.8
122
ragge
1.17
123 static void
ragge
1.2
124 p2compile(NODE *p)
125 {
ragge
1.46
126         int i;
127
ragge
1.15
128 #if !defined(MULTIPASS)
129         extern char *ftitle;
130 #endif
ragge
1.1
131
ragge
1.14
132         if (lflag)
133                 lineid(linenoftitle);
134
ragge
1.1
135         /* generate code for the tree p */
ragge
1.26
136 #ifdef PCC_DEBUG
137         walkf(pcktree);
138         if (e2debug)
139                 fwalk(pe2print0);
140 #endif
ragge
1.25
141
ragge
1.1
142 # ifdef MYREADER
143         MYREADER(p);  /* do your own laundering of the input */
144 # endif
145         nrecur = 0;
ragge
1.46
146         deli = 0;
147         delay(p);
ragge
1.25
148         codgen(pFOREFF);
ragge
1.46
149         for (i = 0i < deli; ++i)
150                 codgen(deltrees[i], FOREFF);  /* do the rest */
ragge
1.1
151         reclaimpRNULL0 );
152         allchk();
ragge
1.46
153 }
154
155 /* look for delayable ++ and -- operators */
156 void
157 delay(NODE *p)
158 {
159         int ty = optype(p->n_op);
160
161         switch (p->n_op) {
162         case CALL:
ragge
1.68
163         case UCALL:
ragge
1.46
164         case STCALL:
ragge
1.68
165         case USTCALL:
ragge
1.46
166         case FORTCALL:
ragge
1.68
167         case UFORTCALL:
ragge
1.46
168         case CBRANCH:
169                 /* for the moment, don7t delay past a conditional context, or
170                  * inside of a call */
171                 return;
172
ragge
1.67
173         case UMUL:
ragge
1.46
174                 /* if *p++, do not rewrite */
175                 ifautoincrp ) ) return;
176                 break;
177
178         case INCR:
179         case DECR:
180                 ifdeltestp ) ){
181                         ifdeli < DELAYS ){
182                                 register NODE *q;
183                                 deltrees[deli++] = tcopy(p);
184                                 q = p->n_left;
ragge
1.58
185                                 nfree(p->n_right); /* zap constant */
ragge
1.46
186                                 *p = *q;
ragge
1.58
187                                 nfree(q);
ragge
1.46
188                                 return;
189                                 }
190                         }
191
192                 }
193
194         if (ty == BITYPE)
195                 delay(p->n_right);
196         if (ty != LTYPE)
197                 delay(p->n_left);
ragge
1.2
198 }
ragge
1.1
199
ragge
1.17
200 static void newblock(int myregint aoff);
201 static void epilogue(int regsint autosint retlab);
202
ragge
1.2
203 void
ragge
1.17
204 pass2_compile(struct interpass *ip)
205 {
ragge
1.37
206         if (Oflag) {
207                 if (ip->type == IP_PROLOG)
208                         saving++;
209                 if (saving)
210                         return saveip(ip);
211         }
ragge
1.17
212         switch (ip->type) {
213         case IP_NODE:
ragge
1.71
214                 thisline = ip->lineno;
ragge
1.17
215                 p2compile(ip->ip_node);
ragge
1.21
216                 tfree(ip->ip_node);
ragge
1.17
217                 break;
218         case IP_PROLOG:
219                 prologue(ip->ip_regsip->ip_auto);
220                 break;
221         case IP_NEWBLK:
222                 newblock(ip->ip_regsip->ip_auto);
223                 break;
224         case IP_EPILOG:
225                 epilogue(ip->ip_regsip->ip_autoip->ip_retl);
ragge
1.18
226                 break;
227         case IP_LOCCTR:
228                 setlocc(ip->ip_locc);
229                 break;
230         case IP_DEFLAB:
231                 deflab(ip->ip_lbl);
232                 break;
233         case IP_DEFNAM:
234                 defname(ip->ip_nameip->ip_vis);
ragge
1.39
235                 break;
236         case IP_ASM:
237                 printf("%s\n"ip->ip_asm);
ragge
1.18
238                 break;
ragge
1.17
239         default:
240                 cerror("pass2_compile %d"ip->type);
241         }
242 }
243
244 static void
ragge
1.16
245 newblock(int myregint aoff)
ragge
1.2
246 {
ragge
1.1
247         setregs();
ragge
1.2
248 }
ragge
1.1
249
ragge
1.17
250 static void
ragge
1.16
251 epilogue(int regsint autosint retlab)
ragge
1.2
252 {
ragge
1.23
253         templst = NULL;
ragge
1.16
254         eoftn(regsautosretlab);
ragge
1.2
255 }
ragge
1.1
256
ragge
1.2
257 /*
258  * generate the code for p;
ragge
1.72
259  * store may call codgen recursively
ragge
1.2
260  * cookie is used to describe the context
261  */
262 void
263 codgen(NODE *pint cookie)
264 {
ragge
1.71
265         int o;
ragge
1.70
266
ragge
1.71
267         nodepole = p;
ragge
1.69
268         canon(p);  /* creats OREG from * if possible and does sucomp */
269 #ifdef PCC_DEBUG
270         if (e2debug) {
271                 printf("geninsn called on:\n");
272                 fwalk(pe2print0);
273         }
274 #endif
ragge
1.70
275         do {
276                 geninsn(pcookie); /* Assign instructions for tree */
ragge
1.72
277         } while (sucomp(p) < 0);  /* Calculate sub-tree evaluation order */
ragge
1.69
278 #ifdef PCC_DEBUG
279         if (udebug) {
280                 printf("genregs called on:\n");
281                 fwalk(pe2print0);
282         }
283 #endif
ragge
1.72
284         /*
285          * When here it is known that the tree can be evaluated.
286          * Assign registers for all instructions.
287          */
ragge
1.69
288         genregs(p); /* allocate registers for instructions */
ragge
1.72
289 #ifdef PCC_DEBUG
290         if (udebug) {
291                 printf("gencode called on:\n");
292                 fwalk(pe2print0);
293         }
294 #endif
ragge
1.71
295         switch (p->n_op) {
296         case CBRANCH:
297                 o = p->n_left->n_op;
ragge
1.72
298                 gencode(pFORCC);
ragge
1.71
299                 cbgen(op->n_right->n_lval);
300                 break;
301         case FORCE:
ragge
1.72
302                 gencode(p->n_leftINTAREG|INTBREG);
ragge
1.71
303                 break;
304         default:
305                 if (p->n_op != REG || p->n_type != VOID/* XXX */
ragge
1.72
306                         gencode(pFOREFF); /* Emit instructions */
ragge
1.71
307         }
ragge
1.2
308 }
ragge
1.1
309
ragge
1.30
310 #ifdef PCC_DEBUG
ragge
1.1
311 char *cnames[] = {
312         "SANY",
313         "SAREG",
314         "STAREG",
315         "SBREG",
316         "STBREG",
317         "SCC",
318         "SNAME",
319         "SCON",
320         "SFLD",
321         "SOREG",
322         "STARNM",
323         "STARREG",
324         "INTEMP",
325         "FORARG",
326         "SWADD",
327         0,
ragge
1.72
328 };
ragge
1.1
329
ragge
1.2
330 /*
331  * print a nice-looking description of cookie
332  */
ragge
1.70
333 char *
ragge
1.2
334 prcook(int cookie)
335 {
ragge
1.70
336         static char buf[50];
ragge
1.1
337         int iflag;
338
ragge
1.70
339         if (cookie & SPECIAL) {
340                 switch (cookie) {
341                 case SZERO:
342                         return "SZERO";
343                 case SONE:
344                         return "SONE";
345                 case SMONE:
346                         return "SMONE";
347                 default:
348                         sprintf(buf"SPECIAL+%d"cookie & ~SPECIAL);
349                         return buf;
ragge
1.1
350                 }
ragge
1.70
351         }
ragge
1.1
352
353         flag = 0;
ragge
1.70
354         buf[0] = 0;
355         for (i = 0cnames[i]; ++i) {
356                 if (cookie & (1<<i)) {
357                         if (flag)
358                                 strcat(buf"|");
ragge
1.1
359                         ++flag;
ragge
1.70
360                         strcat(bufcnames[i]);
ragge
1.1
361                 }
ragge
1.70
362         }
363         return buf;
364 }
ragge
1.1
365
ragge
1.30
366 #endif
ragge
1.1
367
368 int odebug = 0;
369
ragge
1.2
370 void
ragge
1.69
371 geninsn(NODE *pint cookie)
372 {
ragge
1.71
373         NODE *p1, *p2;
ragge
1.69
374         int orv;
375
376 #ifdef PCC_DEBUG
377         if (odebug) {
ragge
1.70
378                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
379                 fwalk(pe2print0);
380         }
381 #endif
382
383 again:  switch (o = p->n_op) {
ragge
1.71
384         case EQ:
385         case NE:
386         case LE:
387         case LT:
388         case GE:
389         case GT:
390         case ULE:
391         case ULT:
392         case UGE:
393         case UGT:
394                 if ((rv = relops(p)) < 0) {
395                         if (setbin(p))
396                                 goto again;
397                         goto failed;
398                 }
399                 goto sw;
400
ragge
1.69
401         case PLUS:
402         case MINUS:
403         case MUL:
404         case DIV:
405         case MOD:
406         case AND:
407         case OR:
408         case ER:
409         case LS:
410         case RS:
411                 if ((rv = findops(pcookie)) < 0) {
412                         if (setbin(p))
413                                 goto again;
414                         goto failed;
415                 }
ragge
1.71
416                 goto sw;
417
ragge
1.69
418         case ASSIGN:
ragge
1.71
419                 if ((rv = findasg(pcookie)) < 0) {
ragge
1.69
420                         if (setasg(pcookie))
421                                 goto again;
422                         goto failed;
423                 }
424                 /*
425                  * Do subnodes conversions (if needed).
426                  */
ragge
1.71
427 sw:             switch (rv & LMASK) {
ragge
1.69
428                 case LREG:
429                         geninsn(p->n_leftINTAREG|INTBREG);
430                         break;
431                 case LOREG:
432                         offstar(p->n_left->n_left);
433                         p->n_left->n_su = -1;
434                         break;
435                 case LTEMP:
436                         geninsn(p->n_leftINTEMP);
437                         break;
438                 }
439
440                 switch (rv & RMASK) {
441                 case RREG:
442                         geninsn(p->n_rightINTAREG|INTBREG);
443                         break;
444                 case ROREG:
445                         offstar(p->n_right->n_left);
446                         p->n_right->n_su = -1;
447                         break;
448                 case RTEMP:
449                         geninsn(p->n_rightINTEMP);
450                         break;
451                 }
452                 p->n_su = rv;
453                 break;
454
455         case REG:
456                 if (istnode(p))
ragge
1.71
457                         comperr("geninsn REG");
ragge
1.69
458                 /* FALLTHROUGH */
ragge
1.72
459         case NAME:
ragge
1.71
460         case ICON:
ragge
1.69
461         case OREG:
462                 if ((cookie & (INTAREG|INTBREG)) == 0)
ragge
1.71
463                         comperr("geninsn OREG, node %p"p);
ragge
1.69
464                 if ((rv = findleaf(pcookie)) < 0) {
465                         if (setasg(pcookie))
466                                 goto again;
467                         goto failed;
468                 }
469                 p->n_su = rv;
470                 break;
471
ragge
1.71
472         case PCONV:
473         case SCONV:
ragge
1.69
474         case UMUL:
ragge
1.71
475         case INIT:
ragge
1.70
476         case GOTO:
477         case FUNARG:
ragge
1.72
478         case UCALL:
ragge
1.69
479                 if ((rv = finduni(pcookie)) < 0) {
480                         if (setuni(pcookie))
481                                 goto again;
482                         goto failed;
483                 }
484                 switch (rv & LMASK) {
485                 case LREG:
486                         geninsn(p->n_leftINTAREG|INTBREG);
487                         break;
ragge
1.70
488                 case LOREG:
489                         offstar(p->n_left->n_left);
490                         p->n_left->n_su = -1;
491                         break;
492                 case LTEMP:
493                         geninsn(p->n_leftINTEMP);
494                         break;
ragge
1.69
495                 }
496                 p->n_su = rv;
497                 break;
498
ragge
1.72
499 #if 0
ragge
1.70
500                 if (gencall(pcookie))
501                         goto failed;
502                 if (cookie == FOREFF)
503                         p->n_type = VOID/* XXX */
504                 gotcall = 1;
505                 break;
ragge
1.72
506 #endif
ragge
1.70
507
ragge
1.71
508         case CBRANCH:
509                 p1 = p->n_left;
510                 p2 = p->n_right;
511                 p1->n_label = p2->n_lval;
512                 o = p1->n_op;
513                 geninsn(p1FORCC);
514                 p->n_su = -1/* su calculations traverse left */
515                 break;
516
517         case FORCE:
518                 geninsn(p->n_leftINTAREG|INTBREG);
519                 p->n_su = -1/* su calculations traverse left */
520                 break;
521
ragge
1.69
522         default:
ragge
1.72
523                 comperr("geninsn: bad op %d, node %p"op);
ragge
1.69
524         }
525         return;
526
527 failed:
528 #ifdef PCC_DEBUG
529         fwalk(pe2print0);
530 #endif
531         cerror("Cannot generate code for op %d\n"o);
532 }
533
ragge
1.72
534 /*
535  * Store a given subtree in a temporary location.
536  * Return an OREG node where it is located.
537  */
538 NODE *
539 store(NODE *p)
ragge
1.2
540 {
ragge
1.72
541         NODE *q, *r, *s;
ragge
1.49
542
ragge
1.72
543         q = talloc();
544         r = talloc();
545         s = talloc();
546         q->n_op = OREG;
547         q->n_type = p->n_type;
548         q->n_name = "";
549         q->n_rval = FPREG;
550         q->n_lval = BITOOR(freetemp(szty(p->n_type)));
551         *r = *q;
552         s->n_op = ASSIGN;
553         s->n_type = p->n_type;
554         s->n_name = "";
555         s->n_left = q;
556         s->n_right = p;
557         codgen(sFOREFF);
558         return r;
ragge
1.8
559 }
ragge
1.1
560
ragge
1.69
561 /*
562  * Count the number of registers needed to evaluate a tree.
563  * This is the trivial implementation, for machines with symmetric
564  * registers. Machines with difficult register assignment strategies
565  * will need to define this function themselves.
566  * Return value is the number of registers used so far.
567  */
568 int
569 sucomp(NODE *p
570 {
571         struct optab *q = &table[TBLIDX(p->n_su)];
572         int leftright;
573         int nreg;
574
575         if (p->n_su == -1)
576                 return sucomp(p->n_left);
577
ragge
1.72
578         if (p->n_op == UCALL) {
579                 if (sucomp(p->n_left) < 0)
580                         return -1;
581                 return fregs;
582         }
583
ragge
1.69
584         nreg = (q->needs & NACOUNT) * szty(p->n_type);
585
586         switch (p->n_su & RMASK) {
587         case RREG:
588         case ROREG:
ragge
1.72
589                 if ((right = sucomp(p->n_right)) < 0)
590                         return right;
ragge
1.69
591                 break;
592         case RTEMP:
593                 cerror("sucomp RTEMP");
594         default:
595                 right = 0;
596         }
597         switch (p->n_su & LMASK) {
598         case LREG:
599         case LOREG:
ragge
1.72
600                 if ((left = sucomp(p->n_left)) < 0)
601                         return left;
ragge
1.69
602                 break;
603         case LTEMP:
604                 cerror("sucomp LTEMP");
605         default:
606                 left = 0;
607         }
ragge
1.72
608 //printf("sucomp: node %p right %d left %d\n", p, right, left);
609         if ((p->n_su & RMASK) && (p->n_su & LMASK) &&
610             right + szty(p->n_left->n_type) > fregs &&
611             left + szty(p->n_right->n_type) > fregs) {
612                 /*
613                  * Must store one subtree. Store the tree
614                  * with highest SU, or left.
615                  */
616                 if (right > left)
617                         p->n_right = store(p->n_right);
618                 else
619                         p->n_left = store(p->n_left);
620                 return -1;
621         }
ragge
1.69
622         if (right > left)
623                 p->n_su |= DORIGHT;
ragge
1.72
624         if (left && right && (q->needs & (NASL|NDLEFT)))
625                 p->n_su |= DORIGHT;
ragge
1.69
626         if (right > nreg)
627                 nreg = right;
628         if (left > nreg)
ragge
1.72
629                 nreg = left;
ragge
1.69
630         return nreg;
ragge
1.72
631 }
632
ragge
1.69
633 void
ragge
1.72
634 gencode(NODE *pint cookie)
ragge
1.69
635 {
636         struct optab *q = &table[TBLIDX(p->n_su)];
637
638         if (p->n_su == -1/* For OREGs and similar */
ragge
1.72
639                 return gencode(p->n_leftcookie);
ragge
1.69
640
641         if (p->n_su & DORIGHT) {
ragge
1.72
642                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
643                 if ((p->n_su & RMASK) == ROREG)
644                         canon(p);
645         }
646         if (p->n_su & LMASK) {
ragge
1.72
647                 gencode(p->n_leftINTAREG|INTBREG);
ragge
1.69
648                 if ((p->n_su & LMASK) == LOREG)
649                         canon(p);
650         }
651         if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
ragge
1.72
652                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
653                 if ((p->n_su & RMASK) == ROREG)
654                         canon(p);
655         }
656         if (!allo(pq))
ragge
1.72
657                 comperr("failed register allocation, node %p"p);
658         expand(pcookieq->cstring);
659         reclaim(pq->rewritecookie);
ragge
1.2
660 }
ragge
1.1
661
662 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
663
ragge
1.2
664 void
665 rcount()
666 /* count recursions */
ragge
1.1
667         if( ++nrecur > NRECUR ){
668                 cerror"expression causes compiler loop: try simplifying" );
669         }
ragge
1.2
670 }
ragge
1.1
671
ragge
1.30
672 #ifdef PCC_DEBUG
ragge
1.2
673 int
ragge
1.8
674 e2print(NODE *pint downint *aint *b)
ragge
1.2
675 {
ragge
1.1
676
677         *a = *b = down+1;
678         whiledown >= 2 ){
ragge
1.71
679                 fprintf(stderr"\t");
ragge
1.1
680                 down -= 2;
681                 }
ragge
1.71
682         ifdown-- ) fprintf(stderr"    " );
ragge
1.1
683
684
ragge
1.71
685         fprintf(stderr"%p) %s"popst[p->n_op] );
ragge
1.13
686         switchp->n_op ) { /* special cases */
ragge
1.1
687
688         case REG:
ragge
1.71
689                 fprintf(stderr" %s"rnames[p->n_rval] );
ragge
1.1
690                 break;
691
ragge
1.23
692         case TEMP:
ragge
1.71
693                 fprintf(stderr," %d", (int)p->n_lval);
ragge
1.23
694                 break;
695
ragge
1.1
696         case ICON:
697         case NAME:
698         case OREG:
ragge
1.71
699                 fprintf(stderr" " );
700                 adrput(stderrp );
ragge
1.1
701                 break;
702
703         case STCALL:
ragge
1.68
704         case USTCALL:
ragge
1.1
705         case STARG:
706         case STASG:
ragge
1.71
707                 fprintf(stderr" size=%d"p->n_stsize );
708                 fprintf(stderr" align=%d"p->n_stalign );
ragge
1.1
709                 break;
710                 }
711
ragge
1.71
712         fprintf(stderr", " );
713         tprint(stderrp->n_typep->n_qual);
714         fprintf(stderr", " );
715         ifp->n_rall == NOPREF ) fprintf(stderr"NOPREF" );
ragge
1.1
716         else {
ragge
1.71
717                 ifp->n_rall & MUSTDO ) fprintf(stderr"MUSTDO " );
718                 else fprintf(stderr"PREF " );
719                 fprintf(stderr"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
720                 }
ragge
1.71
721         fprintf(stderr", SU= %d(%s,%s,%s)\n",
722             TBLIDX(p->n_su), ltyp[LMASK&p->n_su],
ragge
1.70
723             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
724         return 0;
725 }
ragge
1.30
726 #endif
ragge
1.1
727
728 #ifndef FIELDOPS
ragge
1.7
729 /*
730  * do this if there is no special hardware support for fields
731  */
732 static int
733 ffld(NODE *pint downint *down1int *down2 )
734 {
735         /*
736          * look for fields that are not in an lvalue context,
737          * and rewrite them...
738          */
739         NODE *shp;
740         int sovty;
ragge
1.1
741
ragge
1.13
742         *down1 =  asgopp->n_op );
ragge
1.1
743         *down2 = 0;
744
ragge
1.13
745         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
746
ragge
1.7
747                 if( !rewfld(p) ) return 0;
ragge
1.1
748
ragge
1.48
749                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
750                 v = p->n_rval;
ragge
1.1
751                 s = UPKFSZ(v);
752 # ifdef RTOLBYTES
753                 o = UPKFOFF(v);  /* amount to shift */
754 # else
ragge
1.13
755                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
756 #endif
757
758                 /* make & mask part */
759
ragge
1.13
760                 p->n_left->n_type = ty;
ragge
1.1
761
ragge
1.13
762                 p->n_op = AND;
763                 p->n_right = talloc();
764                 p->n_right->n_op = ICON;
765                 p->n_right->n_rall = NOPREF;
766                 p->n_right->n_type = ty;
767                 p->n_right->n_lval = 1;
768                 p->n_right->n_rval = 0;
769                 p->n_right->n_name = "";
770                 p->n_right->n_lval <<= s;
771                 p->n_right->n_lval--;
ragge
1.1
772
773                 /* now, if a shift is needed, do it */
774
775                 ifo != 0 ){
776                         shp = talloc();
ragge
1.13
777                         shp->n_op = RS;
778                         shp->n_rall = NOPREF;
779                         shp->n_type = ty;
780                         shp->n_left = p->n_left;
781                         shp->n_right = talloc();
782                         shp->n_right->n_op = ICON;
783                         shp->n_right->n_rall = NOPREF;
784                         shp->n_right->n_type = ty;
785                         shp->n_right->n_rval = 0;
786                         shp->n_right->n_lval = o;  /* amount to shift */
787                         shp->n_right->n_name = "";
788                         p->n_left = shp;
ragge
1.1
789                         /* whew! */
790                 }
791         }
ragge
1.7
792         return 0;
793 }
ragge
1.1
794 #endif
795
ragge
1.23
796 /*
797  * change left TEMPs into OREGs
ragge
1.40
798  */
799 void
800 deltemp(NODE *p)
801 {
802         struct templst *w = templst;
803
804         if (p->n_op != TEMP)
805                 return;
806         /*
807          * the size of a TEMP is in multiples of the reg size.
808          */
809         p->n_op = OREG;
810         p->n_rval = FPREG;
811         while (w != NULL) {
812                 if (w->tempnr == p->n_lval)
813                         break;
814                 w = w->next;
815         }
816         if (w == NULL) {
817                 w = tmpalloc(sizeof(struct templst));
818                 w->tempnr = p->n_lval;
819                 w->tempoff = BITOOR(freetemp(szty(p->n_type)));
820                 w->next = templst;
821                 templst = w;
822         }
823         p->n_lval = w->tempoff;
824         p->n_name = "";
825 }
826
827 /*
ragge
1.48
828  * for pointer/integer arithmetic, set pointer at left node
829  */
830 static void
831 setleft(NODE *p)          
832 {        
833         NODE *q;
834
835         /* only additions for now */
836         if (p->n_op != PLUS)
837                 return;
838         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
839                 q = p->n_right;
840                 p->n_right = p->n_left;
841                 p->n_left = q;
842         }
843 }
844
845 /*
ragge
1.23
846  * look for situations where we can turn * into OREG
847  */
ragge
1.2
848 void
849 oreg2(NODE *p)
850 {
ragge
1.1
851
852         NODE *q;
ragge
1.2
853         int r;
854         char *cp;
855         NODE *ql, *qr;
ragge
1.1
856         CONSZ temp;
ragge
1.23
857
ragge
1.44
858         if (Oflag == 0)
859                 deltemp(p);
ragge
1.1
860
ragge
1.67
861         if (p->n_op == UMUL) {
ragge
1.13
862                 q = p->n_left;
863                 if (q->n_op == REG) {
864                         temp = q->n_lval;
865                         r = q->n_rval;
866                         cp = q->n_name;
ragge
1.1
867                         goto ormake;
ragge
1.12
868                 }
ragge
1.1
869
ragge
1.13
870                 if (q->n_op != PLUS && q->n_op != MINUS)
ragge
1.12
871                         return;
ragge
1.13
872                 ql = q->n_left;
873                 qr = q->n_right;
ragge
1.1
874
875 #ifdef R2REGS
876
877                 /* look for doubly indexed expressions */
878
ragge
1.13
879                 ifq->n_op == PLUS) {
ragge
1.7
880                         int i;
ragge
1.1
881                         if( (r=base(ql))>=0 && (i=offset(qrtlen(p)))>=0) {
882                                 makeor2(pqlri);
883                                 return;
ragge
1.12
884                         } else if((r=base(qr))>=0 && (i=offset(qltlen(p)))>=0) {
ragge
1.1
885                                 makeor2(pqrri);
886                                 return;
887                         }
ragge
1.12
888                 }
ragge
1.1
889
890
891 #endif
892
ragge
1.13
893                 if( (q->n_op==PLUS || q->n_op==MINUS) && qr->n_op == ICON &&
894                                 ql->n_op==REG && szty(qr->n_type)==1) {
895                         temp = qr->n_lval;
896                         ifq->n_op == MINUS ) temp = -temp;
897                         r = ql->n_rval;
898                         temp += ql->n_lval;
899                         cp = qr->n_name;
900                         if( *cp && ( q->n_op == MINUS || *ql->n_name ) ) return;
901                         if( !*cp ) cp = ql->n_name;
ragge
1.1
902
903                         ormake:
ragge
1.13
904                         ifnotoffp->n_typertempcp ) ) return;
905                         p->n_op = OREG;
906                         p->n_rval = r;
907                         p->n_lval = temp;
908                         p->n_name = cp;
ragge
1.1
909                         tfree(q);
910                         return;
911                 }
912         }
ragge
1.12
913 }
ragge
1.1
914
ragge
1.2
915 void
ragge
1.1
916 canon(pNODE *p; {
917         /* put p in canonical form */
918
919 #ifndef FIELDOPS
ragge
1.48
920         fwalk(pffld0);      /* look for field operators */
ragge
1.1
921 # endif
ragge
1.48
922         walkf(psetleft);      /* ptrs at left node for arithmetic */
923         walkf(poreg2);        /* look for and create OREG nodes */
ragge
1.1
924 #ifdef MYCANON
ragge
1.48
925         MYCANON(p);             /* your own canonicalization routine(s) */
ragge
1.1
926 #endif
ragge
1.69
927 #if 0
ragge
1.48
928         walkf(psucomp);       /* do the Sethi-Ullman computation */
ragge
1.69
929 #endif
ragge
1.1
930
ragge
1.2
931 }
ragge
1.1
932
ragge
1.37
933 static SIMPLEQ_HEAD(, interpassipole = SIMPLEQ_HEAD_INITIALIZER(ipole);
934
935 void
936 saveip(struct interpass *ip)
937 {
ragge
1.40
938         struct interpass *prol;
939
ragge
1.37
940         SIMPLEQ_INSERT_TAIL(&ipoleipsqelem);
941
942         if (ip->type != IP_EPILOG)
943                 return;
944         saving = -1;
945
ragge
1.40
946         cvtemps(ip);    /* Convert TEMPs to OREGs */
947         deljumps();     /* Delete redundant jumps and dead code */