Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20061007091934

Diff

Diff from 1.197 to:

Annotations

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

Annotated File View

ragge
1.197
1 /*      $Id: reader.c,v 1.197 2006/10/07 09:19:34 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 /*
ragge
1.174
64  * Everything is entered via pass2_compile().  Three functions are 
65  * allowed to recurse into pass2_compile(), so be careful:
66  * - deluseless()
ragge
1.123
67  * - myreader()
ragge
1.174
68  * Especially in myreader note that trees may be rewritten twice if
69  * things are not carefully handled.
ragge
1.123
70  */
71
ragge
1.1
72 # include "pass2.h"
73
ragge
1.70
74 #include <string.h>
ragge
1.71
75 #include <stdarg.h>
ragge
1.94
76 #include <stdlib.h>
ragge
1.70
77
ragge
1.1
78 /*      some storage declarations */
79 int nrecur;
80 int lflag;
ragge
1.9
81 int x2debug;
ragge
1.1
82 int udebug = 0;
ragge
1.103
83 int thisline;
ragge
1.72
84 int fregs;
ragge
1.123
85 int p2autooffp2maxautooff;
ragge
1.1
86
ragge
1.72
87 NODE *nodepole;
ragge
1.197
88 FILE *prfil;
ragge
1.23
89
ragge
1.37
90 void saveip(struct interpass *ip);
91 void deljumps(void);
ragge
1.40
92 void deltemp(NODE *p);
ragge
1.97
93 void mkhardops(NODE *p);
ragge
1.37
94 void optdump(struct interpass *ip);
ragge
1.40
95 void cvtemps(struct interpass *epil);
ragge
1.72
96 NODE *store(NODE *);
ragge
1.104
97 void rcount(void);
ragge
1.124
98 void compile2(struct interpass *ip);
99 void compile3(struct interpass *ip);
100 void compile4(struct interpass *ip);
ragge
1.65
101
ragge
1.72
102 static void gencode(NODE *pint cookie);
ragge
1.69
103
ragge
1.150
104 char *ltyp[] = { """LREG""LOREG""LTEMP" };
105 char *rtyp[] = { """RREG""ROREG""RTEMP" };
ragge
1.37
106
ragge
1.121
107 /* used when removing nodes */
108 struct tmpsave {
109         struct tmpsave *next;
110         CONSZ tempaddr;
111         int tempno;
112 } *tmpsave;
113
ragge
1.26
114 #ifdef PCC_DEBUG
115 static void
116 cktree(NODE *p)
117 {
118         if (p->n_op > MAXOP)
119                 cerror("op %d slipped through"p->n_op);
ragge
1.35
120         if (p->n_op == CBRANCH && !logop(p->n_left->n_op))
121                 cerror("not logop branch");
ragge
1.47
122         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
123                 cerror("asgop %d slipped through"p->n_op);
ragge
1.26
124 }
125 #endif
ragge
1.8
126
ragge
1.130
127 /*
ragge
1.89
128  * Check if a node has side effects.
129  */
130 static int
131 isuseless(NODE *n)
132 {
133         switch (n->n_op) {
134         case FUNARG:
135         case UCALL:
136         case UFORTCALL:
137         case FORCE:
138         case INIT:
139         case ASSIGN:
140         case CALL:
141         case FORTCALL:
142         case CBRANCH:
143         case RETURN:
144         case GOTO:
145         case STCALL:
146         case USTCALL:
147         case STASG:
148         case STARG:
149                 return 0;
150         default:
151                 return 1;
152         }
153 }
154
ragge
1.130
155 /*
156  * Delete statements with no meaning (like a+b; or 513.4;)
157  */
ragge
1.89
158 static NODE *
159 deluseless(NODE *p)
160 {
161         struct interpass *ip;
162         NODE *l, *r;
163
164         if (optype(p->n_op) == LTYPE) {
165                 nfree(p);
166                 return NULL;
167         }
168         if (isuseless(p) == 0)
169                 return p;
170
171         if (optype(p->n_op) == UTYPE) {
172                 l = p->n_left;
173                 nfree(p);
174                 return deluseless(l);
175         }
176
177         /* Be sure that both leaves may be valid */
178         l = deluseless(p->n_left);
179         r = deluseless(p->n_right);
180         nfree(p);
181         if (l && r) {
182                 /* Put left on queue first */
183                 ip = tmpalloc(sizeof(*ip));
184                 ip->type = IP_NODE;
185                 ip->lineno = 0/* XXX */
186                 ip->ip_node = l;
187                 pass2_compile(ip);
188                 return r;
189         } else if (l)
190                 return l;
191         else if (r)
192                 return r;
193         return NULL;
194 }
195
ragge
1.172
196 static struct interpass ipole;
ragge
1.174
197 struct interpass_prolog *ipp, *epp;
ragge
1.172
198
199 /*
200  * Receives interpass structs from pass1.
201  */
202 void
203 pass2_compile(struct interpass *ip)
204 {
205         if (ip->type == IP_PROLOG) {
206                 tmpsave = NULL;
ragge
1.174
207                 ipp = (struct interpass_prolog *)ip;
ragge
1.172
208                 DLIST_INIT(&ipoleqelem);
209         }
210         DLIST_INSERT_BEFORE(&ipoleipqelem);
211         if (ip->type != IP_EPILOG)
212                 return;
213
214 #ifdef PCC_DEBUG
215         if (e2debug) {
216                 printf("Entering pass2\n");
217                 printip(&ipole);
218         }
219 #endif
ragge
1.174
220
ragge
1.172
221         epp = (struct interpass_prolog *)DLIST_PREV(&ipoleqelem);
222         p2maxautooff = p2autooff = epp->ipp_autos;
ragge
1.174
223
224         myreader(&ipole); /* local massage of input */
225
ragge
1.172
226         DLIST_FOREACH(ip, &ipoleqelem) {
227                 if (ip->type != IP_NODE)
228                         continue;
229                 if (xtemps == 0)
230                         walkf(ip->ip_nodedeltemp);
231         }
232         DLIST_FOREACH(ip, &ipoleqelem) {
233                 if (ip->type != IP_NODE)
234                         continue;
235                 canon(ip->ip_node);
236                 walkf(ip->ip_nodecktree);
237                 if ((ip->ip_node = deluseless(ip->ip_node)) == NULL)
238                         DLIST_REMOVE(ipqelem);
239         }
240
241         optimize(&ipole);
242         ngenregs(&ipole);
243
244         DLIST_FOREACH(ip, &ipoleqelem)
245                 emit(ip);
246 }
247
ragge
1.124
248 void
ragge
1.125
249 emit(struct interpass *ip)
ragge
1.124
250 {
251         NODE *p;
ragge
1.149
252         int o;
ragge
1.124
253
ragge
1.125
254         switch (ip->type) {
255         case IP_NODE:
256                 p = ip->ip_node;
ragge
1.124
257
ragge
1.149
258                 nodepole = p;
ragge
1.180
259 //printf("bu:\n");
260 //fwalk(p, e2print, 0);
261                 canon(p); /* may convert stuff after genregs */
262 //fwalk(p, e2print, 0);
ragge
1.124
263                 switch (p->n_op) {
264                 case CBRANCH:
265                         /* Only emit branch insn if RESCC */
266                         if (table[TBLIDX(p->n_left->n_su)].rewrite & RESCC) {
267                                 o = p->n_left->n_op;
268                                 gencode(pFORCC);
269                                 cbgen(op->n_right->n_lval);
270                         } else
271                                 gencode(pFORCC);
272                         break;
273                 case FORCE:
ragge
1.151
274                         gencode(p->n_leftINREGS);
ragge
1.124
275                         break;
276                 default:
277                         if (p->n_op != REG || p->n_type != VOID/* XXX */
278                                 gencode(pFOREFF); /* Emit instructions */
279                 }
280
ragge
1.125
281                 tfree(p);
282                 break;
ragge
1.124
283         case IP_PROLOG:
284                 prologue((struct interpass_prolog *)ip);
285                 break;
286         case IP_EPILOG:
287                 eoftn((struct interpass_prolog *)ip);
288                 tmpsave = NULL/* Always forget old nodes */
ragge
1.174
289                 p2maxautooff = p2autooff = AUTOINIT/SZCHAR;
ragge
1.124
290                 break;
291         case IP_DEFLAB:
292                 deflab(ip->ip_lbl);
293                 break;
294         case IP_ASM:
295                 printf("\t%s\n"ip->ip_asm);
296                 break;
297         default:
298                 cerror("compile4 %d"ip->type);
299         }
ragge
1.123
300 }
ragge
1.124
301
ragge
1.30
302 #ifdef PCC_DEBUG
ragge
1.1
303 char *cnames[] = {
304         "SANY",
305         "SAREG",
306         "SBREG",
ragge
1.153
307         "SCREG",
308         "SDREG",
ragge
1.1
309         "SCC",
310         "SNAME",
311         "SCON",
312         "SFLD",
313         "SOREG",
314         "STARNM",
315         "STARREG",
316         "INTEMP",
317         "FORARG",
318         "SWADD",
319         0,
ragge
1.72
320 };
ragge
1.1
321
ragge
1.2
322 /*
323  * print a nice-looking description of cookie
324  */
ragge
1.70
325 char *
ragge
1.2
326 prcook(int cookie)
327 {
ragge
1.70
328         static char buf[50];
ragge
1.1
329         int iflag;
330
ragge
1.70
331         if (cookie & SPECIAL) {
332                 switch (cookie) {
333                 case SZERO:
334                         return "SZERO";
335                 case SONE:
336                         return "SONE";
337                 case SMONE:
338                         return "SMONE";
339                 default:
340                         sprintf(buf"SPECIAL+%d"cookie & ~SPECIAL);
341                         return buf;
ragge
1.1
342                 }
ragge
1.70
343         }
ragge
1.1
344
345         flag = 0;
ragge
1.70
346         buf[0] = 0;
347         for (i = 0cnames[i]; ++i) {
348                 if (cookie & (1<<i)) {
349                         if (flag)
350                                 strcat(buf"|");
ragge
1.1
351                         ++flag;
ragge
1.70
352                         strcat(bufcnames[i]);
ragge
1.1
353                 }
ragge
1.70
354         }
355         return buf;
356 }
ragge
1.1
357
ragge
1.30
358 #endif
ragge
1.1
359
360 int odebug = 0;
361
ragge
1.151
362 int
ragge
1.69
363 geninsn(NODE *pint cookie)
364 {
ragge
1.71
365         NODE *p1, *p2;
ragge
1.151
366         int orv = 0;
ragge
1.69
367
368 #ifdef PCC_DEBUG
369         if (odebug) {
ragge
1.70
370                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
371                 fwalk(pe2print0);
372         }
373 #endif
374
375 again:  switch (o = p->n_op) {
ragge
1.71
376         case EQ:
377         case NE:
378         case LE:
379         case LT:
380         case GE:
381         case GT:
382         case ULE:
383         case ULT:
384         case UGE:
385         case UGT:
ragge
1.159
386                 rv = relops(p);
387                 break;
ragge
1.71
388
ragge
1.69
389         case PLUS:
390         case MINUS:
391         case MUL:
392         case DIV:
393         case MOD:
394         case AND:
395         case OR:
396         case ER:
397         case LS:
398         case RS:
ragge
1.151
399                 rv = findops(pcookie);
400                 break;
ragge
1.77
401
ragge
1.69
402         case ASSIGN:
ragge
1.174
403         case STASG:
ragge
1.151
404                 rv = findasg(pcookie);
405                 break;
ragge
1.159
406
ragge
1.178
407         case UMUL/* May turn into an OREG */
ragge
1.179
408                 rv = findumul(pcookie);
409                 break;
410
ragge
1.69
411         case REG:
ragge
1.144
412         case TEMP:
ragge
1.72
413         case NAME:
ragge
1.71
414         case ICON:
ragge
1.69
415         case OREG:
ragge
1.152
416                 rv = findleaf(pcookie);
417                 break;
ragge
1.69
418
ragge
1.172
419         case STCALL:
420         case CALL:
421                 /* CALL arguments are handled special */
422                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
423                         geninsn(p1->n_rightFOREFF);
424                 geninsn(p1FOREFF);
425                 /* FALLTHROUGH */
ragge
1.86
426         case COMPL:
ragge
1.85
427         case UMINUS:
ragge
1.71
428         case PCONV:
429         case SCONV:
430         case INIT:
ragge
1.70
431         case GOTO:
432         case FUNARG:
ragge
1.172
433         case STARG:
ragge
1.72
434         case UCALL:
ragge
1.103
435         case USTCALL:
ragge
1.155
436                 rv = finduni(pcookie);
437                 break;
ragge
1.69
438
ragge
1.71
439         case CBRANCH:
440                 p1 = p->n_left;
441                 p2 = p->n_right;
442                 p1->n_label = p2->n_lval;
443                 o = p1->n_op;
444                 geninsn(p1FORCC);
ragge
1.187
445                 p->n_su = 0;
ragge
1.71
446                 break;
447
ragge
1.187
448         case FORCE/* XXX needed? */
ragge
1.151
449                 geninsn(p->n_leftINREGS);
ragge
1.187
450                 p->n_su = 0/* su calculations traverse left */
ragge
1.71
451                 break;
452
ragge
1.69
453         default:
ragge
1.174
454                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
455         }
ragge
1.160
456         if (rv == FFAIL)
457                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
458         if (rv == FRETRY)
459                 goto again;
ragge
1.153
460         return rv;
ragge
1.69
461 }
462
ragge
1.72
463 /*
464  * Store a given subtree in a temporary location.
465  * Return an OREG node where it is located.
466  */
467 NODE *
468 store(NODE *p)
ragge
1.2
469 {
ragge
1.130
470         extern struct interpass *storesave;
471         struct interpass *ip;
472         NODE *q, *r;
473         int s;
ragge
1.49
474
ragge
1.130
475         s = BITOOR(freetemp(szty(p->n_type)));
476         q = mklnode(OREGsFPREGp->n_type);
477         r = mklnode(OREGsFPREGp->n_type);
478         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
479
ragge
1.149
480         storesave = ip;
ragge
1.72
481         return r;
ragge
1.8
482 }
ragge
1.1
483
ragge
1.170
484 #ifdef PCC_DEBUG
485 #define CDEBUG(x) if (c2debug) printf x
486 #else
487 #define CDEBUG(x)
488 #endif
489
ragge
1.69
490 /*
ragge
1.188
491  * Do a register-register move if necessary.
492  */
493 static void
494 ckmove(NODE *pNODE *q)
495 {
ragge
1.189
496         if (q->n_op != REG || p->n_reg == -1)
ragge
1.188
497                 return/* no register */
498         if (DECRA(p->n_reg0) == DECRA(q->n_reg0))
499                 return/* no move necessary */
ragge
1.190
500         CDEBUG(("rmove: node %p, %s -> %s\n"prnames[DECRA(q->n_reg0)],
501             rnames[DECRA(p->n_reg0)]));
ragge
1.188
502         rmove(DECRA(q->n_reg0), DECRA(p->n_reg0), p->n_type);
503         q->n_reg = q->n_rval = DECRA(p->n_reg0);
504 }
505
506 /*
507  * Rewrite node to register after instruction emit.
ragge
1.75
508  */
509 static void
ragge
1.160
510 rewrite(NODE *pint rewriteint cookie)
ragge
1.75
511 {
ragge
1.79
512         NODE *l, *r;
513         int o;
514
ragge
1.80
515         l = getlr(p'L');
516         r = getlr(p'R');
ragge
1.79
517         o = p->n_op;
ragge
1.75
518         p->n_op = REG;
ragge
1.76
519         p->n_lval = 0;
ragge
1.95
520         p->n_name = "";
ragge
1.158
521
ragge
1.190
522         if (o == ASSIGN) {
523                 /* special rewrite care */
524                 int reg = DECRA(p->n_reg0);
ragge
1.191
525 #define TL(x) (TBLIDX(x->n_su) || x->n_op == REG)
ragge
1.190
526                 if (p->n_reg == -1)
527                         ;
ragge
1.191
528                 else if (TL(l) && (DECRA(l->n_reg0) == reg))
ragge
1.190
529                         ;
ragge
1.191
530                 else if (TL(r) && (DECRA(r->n_reg0) == reg))
ragge
1.190
531                         ;
ragge
1.191
532                 else if (TL(l))
ragge
1.190
533                         rmove(DECRA(l->n_reg0), regp->n_type);
ragge
1.191
534                 else if (TL(r))
ragge
1.190
535                         rmove(DECRA(r->n_reg0), regp->n_type);
536 #if 0
537                 else
538                         comperr("rewrite");
539 #endif
ragge
1.191
540 #undef TL
ragge
1.190
541         }
ragge
1.79
542         if (optype(o) != LTYPE)
543                 tfree(l);
544         if (optype(o) == BITYPE)
545                 tfree(r);
ragge
1.190
546         if (rewrite == 0)
547                 return;
548         CDEBUG(("rewrite: %p, reg %s\n"prnames[DECRA(p->n_reg0)]));
ragge
1.187
549         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
550 }
551
ragge
1.69
552 void
ragge
1.72
553 gencode(NODE *pint cookie)
ragge
1.69
554 {
555         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
556         NODE *p1, *l, *r;
ragge
1.190
557         int o = optype(p->n_op);
ragge
1.188
558
559         l = p->n_left;
560         r = p->n_right;
ragge
1.69
561
ragge
1.186
562         if (TBLIDX(p->n_su) == 0) {
563                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
564                         gencode(r0);
ragge
1.185
565                 if (optype(p->n_op) != LTYPE)
ragge
1.188
566                         gencode(l0);
ragge
1.186
567                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
568                         gencode(r0);
ragge
1.185
569                 return;
570         }
ragge
1.69
571
ragge
1.170
572         CDEBUG(("gencode: node %p\n"p));
573
574         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
575                 return/* meaningless move to itself */
ragge
1.175
576
577         if (callop(p->n_op))
578                 lastcall(p); /* last chance before function args */
579         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
580                 /* Print out arguments first */
ragge
1.188
581                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
582                         gencode(p1->n_rightFOREFF);
583                 gencode(p1FOREFF);
ragge
1.190
584                 o = UTYPE/* avoid going down again */
ragge
1.175
585         }
586
ragge
1.190
587         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
588                 gencode(rINREGS);
589                 if (q->rewrite & RRIGHT)
590                         ckmove(pr);
591         }
ragge
1.190
592         if (o != LTYPE) {
ragge
1.188
593                 gencode(lINREGS);
594                 if (q->rewrite & RLEFT)
595                         ckmove(pl);
596         }
ragge
1.190
597         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
598                 gencode(rINREGS);
599                 if (q->rewrite & RRIGHT)
600                         ckmove(pr);
601         }
ragge
1.185
602
ragge
1.188
603         canon(p);
ragge
1.185
604
ragge
1.188
605         if (q->needs & NSPECIAL) {
606                 int rr = rspecial(qNRIGHT);
607                 int lr = rspecial(qNLEFT);
ragge
1.187
608
ragge
1.188
609                 if (rr >= 0) {
610                         if (r->n_op != REG)
611                                 comperr("gencode: rop != REG");
612                         if (rr != r->n_rval)
613                                 rmove(r->n_rvalrrr->n_type);
614                         r->n_rval = r->n_reg = rr;
615                 }
616                 if (lr >= 0) {
617                         if (l->n_op != REG)
ragge
1.192
618                                 comperr("gencode: %p lop != REG"p);
ragge
1.188
619                         if (lr != l->n_rval)
620                                 rmove(l->n_rvallrl->n_type);
621                         l->n_rval = l->n_reg = lr;
622                 }
623                 if (rr >= 0 && lr >= 0 && (l->n_reg == rr || r->n_reg == lr))
624                         comperr("gencode: cross-reg-move");
625         }
ragge
1.161
626
ragge
1.162
627         if (p->n_op == ASSIGN &&
628             p->n_left->n_op == REG && p->n_right->n_op == REG &&
629             p->n_left->n_rval == p->n_right->n_rval){
ragge
1.161
630                 /* do not emit anything */
ragge
1.170
631                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
632                 rewrite(pq->rewritecookie);
633                 return;
634         }
ragge
1.147
635
ragge
1.170
636         CDEBUG(("emitting node %p\n"p));
ragge
1.190
637         if (TBLIDX(p->n_su) == 0)
ragge
1.173
638                 return;
ragge
1.170
639
ragge
1.72
640         expand(pcookieq->cstring);
ragge
1.169
641         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
642             DECRA(p->n_reg0) != RETREG(p->n_type)) {
643                 CDEBUG(("gencode(%p) retreg\n"p));
644                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
645         } else if (q->needs & NSPECIAL) {
ragge
1.158
646                 int rr = rspecial(qNRES);
ragge
1.150
647
ragge
1.188
648                 if (rr >= 0 && DECRA(p->n_reg0) != rr) {
ragge
1.170
649                         CDEBUG(("gencode(%p) nspec retreg\n"p));
650                         rmove(rrDECRA(p->n_reg0), p->n_type);
651                 }
ragge
1.162
652         } else if ((q->rewrite & RESC1) &&
ragge
1.170
653             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
654                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
655                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.190
656         }
657 #if 0
658                 /* XXX - kolla upp det här */
659            else if (p->n_op == ASSIGN) {
ragge
1.176
660                 /* may need move added if RLEFT/RRIGHT */
661                 /* XXX should be handled in sucomp() */
662                 if ((q->rewrite & RLEFT) && (p->n_left->n_op == REG) &&
663                     (p->n_left->n_rval != DECRA(p->n_reg0)) &&
664                     TCLASS(p->n_su)) {
665                         rmove(p->n_left->n_rvalDECRA(p->n_reg0), p->n_type);
666                 } else if ((q->rewrite & RRIGHT) && (p->n_right->n_op == REG) &&
667                     (p->n_right->n_rval != DECRA(p->n_reg0)) &&
668                     TCLASS(p->n_su)) {
669                         rmove(p->n_right->n_rvalDECRA(p->n_reg0), p->n_type);
670                 }
ragge
1.149
671         }
ragge
1.190
672 #endif
ragge
1.160
673         rewrite(pq->rewritecookie);
ragge
1.2
674 }
ragge
1.1
675
676 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
677
ragge
1.30
678 #ifdef PCC_DEBUG
ragge
1.87
679 #undef  PRTABLE
ragge
1.174
680 void
ragge
1.8
681 e2print(NODE *pint downint *aint *b)
ragge
1.2
682 {
ragge
1.85
683 #ifdef PRTABLE
684         extern int tablesize;
685 #endif
ragge
1.1
686
ragge
1.197
687         prfil = stdout;
ragge
1.1
688         *a = *b = down+1;
689         whiledown >= 2 ){
ragge
1.148
690                 fprintf(prfil"\t");
ragge
1.1
691                 down -= 2;
692                 }
ragge
1.148
693         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
694
695
ragge
1.148
696         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
697         switchp->n_op ) { /* special cases */
ragge
1.1
698
699         case REG:
ragge
1.148
700                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
701                 break;
702
ragge
1.121
703         case TEMP:
ragge
1.148
704                 fprintf(prfil" " CONFMTp->n_lval);
ragge
1.121
705                 break;
706
ragge
1.1
707         case ICON:
708         case NAME:
709         case OREG:
ragge
1.148
710                 fprintf(prfil" " );
711                 adrput(prfilp );
ragge
1.1
712                 break;
713
714         case STCALL:
ragge
1.68
715         case USTCALL:
ragge
1.1
716         case STARG:
717         case STASG:
ragge
1.148
718                 fprintf(prfil" size=%d"p->n_stsize );
719                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
720                 break;
721                 }
722
ragge
1.148
723         fprintf(prfil", " );
724         tprint(prfilp->n_typep->n_qual);
725         fprintf(prfil", " );
ragge
1.156
726         {
727                 int gregn(struct regw *);
ragge
1.189
728                 if (p->n_reg == -1)
729                         fprintf(prfil"REG <undef>");
730                 else if (p->n_reg < 100000/* XXX */
ragge
1.170
731                         fprintf(prfil"REG %s"rnames[DECRA(p->n_reg0)]);
ragge
1.155
732                 else
ragge
1.156
733                         fprintf(prfil"TEMP %d"gregn(p->n_regw));
ragge
1.1
734                 }
ragge
1.151
735         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
ragge
1.85
736             TBLIDX(p->n_su), 
ragge
1.151
737             TCLASS(p->n_su)+'@',
ragge
1.85
738 #ifdef PRTABLE
739             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
740             table[TBLIDX(p->n_su)].cstring : "",
741 #else
742             "",
743 #endif
744             ltyp[LMASK&p->n_su],
ragge
1.70
745             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
746 }
ragge
1.30
747 #endif
ragge
1.1
748
749 #ifndef FIELDOPS
ragge
1.7
750 /*
751  * do this if there is no special hardware support for fields
752  */
ragge
1.174
753 static void
ragge
1.7
754 ffld(NODE *pint downint *down1int *down2 )
755 {
756         /*
757          * look for fields that are not in an lvalue context,
758          * and rewrite them...
759          */
760         NODE *shp;
761         int sovty;
ragge
1.1
762
ragge
1.13
763         *down1 =  asgopp->n_op );
ragge
1.1
764         *down2 = 0;
765
ragge
1.13
766         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
767
ragge
1.174
768                 if( !rewfld(p) ) return;
ragge
1.1
769
ragge
1.173
770                 ty = p->n_type;
ragge
1.13
771                 v = p->n_rval;
ragge
1.1
772                 s = UPKFSZ(v);
773 # ifdef RTOLBYTES
774                 o = UPKFOFF(v);  /* amount to shift */
775 # else
ragge
1.13
776                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
777 #endif
778
779                 /* make & mask part */
780
ragge
1.13
781                 p->n_left->n_type = ty;
ragge
1.1
782
ragge
1.13
783                 p->n_op = AND;
ragge
1.130
784                 p->n_right = mklnode(ICON, (1 << s)-10ty);
ragge
1.1
785
786                 /* now, if a shift is needed, do it */
787
788                 ifo != 0 ){
ragge
1.130
789                         shp = mkbinode(RSp->n_left,
ragge
1.173
790                             mklnode(ICONo0INT), ty);
ragge
1.13
791                         p->n_left = shp;
ragge
1.1
792                         /* whew! */
793                 }
794         }
ragge
1.7
795 }
ragge
1.1
796 #endif
797
ragge
1.23
798 /*
799  * change left TEMPs into OREGs
ragge
1.40
800  */
801 void
802 deltemp(NODE *p)
803 {
ragge
1.116
804         struct tmpsave *w;
ragge
1.130
805         NODE *l;
ragge
1.40
806
ragge
1.116
807         if (p->n_op == TEMP) {
808                 /* Check if already existing */
809                 for (w = tmpsaveww = w->next)
810                         if (w->tempno == p->n_lval)
811                                 break;
812                 if (w == NULL) {
813                         /* new on stack */
814                         w = tmpalloc(sizeof(struct tmpsave));
815                         w->tempno = p->n_lval;
816                         w->tempaddr = BITOOR(freetemp(szty(p->n_type)));
817                         w->next = tmpsave;
818                         tmpsave = w;
819                 }
820                 p->n_op = OREG;
821                 p->n_rval = FPREG;
822                 p->n_lval = w->tempaddr;
823         } else if (p->n_op == ADDROF) {
ragge
1.90
824                 /* TEMPs are already converted to OREGs */
825                 if ((l = p->n_left)->n_op != OREG)
826                         comperr("bad U&");
827                 p->n_op = PLUS;
828                 l->n_op = REG;
829                 l->n_type = INCREF(l->n_type);
ragge
1.130
830                 p->n_right = mklnode(ICONl->n_lval0INT);
ragge
1.90
831         }
ragge
1.40
832 }
833
834 /*
ragge
1.48
835  * for pointer/integer arithmetic, set pointer at left node
836  */
837 static void
838 setleft(NODE *p)          
839 {        
840         NODE *q;
841
842         /* only additions for now */
843         if (p->n_op != PLUS)
844                 return;
845         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
846                 q = p->n_right;
847                 p->n_right = p->n_left;
848                 p->n_left = q;
849         }
850 }
851
ragge
1.180
852 /* It is OK to have these as externals */
853 static int oregr;
854 static CONSZ oregtemp;
855 static char *oregcp;
ragge
1.48
856 /*
ragge
1.23
857  * look for situations where we can turn * into OREG
ragge
1.180
858  * If sharp then do not allow temps.
ragge
1.23
859  */
ragge
1.179
860 int
ragge
1.180
861 oregok(NODE *pint sharp)
ragge
1.2
862 {
ragge
1.1
863
864         NODE *q;
ragge
1.2
865         NODE *ql, *qr;
ragge
1.180
866         int r;
867         CONSZ temp;
868         char *cp;
ragge
1.23
869
ragge
1.179
870         q = p->n_left;
ragge
1.182
871 #if 0
ragge
1.180
872         if ((q->n_op == REG || (q->n_op == TEMP && !sharp)) &&
873             q->n_rval == DECRA(q->n_reg0)) {
ragge
1.182
874 #endif
875         if (q->n_op == REG || (q->n_op == TEMP && !sharp)) {
ragge
1.180
876                 temp = q->n_lval;
877                 r = q->n_rval;
878                 cp = q->n_name;
ragge
1.179
879                 goto ormake;
880         }
ragge
1.1
881
ragge
1.179
882         if (q->n_op != PLUS && q->n_op != MINUS)
883                 return 0;
884         ql = q->n_left;
885         qr = q->n_right;
ragge
1.1
886
887 #ifdef R2REGS
888
ragge
1.179
889         /* look for doubly indexed expressions */
890         /* XXX - fix checks */
ragge
1.1
891
ragge
1.179
892         ifq->n_op == PLUS) {
893                 int i;
894                 if( (r=base(ql))>=0 && (i=offset(qrtlen(p)))>=0) {
895                         makeor2(pqlri);
896                         return;
897                 } else if((r=base(qr))>=0 && (i=offset(qltlen(p)))>=0) {
898                         makeor2(pqrri);
899                         return;
ragge
1.12
900                 }
ragge
1.179
901         }
ragge
1.1
902
903
904 #endif
905
ragge
1.182
906 #if 0
ragge
1.179
907         if( (q->n_op==PLUS || q->n_op==MINUS) && qr->