Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050306154033

Diff

Diff from 1.122 to:

Annotations

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

Annotated File View

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