Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20041230103516

Diff

Diff from 1.108 to:

Annotations

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

Annotated File View

ragge
1.108
1 /*      $Id: reader.c,v 1.108 2004/12/30 10:35:17 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.82
638
ragge
1.86
639         case COMPL:
ragge
1.85
640         case UMINUS:
ragge
1.71
641         case PCONV:
642         case SCONV:
643         case INIT:
ragge
1.70
644         case GOTO:
645         case FUNARG:
ragge
1.72
646         case UCALL:
ragge
1.103
647         case USTCALL:
ragge
1.69
648                 if ((rv = finduni(pcookie)) < 0) {
649                         if (setuni(pcookie))
650                                 goto again;
651                         goto failed;
652                 }
653                 switch (rv & LMASK) {
654                 case LREG:
655                         geninsn(p->n_leftINTAREG|INTBREG);
656                         break;
ragge
1.70
657                 case LOREG:
658                         offstar(p->n_left->n_left);
659                         p->n_left->n_su = -1;
660                         break;
661                 case LTEMP:
662                         geninsn(p->n_leftINTEMP);
663                         break;
ragge
1.69
664                 }
665                 p->n_su = rv;
666                 break;
667
ragge
1.71
668         case CBRANCH:
669                 p1 = p->n_left;
670                 p2 = p->n_right;
671                 p1->n_label = p2->n_lval;
672                 o = p1->n_op;
673                 geninsn(p1FORCC);
674                 p->n_su = -1/* su calculations traverse left */
675                 break;
676
677         case FORCE:
678                 geninsn(p->n_leftINTAREG|INTBREG);
679                 p->n_su = -1/* su calculations traverse left */
680                 break;
681
ragge
1.69
682         default:
ragge
1.72
683                 comperr("geninsn: bad op %d, node %p"op);
ragge
1.69
684         }
685         return;
686
687 failed:
ragge
1.84
688         comperr("Cannot generate code, node %p op %s"popst[p->n_op]);
689
ragge
1.69
690 }
691
ragge
1.72
692 /*
693  * Store a given subtree in a temporary location.
694  * Return an OREG node where it is located.
695  */
696 NODE *
697 store(NODE *p)
ragge
1.2
698 {
ragge
1.72
699         NODE *q, *r, *s;
ragge
1.49
700
ragge
1.72
701         q = talloc();
702         r = talloc();
703         s = talloc();
704         q->n_op = OREG;
705         q->n_type = p->n_type;
706         q->n_name = "";
707         q->n_rval = FPREG;
708         q->n_lval = BITOOR(freetemp(szty(p->n_type)));
709         *r = *q;
710         s->n_op = ASSIGN;
711         s->n_type = p->n_type;
712         s->n_name = "";
713         s->n_left = q;
714         s->n_right = p;
715         codgen(sFOREFF);
ragge
1.80
716         tfree(s);
ragge
1.72
717         return r;
ragge
1.8
718 }
ragge
1.1
719
ragge
1.69
720 /*
ragge
1.75
721  * Rewrite node after instruction emit.
722  */
723 static void
724 rewrite(NODE *pint rewrite)
725 {
ragge
1.79
726         NODE *l, *r;
727         int o;
728
ragge
1.75
729         if (p->n_su == -1)
730                 comperr("rewrite");
731
ragge
1.80
732         l = getlr(p'L');
733         r = getlr(p'R');
ragge
1.79
734         o = p->n_op;
ragge
1.75
735         p->n_op = REG;
ragge
1.76
736         p->n_lval = 0;
ragge
1.95
737         p->n_name = "";
ragge
1.79
738         if (rewrite & RLEFT) {
739 #ifdef PCC_DEBUG
740                 if (l->n_op != REG)
741                         comperr("rewrite left");
742 #endif
743                 p->n_rval = l->n_rval;
744         } else if (rewrite & RRIGHT) {
745 #ifdef PCC_DEBUG
746                 if (r->n_op != REG)
747                         comperr("rewrite right");
748 #endif
749                 p->n_rval = r->n_rval;
750         } else if (rewrite & RESC1)
751                 p->n_rval = p->n_rall;
752         else if (rewrite & RESC2)
753                 p->n_rval = p->n_rall + szty(p->n_type);
ragge
1.75
754         else if (rewrite & RESC3)
ragge
1.79
755                 p->n_rval = p->n_rall + 2*szty(p->n_type);
ragge
1.99
756         else if (p->n_su == DORIGHT)
757                 p->n_rval = l->n_rval/* XXX special */
ragge
1.79
758         if (optype(o) != LTYPE)
759                 tfree(l);
760         if (optype(o) == BITYPE)
761                 tfree(r);
ragge
1.75
762 }
763
ragge
1.69
764 void
ragge
1.72
765 gencode(NODE *pint cookie)
ragge
1.69
766 {
767         struct optab *q = &table[TBLIDX(p->n_su)];
768
769         if (p->n_su == -1/* For OREGs and similar */
ragge
1.72
770                 return gencode(p->n_leftcookie);
ragge
1.69
771
772         if (p->n_su & DORIGHT) {
ragge
1.72
773                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
774                 if ((p->n_su & RMASK) == ROREG)
775                         canon(p);
776         }
777         if (p->n_su & LMASK) {
ragge
1.72
778                 gencode(p->n_leftINTAREG|INTBREG);
ragge
1.69
779                 if ((p->n_su & LMASK) == LOREG)
780                         canon(p);
781         }
782         if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
ragge
1.72
783                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
784                 if ((p->n_su & RMASK) == ROREG)
785                         canon(p);
786         }
ragge
1.72
787         expand(pcookieq->cstring);
ragge
1.75
788         rewrite(pq->rewrite);
ragge
1.2
789 }
ragge
1.1
790
791 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
792
ragge
1.2
793 void
794 rcount()
795 /* count recursions */
ragge
1.1
796         if( ++nrecur > NRECUR ){
797                 cerror"expression causes compiler loop: try simplifying" );
798         }
ragge
1.2
799 }
ragge
1.1
800
ragge
1.30
801 #ifdef PCC_DEBUG
ragge
1.87
802 #undef  PRTABLE
ragge
1.2
803 int
ragge
1.8
804 e2print(NODE *pint downint *aint *b)
ragge
1.2
805 {
ragge
1.85
806 #ifdef PRTABLE
807         extern int tablesize;
808 #endif
ragge
1.1
809
810         *a = *b = down+1;
811         whiledown >= 2 ){
ragge
1.71
812                 fprintf(stderr"\t");
ragge
1.1
813                 down -= 2;
814                 }
ragge
1.71
815         ifdown-- ) fprintf(stderr"    " );
ragge
1.1
816
817
ragge
1.71
818         fprintf(stderr"%p) %s"popst[p->n_op] );
ragge
1.13
819         switchp->n_op ) { /* special cases */
ragge
1.1
820
821         case REG:
ragge
1.71
822                 fprintf(stderr" %s"rnames[p->n_rval] );
ragge
1.1
823                 break;
824
825         case ICON:
826         case NAME:
827         case OREG:
ragge
1.71
828                 fprintf(stderr" " );
829                 adrput(stderrp );
ragge
1.1
830                 break;
831
832         case STCALL:
ragge
1.68
833         case USTCALL:
ragge
1.1
834         case STARG:
835         case STASG:
ragge
1.71
836                 fprintf(stderr" size=%d"p->n_stsize );
837                 fprintf(stderr" align=%d"p->n_stalign );
ragge
1.1
838                 break;
839                 }
840
ragge
1.71
841         fprintf(stderr", " );
842         tprint(stderrp->n_typep->n_qual);
843         fprintf(stderr", " );
844         ifp->n_rall == NOPREF ) fprintf(stderr"NOPREF" );
ragge
1.1
845         else {
ragge
1.71
846                 ifp->n_rall & MUSTDO ) fprintf(stderr"MUSTDO " );
847                 else fprintf(stderr"PREF " );
848                 fprintf(stderr"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
849                 }
ragge
1.85
850         fprintf(stderr", SU= %d(%s,%s,%s,%s)\n",
851             TBLIDX(p->n_su), 
852 #ifdef PRTABLE
853             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
854             table[TBLIDX(p->n_su)].cstring : "",
855 #else
856             "",
857 #endif
858             ltyp[LMASK&p->n_su],
ragge
1.70
859             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
860         return 0;
861 }
ragge
1.30
862 #endif
ragge
1.1
863
864 #ifndef FIELDOPS
ragge
1.7
865 /*
866  * do this if there is no special hardware support for fields
867  */
868 static int
869 ffld(NODE *pint downint *down1int *down2 )
870 {
871         /*
872          * look for fields that are not in an lvalue context,
873          * and rewrite them...
874          */
875         NODE *shp;
876         int sovty;
ragge
1.1
877
ragge
1.13
878         *down1 =  asgopp->n_op );
ragge
1.1
879         *down2 = 0;
880
ragge
1.13
881         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
882
ragge
1.7
883                 if( !rewfld(p) ) return 0;
ragge
1.1
884
ragge
1.48
885                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
886                 v = p->n_rval;
ragge
1.1
887                 s = UPKFSZ(v);
888 # ifdef RTOLBYTES
889                 o = UPKFOFF(v);  /* amount to shift */
890 # else
ragge
1.13
891                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
892 #endif
893
894                 /* make & mask part */
895
ragge
1.13
896                 p->n_left->n_type = ty;
ragge
1.1
897
ragge
1.13
898                 p->n_op = AND;
899                 p->n_right = talloc();
900                 p->n_right->n_op = ICON;
901                 p->n_right->n_rall = NOPREF;
902                 p->n_right->n_type = ty;
903                 p->n_right->n_lval = 1;
904                 p->n_right->n_rval = 0;
905                 p->n_right->n_name = "";
906                 p->n_right->n_lval <<= s;
907                 p->n_right->n_lval--;
ragge
1.1
908
909                 /* now, if a shift is needed, do it */
910
911                 ifo != 0 ){
912                         shp = talloc();
ragge
1.13
913                         shp->n_op = RS;
914                         shp->n_rall = NOPREF;
915                         shp->n_type = ty;
916                         shp->n_left = p->n_left;
917                         shp->n_right = talloc();
918                         shp->n_right->n_op = ICON;
919                         shp->n_right->n_rall = NOPREF;
920                         shp->n_right->n_type = ty;
921                         shp->n_right->n_rval = 0;
922                         shp->n_right->n_lval = o;  /* amount to shift */
923                         shp->n_right->n_name = "";
924                         p->n_left = shp;
ragge
1.1
925                         /* whew! */
926                 }
927         }
ragge
1.7
928         return 0;
929 }
ragge
1.1
930 #endif
931
ragge
1.23
932 /*
933  * change left TEMPs into OREGs
ragge
1.40
934  */
935 void
936 deltemp(NODE *p)
937 {