Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040428204947

Diff

Diff from 1.77 to:

Annotations

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

Annotated File View

ragge
1.77
1 /*      $Id: reader.c,v 1.77 2004/04/28 20:49:47 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.75
151         tfree(p);
ragge
1.1
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;
ragge
1.77
417
418         case INCR:
419         case DECR:
420                 if ((rv = findops(pcookie)) < 0) {
421                         if (setbin(p))
422                                 goto again;
423                 } else
424                         goto sw;
425
426                 /*
427                  * Rewrite x++ to (x = x + 1) -1;
428                  */
429                 p1 = p->n_left;
430                 p->n_op = o == INCR ? MINUS : PLUS;
431                 /* Assign node */
432                 p2 = talloc();
433                 p2->n_type = p->n_type;
434                 p2->n_name = "";
435                 p2->n_op = ASSIGN;
436                 p->n_left = p2;
437                 p->n_left->n_left = p1;
438                 /* incr/decr node */
439                 p2 = talloc();
440                 p2->n_type = p->n_type;
441                 p2->n_name = "";
442                 p2->n_op = o == INCR ? PLUS : MINUS;
443                 p->n_left->n_right = p2;
444                 /* const one node */
445                 p->n_left->n_right->n_right = tcopy(p->n_right);
446                 /* input tree */
447                 p1 = tcopy(p1);
448                 /* idstrip(p1); */
449                 p->n_left->n_right->n_left = p1;
450                 goto again;
ragge
1.71
451
ragge
1.69
452         case ASSIGN:
ragge
1.71
453                 if ((rv = findasg(pcookie)) < 0) {
ragge
1.69
454                         if (setasg(pcookie))
455                                 goto again;
456                         goto failed;
457                 }
458                 /*
459                  * Do subnodes conversions (if needed).
460                  */
ragge
1.71
461 sw:             switch (rv & LMASK) {
ragge
1.69
462                 case LREG:
463                         geninsn(p->n_leftINTAREG|INTBREG);
464                         break;
465                 case LOREG:
466                         offstar(p->n_left->n_left);
467                         p->n_left->n_su = -1;
468                         break;
469                 case LTEMP:
470                         geninsn(p->n_leftINTEMP);
471                         break;
472                 }
473
474                 switch (rv & RMASK) {
475                 case RREG:
476                         geninsn(p->n_rightINTAREG|INTBREG);
477                         break;
478                 case ROREG:
479                         offstar(p->n_right->n_left);
480                         p->n_right->n_su = -1;
481                         break;
482                 case RTEMP:
483                         geninsn(p->n_rightINTEMP);
484                         break;
485                 }
486                 p->n_su = rv;
487                 break;
488
489         case REG:
490                 if (istnode(p))
ragge
1.71
491                         comperr("geninsn REG");
ragge
1.69
492                 /* FALLTHROUGH */
ragge
1.72
493         case NAME:
ragge
1.71
494         case ICON:
ragge
1.69
495         case OREG:
496                 if ((cookie & (INTAREG|INTBREG)) == 0)
ragge
1.71
497                         comperr("geninsn OREG, node %p"p);
ragge
1.69
498                 if ((rv = findleaf(pcookie)) < 0) {
499                         if (setasg(pcookie))
500                                 goto again;
501                         goto failed;
502                 }
503                 p->n_su = rv;
504                 break;
505
ragge
1.71
506         case PCONV:
507         case SCONV:
ragge
1.69
508         case UMUL:
ragge
1.71
509         case INIT:
ragge
1.70
510         case GOTO:
511         case FUNARG:
ragge
1.72
512         case UCALL:
ragge
1.69
513                 if ((rv = finduni(pcookie)) < 0) {
514                         if (setuni(pcookie))
515                                 goto again;
516                         goto failed;
517                 }
518                 switch (rv & LMASK) {
519                 case LREG:
520                         geninsn(p->n_leftINTAREG|INTBREG);
521                         break;
ragge
1.70
522                 case LOREG:
523                         offstar(p->n_left->n_left);
524                         p->n_left->n_su = -1;
525                         break;
526                 case LTEMP:
527                         geninsn(p->n_leftINTEMP);
528                         break;
ragge
1.69
529                 }
530                 p->n_su = rv;
531                 break;
532
ragge
1.72
533 #if 0
ragge
1.70
534                 if (gencall(pcookie))
535                         goto failed;
536                 if (cookie == FOREFF)
537                         p->n_type = VOID/* XXX */
538                 gotcall = 1;
539                 break;
ragge
1.72
540 #endif
ragge
1.70
541
ragge
1.71
542         case CBRANCH:
543                 p1 = p->n_left;
544                 p2 = p->n_right;
545                 p1->n_label = p2->n_lval;
546                 o = p1->n_op;
547                 geninsn(p1FORCC);
548                 p->n_su = -1/* su calculations traverse left */
549                 break;
550
551         case FORCE:
552                 geninsn(p->n_leftINTAREG|INTBREG);
553                 p->n_su = -1/* su calculations traverse left */
554                 break;
555
ragge
1.69
556         default:
ragge
1.72
557                 comperr("geninsn: bad op %d, node %p"op);
ragge
1.69
558         }
559         return;
560
561 failed:
562 #ifdef PCC_DEBUG
563         fwalk(pe2print0);
564 #endif
565         cerror("Cannot generate code for op %d\n"o);
566 }
567
ragge
1.72
568 /*
569  * Store a given subtree in a temporary location.
570  * Return an OREG node where it is located.
571  */
572 NODE *
573 store(NODE *p)
ragge
1.2
574 {
ragge
1.72
575         NODE *q, *r, *s;
ragge
1.49
576
ragge
1.72
577         q = talloc();
578         r = talloc();
579         s = talloc();
580         q->n_op = OREG;
581         q->n_type = p->n_type;
582         q->n_name = "";
583         q->n_rval = FPREG;
584         q->n_lval = BITOOR(freetemp(szty(p->n_type)));
585         *r = *q;
586         s->n_op = ASSIGN;
587         s->n_type = p->n_type;
588         s->n_name = "";
589         s->n_left = q;
590         s->n_right = p;
591         codgen(sFOREFF);
592         return r;
ragge
1.8
593 }
ragge
1.1
594
ragge
1.69
595 /*
596  * Count the number of registers needed to evaluate a tree.
597  * This is the trivial implementation, for machines with symmetric
598  * registers. Machines with difficult register assignment strategies
599  * will need to define this function themselves.
600  * Return value is the number of registers used so far.
601  */
602 int
603 sucomp(NODE *p
604 {
605         struct optab *q = &table[TBLIDX(p->n_su)];
606         int leftright;
607         int nreg;
608
609         if (p->n_su == -1)
610                 return sucomp(p->n_left);
611
ragge
1.72
612         if (p->n_op == UCALL) {
613                 if (sucomp(p->n_left) < 0)
614                         return -1;
615                 return fregs;
616         }
617
ragge
1.69
618         nreg = (q->needs & NACOUNT) * szty(p->n_type);
619
620         switch (p->n_su & RMASK) {
621         case RREG:
622         case ROREG:
ragge
1.72
623                 if ((right = sucomp(p->n_right)) < 0)
624                         return right;
ragge
1.69
625                 break;
626         case RTEMP:
627                 cerror("sucomp RTEMP");
628         default:
629                 right = 0;
630         }
631         switch (p->n_su & LMASK) {
632         case LREG:
633         case LOREG:
ragge
1.72
634                 if ((left = sucomp(p->n_left)) < 0)
635                         return left;
ragge
1.69
636                 break;
637         case LTEMP:
638                 cerror("sucomp LTEMP");
639         default:
640                 left = 0;
641         }
ragge
1.72
642 //printf("sucomp: node %p right %d left %d\n", p, right, left);
643         if ((p->n_su & RMASK) && (p->n_su & LMASK) &&
644             right + szty(p->n_left->n_type) > fregs &&
645             left + szty(p->n_right->n_type) > fregs) {
646                 /*
647                  * Must store one subtree. Store the tree
648                  * with highest SU, or left.
649                  */
650                 if (right > left)
651                         p->n_right = store(p->n_right);
652                 else
653                         p->n_left = store(p->n_left);
654                 return -1;
655         }
ragge
1.69
656         if (right > left)
657                 p->n_su |= DORIGHT;
ragge
1.72
658         if (left && right && (q->needs & (NASL|NDLEFT)))
659                 p->n_su |= DORIGHT;
ragge
1.69
660         if (right > nreg)
661                 nreg = right;
662         if (left > nreg)
ragge
1.72
663                 nreg = left;
ragge
1.69
664         return nreg;
ragge
1.72
665 }
666
ragge
1.75
667 /*
668  * Rewrite node after instruction emit.
669  * This is not strictly necessary anymore, but prettier if done :-)
670  */
671 static void
672 rewrite(NODE *pint rewrite)
673 {
674         if (p->n_su == -1)
675                 comperr("rewrite");
676
677         if (optype(p->n_op) != LTYPE)
678                 tfree(p->n_left);
679         if (optype(p->n_op) == BITYPE)
680                 tfree(p->n_right);
681         p->n_op = REG;
682         p->n_rval = p->n_rall;
ragge
1.76
683         p->n_lval = 0;
ragge
1.75
684         if (rewrite & RESC2)
685                 p->n_rval += szty(p->n_type);
686         else if (rewrite & RESC3)
687                 p->n_rval += 2*szty(p->n_type);
688 }
689
ragge
1.69
690 void
ragge
1.72
691 gencode(NODE *pint cookie)
ragge
1.69
692 {
693         struct optab *q = &table[TBLIDX(p->n_su)];
694
695         if (p->n_su == -1/* For OREGs and similar */
ragge
1.72
696                 return gencode(p->n_leftcookie);
ragge
1.69
697
698         if (p->n_su & DORIGHT) {
ragge
1.72
699                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
700                 if ((p->n_su & RMASK) == ROREG)
701                         canon(p);
702         }
703         if (p->n_su & LMASK) {
ragge
1.72
704                 gencode(p->n_leftINTAREG|INTBREG);
ragge
1.69
705                 if ((p->n_su & LMASK) == LOREG)
706                         canon(p);
707         }
708         if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
ragge
1.72
709                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
710                 if ((p->n_su & RMASK) == ROREG)
711                         canon(p);
712         }
ragge
1.72
713         expand(pcookieq->cstring);
ragge
1.75
714         rewrite(pq->rewrite);
ragge
1.2
715 }
ragge
1.1
716
717 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
718
ragge
1.2
719 void
720 rcount()
721 /* count recursions */
ragge
1.1
722         if( ++nrecur > NRECUR ){
723                 cerror"expression causes compiler loop: try simplifying" );
724         }
ragge
1.2
725 }
ragge
1.1
726
ragge
1.30
727 #ifdef PCC_DEBUG
ragge
1.2
728 int
ragge
1.8
729 e2print(NODE *pint downint *aint *b)
ragge
1.2
730 {
ragge
1.1
731
732         *a = *b = down+1;
733         whiledown >= 2 ){
ragge
1.71
734                 fprintf(stderr"\t");
ragge
1.1
735                 down -= 2;
736                 }
ragge
1.71
737         ifdown-- ) fprintf(stderr"    " );
ragge
1.1
738
739
ragge
1.71
740         fprintf(stderr"%p) %s"popst[p->n_op] );
ragge
1.13
741         switchp->n_op ) { /* special cases */
ragge
1.1
742
743         case REG:
ragge
1.71
744                 fprintf(stderr" %s"rnames[p->n_rval] );
ragge
1.1
745                 break;
746
ragge
1.23
747         case TEMP:
ragge
1.71
748                 fprintf(stderr," %d", (int)p->n_lval);
ragge
1.23
749                 break;
750
ragge
1.1
751         case ICON:
752         case NAME:
753         case OREG:
ragge
1.71
754                 fprintf(stderr" " );
755                 adrput(stderrp );
ragge
1.1
756                 break;
757
758         case STCALL:
ragge
1.68
759         case USTCALL:
ragge
1.1
760         case STARG:
761         case STASG:
ragge
1.71
762                 fprintf(stderr" size=%d"p->n_stsize );
763                 fprintf(stderr" align=%d"p->n_stalign );
ragge
1.1
764                 break;
765                 }
766
ragge
1.71
767         fprintf(stderr", " );
768         tprint(stderrp->n_typep->n_qual);
769         fprintf(stderr", " );
770         ifp->n_rall == NOPREF ) fprintf(stderr"NOPREF" );
ragge
1.1
771         else {
ragge
1.71
772                 ifp->n_rall & MUSTDO ) fprintf(stderr"MUSTDO " );
773                 else fprintf(stderr"PREF " );
774                 fprintf(stderr"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
775                 }
ragge
1.71
776         fprintf(stderr", SU= %d(%s,%s,%s)\n",
777             TBLIDX(p->n_su), ltyp[LMASK&p->n_su],
ragge
1.70
778             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
779         return 0;
780 }
ragge
1.30
781 #endif
ragge
1.1
782
783 #ifndef FIELDOPS
ragge
1.7
784 /*
785  * do this if there is no special hardware support for fields
786  */
787 static int
788 ffld(NODE *pint downint *down1int *down2 )
789 {
790         /*
791          * look for fields that are not in an lvalue context,
792          * and rewrite them...
793          */
794         NODE *shp;
795         int sovty;
ragge
1.1
796
ragge
1.13
797         *down1 =  asgopp->n_op );
ragge
1.1
798         *down2 = 0;
799
ragge
1.13
800         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
801
ragge
1.7
802                 if( !rewfld(p) ) return 0;
ragge
1.1
803
ragge
1.48
804                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
805                 v = p->n_rval;
ragge
1.1
806                 s = UPKFSZ(v);
807 # ifdef RTOLBYTES
808                 o = UPKFOFF(v);  /* amount to shift */
809 # else
ragge
1.13
810                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
811 #endif
812
813                 /* make & mask part */
814
ragge
1.13
815                 p->n_left->n_type = ty;
ragge
1.1
816
ragge
1.13
817                 p->n_op = AND;
818                 p->n_right = talloc();
819                 p->n_right->n_op = ICON;
820                 p->n_right->n_rall = NOPREF;
821                 p->n_right->n_type = ty;
822                 p->n_right->n_lval = 1;
823                 p->n_right->n_rval = 0;
824                 p->n_right->n_name = "";
825                 p->n_right->n_lval <<= s;
826                 p->n_right->n_lval--;
ragge
1.1
827
828                 /* now, if a shift is needed, do it */
829
830                 ifo != 0 ){
831                         shp = talloc();
ragge
1.13
832                         shp->n_op = RS;
833                         shp->n_rall = NOPREF;
834                         shp->n_type = ty;
835                         shp->n_left = p->n_left;
836                         shp->n_right = talloc();
837                         shp->n_right->n_op = ICON;
838                         shp->n_right->n_rall = NOPREF;
839                         shp->n_right->n_type = ty;
840                         shp->n_right->n_rval = 0;
841                         shp->n_right->n_lval = o;  /* amount to shift */
842                         shp->n_right->n_name = "";
843                         p->n_left = shp;
ragge
1.1
844                         /* whew! */
845                 }
846         }
ragge
1.7
847         return 0;
848 }
ragge
1.1
849 #endif
850
ragge
1.23
851 /*
852  * change left TEMPs into OREGs
ragge
1.40
853  */
854 void
855 deltemp(NODE *p)
856 {
857         struct templst *w = templst;
858
859         if (p->n_op != TEMP)
860                 return;
861         /*
862          * the size of a TEMP is in multiples of the reg size.
863          */
864         p->n_op = OREG;
865         p->n_rval = FPREG;
866         while (w != NULL) {
867                 if (w->tempnr == p->n_lval)
868                         break;
869                 w = w->next;
870         }
871         if (w == NULL) {
872                 w = tmpalloc(sizeof(struct templst));
873                 w->tempnr = p->n_lval;
874                 w->tempoff = BITOOR(freetemp(szty(p->n_type)));
875                 w->next = templst;
876                 templst = w;
877         }
878         p->n_lval = w->tempoff;
879         p->n_name = "";
880 }
881
882 /*
ragge
1.48
883  * for pointer/integer arithmetic, set pointer at left node
884  */
885 static void
886 setleft(NODE *p)          
887 {        
888         NODE *q;
889
890         /* only additions for now */
891         if (p->n_op != PLUS)
892                 return;
893         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
894                 q = p->n_right;
895                 p->n_right = p->n_left;
896                 p->n_left = q;
897         }
898 }
899
900 /*
ragge
1.23
901  * look for situations where we can turn * into OREG
902  */
ragge
1.2
903 void
904 oreg2(NODE *p)
905 {
ragge
1.1
906
907         NODE *q;
ragge
1.2
908         int r;
909         char *cp;
910         NODE *ql, *qr;
ragge
1.1
911         CONSZ temp;
ragge
1.23
912
ragge
1.44
913         if (Oflag == 0)
914                 deltemp(p);
ragge
1.1
915
ragge
1.67
916         if (p->n_op == UMUL) {
ragge
1.13
917                 q = p->n_left;
918                 if (q->n_op == REG) {
919                         temp = q->n_lval;
920                         r = q->n_rval;
921                         cp = q->n_name;
ragge
1.1
922                         goto ormake;
ragge
1.12
923                 }
ragge
1.1
924
ragge
1.13
925                 if (q->n_op != PLUS && q->n_op != MINUS)
ragge
1.12
926                         return;
ragge
1.13
927                 ql = q->n_left;
928                 qr = q->n_right;
ragge
1.1
929
930 #ifdef R2REGS
931
932                 /* look for doubly indexed expressions */
933
ragge
1.13
934                 ifq->n_op == PLUS) {
ragge
1.7
935                         int i;
ragge
1.1
936                         if( (r=base(ql))>=0 && (i=offset(qrtlen(p)))>=0) {
937                                 makeor2(pqlri);
938                                 return;
ragge
1.12
939                         } else if((r=base(qr))>=0 && (i=offset(qltlen(p)))>=0) {
ragge
1.1
940                                 makeor2(pqrri);
941                                 return;
942                         }
ragge
1.12
943                 }
ragge
1.1
944
945
946 #endif
947
ragge
1.13
948                 if( (q->n_op==PLUS || q->n_op==MINUS) && qr->n_op == ICON &&
949                                 ql->n_op==REG && szty(qr->n_type)==1) {
950                         temp = qr->n_lval;
951                         ifq->n_op == MINUS ) temp = -temp;
952                         r = ql->n_rval;
953                         temp += ql->n_lval;
954                         cp = qr->n_name;
955                         if( *cp && ( q->n_op == MINUS || *ql->n_name ) ) return;
956                         if( !*cp ) cp = ql->n_name;
ragge
1.1
957
958                         ormake: