Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040619091427

Diff

Diff from 1.104 to:

Annotations

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

Annotated File View

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