Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050917075840

Diff

Diff from 1.150 to:

Annotations

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

Annotated File View

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