Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050521145433

Diff

Diff from 1.128 to:

Annotations

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

Annotated File View

ragge
1.128
1 /*      $Id: reader.c,v 1.128 2005/05/21 14:54:33 ragge Exp $   */
ragge
1.72
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
ragge
1.31
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
ragge
1.1
62
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.46
144 /* look for delayable ++ and -- operators */
145 void
146 delay(NODE *p)
147 {
ragge
1.125
148         struct interpass *ip;
149         NODE *q;
ragge
1.128
150
ragge
1.46
151         int ty = optype(p->n_op);
152
153         switch (p->n_op) {
ragge
1.68
154         case UCALL:
ragge
1.46
155         case STCALL:
ragge
1.68
156         case USTCALL:
ragge
1.46
157         case FORTCALL:
ragge
1.68
158         case UFORTCALL:
ragge
1.46
159         case CBRANCH:
ragge
1.125
160                 /* for the moment, don't delay past a conditional context, or
ragge
1.46
161                  * inside of a call */
162                 return;
163
ragge
1.67
164         case UMUL:
ragge
1.46
165                 /* if *p++, do not rewrite */
166                 ifautoincrp ) ) return;
167                 break;
168
169         case INCR:
170         case DECR:
ragge
1.83
171                 break;
ragge
1.46
172                 ifdeltestp ) ){
ragge
1.125
173                         ip = ipnode(tcopy(p));
174                         DLIST_INSERT_BEFORE(&delayqipqelem);
175                         q = p->n_left;
176                         nfree(p->n_right); /* zap constant */
177                         *p = *q;
178                         nfree(q);
179                         return;
ragge
1.83
180                 }
ragge
1.46
181
ragge
1.83
182         }
ragge
1.46
183
184         if (ty == BITYPE)
185                 delay(p->n_right);
186         if (ty != LTYPE)
187                 delay(p->n_left);
ragge
1.2
188 }
ragge
1.1
189
ragge
1.89
190 /*
191  * Check if a node has side effects.
192  */
193 static int
194 isuseless(NODE *n)
195 {
196         switch (n->n_op) {
197         case FUNARG:
198         case UCALL:
199         case UFORTCALL:
200         case FORCE:
201         case INIT:
202         case ASSIGN:
203         case INCR:
204         case DECR:
205         case CALL:
206         case FORTCALL:
207         case CBRANCH:
208         case RETURN:
209         case GOTO:
210         case STCALL:
211         case USTCALL:
212         case STASG:
213         case STARG:
214                 return 0;
215         default:
216                 return 1;
217         }
218 }
219
220 static NODE *
221 deluseless(NODE *p)
222 {
223         struct interpass *ip;
224         NODE *l, *r;
225
226         if (optype(p->n_op) == LTYPE) {
227                 nfree(p);
228                 return NULL;
229         }
230         if (isuseless(p) == 0)
231                 return p;
232
233         if (optype(p->n_op) == UTYPE) {
234                 l = p->n_left;
235                 nfree(p);
236                 return deluseless(l);
237         }
238
239         /* Be sure that both leaves may be valid */
240         l = deluseless(p->n_left);
241         r = deluseless(p->n_right);
242         nfree(p);
243         if (l && r) {
244                 /* Put left on queue first */
245                 ip = tmpalloc(sizeof(*ip));
246                 ip->type = IP_NODE;
247                 ip->lineno = 0/* XXX */
248                 ip->ip_node = l;
249                 pass2_compile(ip);
250                 return r;
251         } else if (l)
252                 return l;
253         else if (r)
254                 return r;
255         return NULL;
256 }
257
ragge
1.123
258 /*
259  * Receives interpass structs from pass1.
260  */
261 void
262 pass2_compile(struct interpass *ip)
263 {
264
265         if (ip->type == IP_NODE) {
266                 myreader(ip->ip_node); /* local massage of input */
267                 mkhardops(ip->ip_node);
268                 gencall(ip->ip_nodeNIL);
ragge
1.124
269                 compile2(ip);
270         } else
271                 compile4(ip);
272 }
273
274 void
275 compile2(struct interpass *ip)
276 {
277         DLIST_INIT(&delayqqelem);
278         delay(ip->ip_node);
279         compile3(ip);
280         while (DLIST_NEXT(&delayqqelem) != &delayq) {
281                 ip = DLIST_NEXT(&delayqqelem);
282                 DLIST_REMOVE(ipqelem);
283                 compile3(ip);
284         }
285 }
286
287 void
288 compile3(struct interpass *ip)
289 {
290         NODE *p = ip->ip_node;
291
292         canon(p);
293         if ((p = deluseless(p)) == NULL)
294                 return/* nothing to do */
295 #ifdef PCC_DEBUG
296         walkf(pcktree);
297         if (e2debug) {
298                 fprintf(stderr"Entering pass2\n");
299                 fwalk(pe2print0);
ragge
1.123
300         }
ragge
1.124
301 #endif
302         ip->ip_node = p;
303         compile4(ip);
304 }
305
306 void
307 compile4(struct interpass *ip)
308 {
ragge
1.123
309         if (Oflag
310                 return saveip(ip);
311
ragge
1.125
312         emit(ip);
ragge
1.124
313 }
314
315 void
ragge
1.125
316 emit(struct interpass *ip)
ragge
1.124
317 {
318         NODE *p;
ragge
1.125
319         int osavautooff;
ragge
1.124
320
ragge
1.125
321         switch (ip->type) {
322         case IP_NODE:
323                 p = ip->ip_node;
ragge
1.124
324
ragge
1.125
325                 if (Oflag == 0) {
326                         savautooff = p2autooff;
327                         do {
328                                 geninsn(pFOREFF);
329                         } while (sucomp(p) < 0);
330                         p2autooff = savautooff;
ragge
1.124
331
ragge
1.125
332                         genregs(p); /* allocate registers for instructions */
333                         mygenregs(p);
334                 }
ragge
1.124
335
336                 switch (p->n_op) {
337                 case CBRANCH:
338                         /* Only emit branch insn if RESCC */
339                         if (table[TBLIDX(p->n_left->n_su)].rewrite & RESCC) {
340                                 o = p->n_left->n_op;
341                                 gencode(pFORCC);
342                                 cbgen(op->n_right->n_lval);
343                         } else
344                                 gencode(pFORCC);
345                         break;
346                 case FORCE:
347                         gencode(p->n_leftINTAREG|INTBREG);
348                         break;
349                 default:
350                         if (p->n_op != REG || p->n_type != VOID/* XXX */
351                                 gencode(pFOREFF); /* Emit instructions */
352                 }
353
ragge
1.125
354                 tfree(p);
355                 break;
ragge
1.124
356         case IP_PROLOG:
357                 prologue((struct interpass_prolog *)ip);
358                 break;
359         case IP_EPILOG:
360                 eoftn((struct interpass_prolog *)ip);
361                 tmpsave = NULL/* Always forget old nodes */
362                 p2maxautooff = p2autooff = AUTOINIT;
363                 break;
364         case IP_STKOFF:
ragge
1.125
365                 if (Oflag == 0) {
366                         p2autooff = ip->ip_off;
367                         if (p2autooff > p2maxautooff)
368                                 p2maxautooff = p2autooff;
369                 }
ragge
1.124
370                 break;
371         case IP_DEFLAB:
372                 deflab(ip->ip_lbl);
373                 break;
374         case IP_ASM:
375                 printf("\t%s\n"ip->ip_asm);
376                 break;
ragge
1.127
377         case IPSTK:
378                 break;
ragge
1.124
379         default:
380                 cerror("compile4 %d"ip->type);
381         }
ragge
1.123
382 }
ragge
1.124
383
ragge
1.30
384 #ifdef PCC_DEBUG
ragge
1.1
385 char *cnames[] = {
386         "SANY",
387         "SAREG",
388         "STAREG",
389         "SBREG",
390         "STBREG",
391         "SCC",
392         "SNAME",
393         "SCON",
394         "SFLD",
395         "SOREG",
396         "STARNM",
397         "STARREG",
398         "INTEMP",
399         "FORARG",
400         "SWADD",
401         0,
ragge
1.72
402 };
ragge
1.1
403
ragge
1.2
404 /*
405  * print a nice-looking description of cookie
406  */
ragge
1.70
407 char *
ragge
1.2
408 prcook(int cookie)
409 {
ragge
1.70
410         static char buf[50];
ragge
1.1
411         int iflag;
412
ragge
1.70
413         if (cookie & SPECIAL) {
414                 switch (cookie) {
415                 case SZERO:
416                         return "SZERO";
417                 case SONE:
418                         return "SONE";
419                 case SMONE:
420                         return "SMONE";
421                 default:
422                         sprintf(buf"SPECIAL+%d"cookie & ~SPECIAL);
423                         return buf;
ragge
1.1
424                 }
ragge
1.70
425         }
ragge
1.1
426
427         flag = 0;
ragge
1.70
428         buf[0] = 0;
429         for (i = 0cnames[i]; ++i) {
430                 if (cookie & (1<<i)) {
431                         if (flag)
432                                 strcat(buf"|");
ragge
1.1
433                         ++flag;
ragge
1.70
434                         strcat(bufcnames[i]);
ragge
1.1
435                 }
ragge
1.70
436         }
437         return buf;
438 }
ragge
1.1
439
ragge
1.30
440 #endif
ragge
1.1
441
442 int odebug = 0;
443
ragge
1.2
444 void
ragge
1.69
445 geninsn(NODE *pint cookie)
446 {
ragge
1.71
447         NODE *p1, *p2;
ragge
1.69
448         int orv;
449
450 #ifdef PCC_DEBUG
451         if (odebug) {
ragge
1.70
452                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
453                 fwalk(pe2print0);
454         }
455 #endif
456
457 again:  switch (o = p->n_op) {
ragge
1.71
458         case EQ:
459         case NE:
460         case LE:
461         case LT:
462         case GE:
463         case GT:
464         case ULE:
465         case ULT:
466         case UGE:
467         case UGT:
468                 if ((rv = relops(p)) < 0) {
469                         if (setbin(p))
470                                 goto again;
471                         goto failed;
472                 }
473                 goto sw;
474
ragge
1.69
475         case PLUS:
476         case MINUS:
477         case MUL:
478         case DIV:
479         case MOD:
480         case AND:
481         case OR:
482         case ER:
483         case LS:
484         case RS:
485                 if ((rv = findops(pcookie)) < 0) {
486                         if (setbin(p))
487                                 goto again;
488                         goto failed;
489                 }
ragge
1.71
490                 goto sw;
ragge
1.77
491
492         case INCR:
493         case DECR:
494                 if ((rv = findops(pcookie)) < 0) {
495                         if (setbin(p))
496                                 goto again;
ragge
1.96
497                 } else {
498                         /* Do tree rewriting to ensure correct incr */
499                         if ((rv & LMASK) != LREG)
500                                 goto sw;
501                 }
ragge
1.77
502                 /*
503                  * Rewrite x++ to (x = x + 1) -1;
504                  */
505                 p1 = p->n_left;
506                 p->n_op = o == INCR ? MINUS : PLUS;
507                 /* Assign node */
508                 p2 = talloc();
509                 p2->n_type = p->n_type;
510                 p2->n_name = "";
511                 p2->n_op = ASSIGN;
512                 p->n_left = p2;
513                 p->n_left->n_left = p1;
514                 /* incr/decr node */
515                 p2 = talloc();
516                 p2->n_type = p->n_type;
517                 p2->n_name = "";
518                 p2->n_op = o == INCR ? PLUS : MINUS;
519                 p->n_left->n_right = p2;
520                 /* const one node */
521                 p->n_left->n_right->n_right = tcopy(p->n_right);
522                 /* input tree */
523                 p1 = tcopy(p1);
524                 /* idstrip(p1); */
525                 p->n_left->n_right->n_left = p1;
ragge
1.108
526                 canon(p); /* if fields involved */
ragge
1.77
527                 goto again;
ragge
1.71
528
ragge
1.69
529         case ASSIGN:
ragge
1.71
530                 if ((rv = findasg(pcookie)) < 0) {
ragge
1.69
531                         if (setasg(pcookie))
532                                 goto again;
533                         goto failed;
534                 }
535                 /*
536                  * Do subnodes conversions (if needed).
537                  */
ragge
1.71
538 sw:             switch (rv & LMASK) {
ragge
1.69
539                 case LREG:
540                         geninsn(p->n_leftINTAREG|INTBREG);
541                         break;
542                 case LOREG:
ragge
1.102
543                         if (p->n_left->n_op == FLD) {
544                                 offstar(p->n_left->n_left->n_left);
545                                 p->n_left->n_left->n_su = -1;
546                         } else
547                                 offstar(p->n_left->n_left);
ragge
1.69
548                         p->n_left->n_su = -1;
549                         break;
550                 case LTEMP:
551                         geninsn(p->n_leftINTEMP);
552                         break;
553                 }
554
555                 switch (rv & RMASK) {
556                 case RREG:
557                         geninsn(p->n_rightINTAREG|INTBREG);
558                         break;
559                 case ROREG:
560                         offstar(p->n_right->n_left);
561                         p->n_right->n_su = -1;
562                         break;
563                 case RTEMP:
564                         geninsn(p->n_rightINTEMP);
565                         break;
566                 }
567                 p->n_su = rv;
568                 break;
569
570         case REG:
571                 if (istnode(p))
ragge
1.71
572                         comperr("geninsn REG");
ragge
1.69
573                 /* FALLTHROUGH */
ragge
1.72
574         case NAME:
ragge
1.71
575         case ICON:
ragge
1.69
576         case OREG:
ragge
1.83
577 #if 0
ragge
1.69
578                 if ((cookie & (INTAREG|INTBREG)) == 0)
ragge
1.71
579                         comperr("geninsn OREG, node %p"p);
ragge
1.83
580 #endif
ragge
1.69
581                 if ((rv = findleaf(pcookie)) < 0) {
582                         if (setasg(pcookie))
583                                 goto again;
584                         goto failed;
585                 }
586                 p->n_su = rv;
587                 break;
588
ragge
1.82
589         case UMUL:
590                 /*
591                  * If we end up here with an UMUL, try to fold it into
592                  * an OREG anyway.
593                  */
ragge
1.86
594                 if (p->n_type == STRTY) {
595                         /* XXX - what to do here? */
596                         geninsn(p->n_leftcookie);
597                         p->n_su = -1;
598                         break;
599                 }
600 #if 0
ragge
1.82
601                 if ((cookie & INTAREG) == 0)
602                         comperr("bad umul!");
ragge
1.86
603 #endif
ragge
1.84
604                 if (offstar(p->n_left)) {
605                         p->n_op = OREG;
606                         if ((rv = findleaf(pcookie)) < 0)
607                                 comperr("bad findleaf"); /* XXX */
608                         p->n_op = UMUL;
609                         p->n_su = rv | LOREG;
610                         break;
611                 }
ragge
1.109
612                 /* FALLTHROUGH */
ragge
1.82
613
ragge
1.86
614         case COMPL:
ragge
1.85
615         case UMINUS:
ragge
1.71
616         case PCONV:
617         case SCONV:
618         case INIT:
ragge
1.70
619         case GOTO:
620         case FUNARG:
ragge
1.72
621         case UCALL:
ragge
1.103
622         case USTCALL:
ragge
1.69
623                 if ((rv = finduni(pcookie)) < 0) {
624                         if (setuni(pcookie))
625                                 goto again;
626                         goto failed;
627                 }
628                 switch (rv & LMASK) {
629                 case LREG:
ragge
1.109
630                         cookie = INTAREG|INTBREG;
631                         if (rv & LBREG/* XXX - make prettier */
632                                 cookie = INTBREG;
633                         geninsn(p->n_leftcookie);
ragge
1.69
634                         break;
ragge
1.70
635                 case LOREG:
636                         offstar(p->n_left->n_left);
637                         p->n_left->n_su = -1;
638                         break;
639                 case LTEMP:
640                         geninsn(p->n_leftINTEMP);
641                         break;
ragge
1.69
642                 }
643                 p->n_su = rv;
644                 break;
645
ragge
1.71
646         case CBRANCH:
647                 p1 = p->n_left;
648                 p2 = p->n_right;
649                 p1->n_label = p2->n_lval;
650                 o = p1->n_op;
651                 geninsn(p1FORCC);
652                 p->n_su = -1/* su calculations traverse left */
653                 break;
654
655         case FORCE:
656                 geninsn(p->n_leftINTAREG|INTBREG);
657                 p->n_su = -1/* su calculations traverse left */
658                 break;
659
ragge
1.69
660         default:
ragge
1.72
661                 comperr("geninsn: bad op %d, node %p"op);
ragge
1.69
662         }
663         return;
664
665 failed:
ragge
1.84
666         comperr("Cannot generate code, node %p op %s"popst[p->n_op]);
667
ragge
1.69
668 }
669
ragge
1.72
670 /*
671  * Store a given subtree in a temporary location.
672  * Return an OREG node where it is located.
673  */
674 NODE *
675 store(NODE *p)
ragge
1.2
676 {
ragge
1.72
677         NODE *q, *r, *s;
ragge
1.49
678
ragge
1.72
679         q = talloc();
680         r = talloc();
681         s = talloc();
682         q->n_op = OREG;
683         q->n_type = p->n_type;
684         q->n_name = "";
685         q->n_rval = FPREG;
686         q->n_lval = BITOOR(freetemp(szty(p->n_type)));
687         *r = *q;
688         s->n_op = ASSIGN;
689         s->n_type = p->n_type;
690         s->n_name = "";
691         s->n_left = q;
692         s->n_right = p;
ragge
1.125
693         if (Oflag) {
694                 extern struct interpass *storesave;
695                 storesave = ipnode(s);
696         } else
697                 emit(ipnode(s));
ragge
1.72
698         return r;
ragge
1.8
699 }
ragge
1.1
700
ragge
1.69
701 /*
ragge
1.75
702  * Rewrite node after instruction emit.
703  */
704 static void
705 rewrite(NODE *pint rewrite)
706 {
ragge
1.79
707         NODE *l, *r;
708         int o;
709
ragge
1.75
710         if (p->n_su == -1)
711                 comperr("rewrite");
712
ragge
1.80
713         l = getlr(p'L');
714         r = getlr(p'R');
ragge
1.79
715         o = p->n_op;
ragge
1.75
716         p->n_op = REG;
ragge
1.76
717         p->n_lval = 0;
ragge
1.95
718         p->n_name = "";
ragge
1.79
719         if (rewrite & RLEFT) {
720 #ifdef PCC_DEBUG
721                 if (l->n_op != REG)
722                         comperr("rewrite left");
723 #endif
724                 p->n_rval = l->n_rval;
725         } else if (rewrite & RRIGHT) {
726 #ifdef PCC_DEBUG
727                 if (r->n_op != REG)
728                         comperr("rewrite right");
729 #endif
730                 p->n_rval = r->n_rval;
731         } else if (rewrite & RESC1)
732                 p->n_rval = p->n_rall;
733         else if (rewrite & RESC2)
734                 p->n_rval = p->n_rall + szty(p->n_type);
ragge
1.75
735         else if (rewrite & RESC3)
ragge
1.79
736                 p->n_rval = p->n_rall + 2*szty(p->n_type);
ragge
1.99
737         else if (p->n_su == DORIGHT)
738                 p->n_rval = l->n_rval/* XXX special */
ragge
1.79
739         if (optype(o) != LTYPE)
740                 tfree(l);
741         if (optype(o) == BITYPE)
742                 tfree(r);
ragge
1.75
743 }
744
ragge
1.69
745 void
ragge
1.72
746 gencode(NODE *pint cookie)
ragge
1.69
747 {
748         struct optab *q = &table[TBLIDX(p->n_su)];
749
750         if (p->n_su == -1/* For OREGs and similar */
ragge
1.72
751                 return gencode(p->n_leftcookie);
ragge
1.69
752
753         if (p->n_su & DORIGHT) {
ragge
1.72
754                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
755                 if ((p->n_su & RMASK) == ROREG)
756                         canon(p);
757         }
758         if (p->n_su & LMASK) {
ragge
1.72
759                 gencode(p->n_leftINTAREG|INTBREG);
ragge
1.69
760                 if ((p->n_su & LMASK) == LOREG)
761                         canon(p);
762         }
763         if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
ragge
1.72
764                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
765                 if ((p->n_su & RMASK) == ROREG)
766                         canon(p);
767         }
ragge
1.72
768         expand(pcookieq->cstring);
ragge
1.75
769         rewrite(pq->rewrite);
ragge
1.2
770 }
ragge
1.1
771
772 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
773
ragge
1.2
774 void
775 rcount()
776 /* count recursions */
ragge
1.1
777         if( ++nrecur > NRECUR ){
778                 cerror"expression causes compiler loop: try simplifying" );
779         }
ragge
1.2
780 }
ragge
1.1
781
ragge
1.30
782 #ifdef PCC_DEBUG
ragge
1.87
783 #undef  PRTABLE
ragge
1.2
784 int
ragge
1.8
785 e2print(NODE *pint downint *aint *b)
ragge
1.2
786 {
ragge
1.85
787 #ifdef PRTABLE
788         extern int tablesize;
789 #endif
ragge
1.1
790
791         *a = *b = down+1;
792         whiledown >= 2 ){
ragge
1.71
793                 fprintf(stderr"\t");
ragge
1.1
794                 down -= 2;
795                 }
ragge
1.71
796         ifdown-- ) fprintf(stderr"    " );
ragge
1.1
797
798
ragge
1.71
799         fprintf(stderr"%p) %s"popst[p->n_op] );
ragge
1.13
800         switchp->n_op ) { /* special cases */
ragge
1.1
801
802         case REG:
ragge
1.71
803                 fprintf(stderr" %s"rnames[p->n_rval] );
ragge
1.1
804                 break;
805
ragge
1.121
806         case TEMP:
807                 fprintf(stderr" " CONFMTp->n_lval);
808                 break;
809
ragge
1.1
810         case ICON:
811         case NAME:
812         case OREG:
ragge
1.71
813                 fprintf(stderr" " );
814                 adrput(stderrp );
ragge
1.1
815                 break;
816
817         case STCALL:
ragge
1.68
818         case USTCALL:
ragge
1.1
819         case STARG:
820         case STASG:
ragge
1.71
821                 fprintf(stderr" size=%d"p->n_stsize );
822                 fprintf(stderr" align=%d"p->n_stalign );
ragge
1.1
823                 break;
824                 }
825
ragge
1.71
826         fprintf(stderr", " );
827         tprint(stderrp->n_typep->n_qual);
828         fprintf(stderr", " );
829         ifp->n_rall == NOPREF ) fprintf(stderr"NOPREF" );
ragge
1.1
830         else {
ragge
1.71
831                 ifp->n_rall & MUSTDO ) fprintf(stderr"MUSTDO " );
832                 else fprintf(stderr"PREF " );
ragge
1.122
833                 if ((p->n_rall&~MUSTDO) > 8/* XXX */
834                 fprintf(stderr"(%d)", (p->n_rall&~MUSTDO));
835                 else fprintf(stderr"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
836                 }
ragge
1.85
837         fprintf(stderr", SU= %d(%s,%s,%s,%s)\n",
838             TBLIDX(p->n_su), 
839 #ifdef PRTABLE
840             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
841             table[TBLIDX(p->n_su)].cstring : "",
842 #else
843             "",
844 #endif
845             ltyp[LMASK&p->n_su],
ragge
1.70
846             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
847         return 0;
848 }
ragge
1.30
849 #endif
ragge
1.1
850
851 #ifndef FIELDOPS
ragge
1.7
852 /*
853  * do this if there is no special hardware support for fields
854  */
855 static int
856 ffld(NODE *pint downint *down1int *down2 )
857 {
858         /*
859          * look for fields that are not in an lvalue context,
860          * and rewrite them...
861          */
862         NODE *shp;
863         int sovty;
ragge
1.1
864
ragge
1.13
865         *down1 =  asgopp->n_op );
ragge
1.1
866         *down2 = 0;
867
ragge
1.13
868         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
869
ragge
1.7
870                 if( !rewfld(p) ) return 0;
ragge
1.1
871
ragge
1.48
872                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
873                 v = p->n_rval;
ragge
1.1
874                 s = UPKFSZ(v);
875 # ifdef RTOLBYTES
876                 o = UPKFOFF(v);  /* amount to shift */
877 # else
ragge
1.13
878                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
879 #endif
880
881                 /* make & mask part */
882
ragge
1.13
883                 p->n_left->n_type = ty;
ragge
1.1
884
ragge
1.13
885                 p->n_op = AND;
886                 p->n_right = talloc();
887                 p->n_right->n_op = ICON;
888                 p->n_right->n_rall = NOPREF;
889                 p->n_right->n_type = ty;
890                 p->n_right->n_lval = 1;
891                 p->n_right->n_rval = 0;
892                 p->n_right->n_name = "";
893                 p->n_right->n_lval <<= s;
894                 p->n_right->n_lval--;
ragge
1.1
895
896                 /* now, if a shift is needed, do it */
897
898                 ifo != 0 ){
899                         shp = talloc();
ragge
1.13
900                         shp->n_op = RS;
901                         shp->n_rall = NOPREF;
902                         shp->n_type = ty;
903                         shp->n_left = p->n_left;
904                         shp->n_right = talloc();
905                         shp->n_right->n_op = ICON;
906                         shp->n_right->n_rall = NOPREF;
907                         shp->n_right->n_type = ty;
908                         shp->n_right->n_rval = 0;
909                         shp->n_right->n_lval = o;  /* amount to shift */
910                         shp->n_right->n_name = "";
911                         p->n_left = shp;
ragge
1.1
912                         /* whew! */
913                 }
914         }
ragge
1.7
915         return 0;
916 }
ragge
1.1
917 #endif
918
ragge
1.23
919 /*
920  * change left TEMPs into OREGs
ragge
1.40
921  */
922 void
923 deltemp(NODE *p)
924 {
ragge
1.116
925         struct tmpsave *w;
ragge
1.90
926         NODE *l, *r;
ragge
1.40
927
ragge
1.116
928         if (p->n_op == TEMP) {
929                 /* Check if already existing */
930                 for (w = tmpsaveww = w->next)
931                         if (w->tempno == p->n_lval)
932                                 break;
933                 if (w == NULL) {
934                         /* new on stack */
935                         w = tmpalloc(sizeof(struct tmpsave));
936                         w->tempno = p->n_lval;
937                         w->tempaddr = BITOOR(freetemp(szty(p->n_type)));
938                         w->next = tmpsave;
939                         tmpsave = w;
940                 }
941                 p->n_op = OREG;
942                 p->n_rval = FPREG;
943                 p->n_lval = w->tempaddr;
944         } else if (p->n_op == ADDROF) {
ragge
1.90
945                 /* TEMPs are already converted to OREGs */
946                 if ((l = p->n_left)->n_op != OREG)
947                         comperr("bad U&");
948                 p->n_op = PLUS;
949                 l->n_op = REG;
950                 l->n_type = INCREF(l->n_type);
951                 r = p->n_right = talloc();
952                 r->n_op = ICON;
953                 r->n_name = "";
954                 r->n_lval = l->n_lval;
955                 r->n_type = INT;
956         }
ragge
1.40
957 }
958
959 /*
ragge
1.48
960  * for pointer/integer arithmetic, set pointer at left node
961  */
962 static void
963 setleft(NODE *p)          
964 {        
965         NODE *q;
966
967         /* only additions for now */
968         if (p->n_op != PLUS)
969                 return;
970         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {