Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040605082242

Diff

Diff from 1.103 to:

Annotations

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

Annotated File View

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