Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050111142708

Diff

Diff from 1.111 to:

Annotations

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

Annotated File View

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