Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050611073841

Diff

Diff from 1.131 to:

Annotations

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

Annotated File View

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