Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20031215220206

Diff

Diff from 1.72 to:

Annotations

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

Annotated File View

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