Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050905170716

Diff

Diff from 1.149 to:

Annotations

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

Annotated File View

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