Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040429202424

Diff

Diff from 1.79 to:

Annotations

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

Annotated File View

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