Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040530101629

Diff

Diff from 1.102 to:

Annotations

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

Annotated File View

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