Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040621081946

Diff

Diff from 1.105 to:

Annotations

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

Annotated File View

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