Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050522135501

Diff

Diff from 1.130 to:

Annotations

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

Annotated File View

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