Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050109142853

Diff

Diff from 1.109 to:

Annotations

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

Annotated File View

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