Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040507164935

Diff

Diff from 1.89 to:

Annotations

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

Annotated File View

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