Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050629193316

Diff

Diff from 1.142 to:

Annotations

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

Annotated File View

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