Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050218164859

Diff

Diff from 1.120 to:

Annotations

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

Annotated File View

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