Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060715073419

Diff

Diff from 1.196 to:

Annotations

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

Annotated File View

ragge
1.196
1 /*      $Id: reader.c,v 1.196 2006/07/15 07:34:19 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.169
88 FILE *prfil = stdout;
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
687         *a = *b = down+1;
688         whiledown >= 2 ){
ragge
1.148
689                 fprintf(prfil"\t");
ragge
1.1
690                 down -= 2;
691                 }
ragge
1.148
692         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
693
694
ragge
1.148
695         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
696         switchp->n_op ) { /* special cases */
ragge
1.1
697
698         case REG:
ragge
1.148
699                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
700                 break;
701
ragge
1.121
702         case TEMP:
ragge
1.148
703                 fprintf(prfil" " CONFMTp->n_lval);
ragge
1.121
704                 break;
705
ragge
1.1
706         case ICON:
707         case NAME:
708         case OREG:
ragge
1.148
709                 fprintf(prfil" " );
710                 adrput(prfilp );
ragge
1.1
711                 break;
712
713         case STCALL:
ragge
1.68
714         case USTCALL:
ragge
1.1
715         case STARG:
716         case STASG:
ragge
1.148
717                 fprintf(prfil" size=%d"p->n_stsize );
718                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
719                 break;
720                 }
721
ragge
1.148
722         fprintf(prfil", " );
723         tprint(prfilp->n_typep->n_qual);
724         fprintf(prfil", " );
ragge
1.156
725         {
726                 int gregn(struct regw *);
ragge
1.189
727                 if (p->n_reg == -1)
728                         fprintf(prfil"REG <undef>");
729                 else if (p->n_reg < 100000/* XXX */
ragge
1.170
730                         fprintf(prfil"REG %s"rnames[DECRA(p->n_reg0)]);
ragge
1.155
731                 else
ragge
1.156
732                         fprintf(prfil"TEMP %d"gregn(p->n_regw));
ragge
1.1
733                 }
ragge
1.151
734         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
ragge
1.85
735             TBLIDX(p->n_su), 
ragge
1.151
736             TCLASS(p->n_su)+'@',
ragge
1.85
737 #ifdef PRTABLE
738             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
739             table[TBLIDX(p->n_su)].cstring : "",
740 #else
741             "",
742 #endif
743             ltyp[LMASK&p->n_su],
ragge
1.70
744             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
745 }
ragge
1.30
746 #endif
ragge
1.1
747
748 #ifndef FIELDOPS
ragge
1.7
749 /*
750  * do this if there is no special hardware support for fields
751  */
ragge
1.174
752 static void
ragge
1.7
753 ffld(NODE *pint downint *down1int *down2 )
754 {
755         /*
756          * look for fields that are not in an lvalue context,
757          * and rewrite them...
758          */
759         NODE *shp;
760         int sovty;
ragge
1.1
761
ragge
1.13
762         *down1 =  asgopp->n_op );
ragge
1.1
763         *down2 = 0;
764
ragge
1.13
765         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
766
ragge
1.174
767                 if( !rewfld(p) ) return;
ragge
1.1
768
ragge
1.173
769                 ty = p->n_type;
ragge
1.13
770                 v = p->n_rval;
ragge
1.1
771                 s = UPKFSZ(v);
772 # ifdef RTOLBYTES
773                 o = UPKFOFF(v);  /* amount to shift */
774 # else
ragge
1.13
775                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
776 #endif
777
778                 /* make & mask part */
779
ragge
1.13
780                 p->n_left->n_type = ty;
ragge
1.1
781
ragge
1.13
782                 p->n_op = AND;
ragge
1.130
783                 p->n_right = mklnode(ICON, (1 << s)-10ty);
ragge
1.1
784
785                 /* now, if a shift is needed, do it */
786
787                 ifo != 0 ){
ragge
1.130
788                         shp = mkbinode(RSp->n_left,
ragge
1.173
789                             mklnode(ICONo0INT), ty);
ragge
1.13
790                         p->n_left = shp;
ragge
1.1
791                         /* whew! */
792                 }
793         }
ragge
1.7
794 }
ragge
1.1
795 #endif
796
ragge
1.23
797 /*
798  * change left TEMPs into OREGs
ragge
1.40
799  */
800 void
801 deltemp(NODE *p)
802 {
ragge
1.116
803         struct tmpsave *w;
ragge
1.130
804         NODE *l;
ragge
1.40
805
ragge
1.116
806         if (p->n_op == TEMP) {
807                 /* Check if already existing */
808                 for (w = tmpsaveww = w->next)
809                         if (w->tempno == p->n_lval)
810                                 break;
811                 if (w == NULL) {
812                         /* new on stack */
813                         w = tmpalloc(sizeof(struct tmpsave));
814                         w->tempno = p->n_lval;
815                         w->tempaddr = BITOOR(freetemp(szty(p->n_type)));
816                         w->next = tmpsave;
817                         tmpsave = w;
818                 }
819                 p->n_op = OREG;
820                 p->n_rval = FPREG;
821                 p->n_lval = w->tempaddr;
822         } else if (p->n_op == ADDROF) {
ragge
1.90
823                 /* TEMPs are already converted to OREGs */
824                 if ((l = p->n_left)->n_op != OREG)
825                         comperr("bad U&");
826                 p->n_op = PLUS;
827                 l->n_op = REG;
828                 l->n_type = INCREF(l->n_type);
ragge
1.130
829                 p->n_right = mklnode(ICONl->n_lval0INT);
ragge
1.90
830         }
ragge
1.40
831 }
832
833 /*
ragge
1.48
834  * for pointer/integer arithmetic, set pointer at left node
835  */
836 static void
837 setleft(NODE *p)          
838 {        
839         NODE *q;
840
841         /* only additions for now */
842         if (p->n_op != PLUS)
843                 return;
844         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
845                 q = p->n_right;
846                 p->n_right = p->n_left;
847                 p->n_left = q;
848         }
849 }
850
ragge
1.180
851 /* It is OK to have these as externals */
852 static int oregr;
853 static CONSZ oregtemp;
854 static char *oregcp;
ragge
1.48
855 /*
ragge
1.23
856  * look for situations where we can turn * into OREG
ragge
1.180
857  * If sharp then do not allow temps.
ragge
1.23
858  */
ragge
1.179
859 int
ragge
1.180
860 oregok(NODE *pint sharp)
ragge
1.2
861 {
ragge
1.1
862
863         NODE *q;
ragge
1.2
864         NODE *ql, *qr;
ragge
1.180
865         int r;
866         CONSZ temp;
867         char *cp;
ragge
1.23
868
ragge
1.179
869         q = p->n_left;
ragge
1.182
870 #if 0
ragge
1.180
871         if ((q->n_op == REG || (q->n_op == TEMP && !sharp)) &&
872             q->n_rval == DECRA(q->n_reg0)) {
ragge
1.182
873 #endif
874         if (q->n_op == REG || (q->n_op == TEMP && !sharp)) {
ragge
1.180
875                 temp = q->n_lval;
876                 r = q->n_rval;
877                 cp = q->n_name;
ragge
1.179
878                 goto ormake;
879         }
ragge
1.1
880
ragge
1.179
881         if (q->n_op != PLUS && q->n_op != MINUS)
882                 return 0;
883         ql = q->n_left;
884         qr = q->n_right;
ragge
1.1
885
886 #ifdef R2REGS
887
ragge
1.179
888         /* look for doubly indexed expressions */
889         /* XXX - fix checks */
ragge
1.1
890
ragge
1.179
891         ifq->n_op == PLUS) {
892                 int i;
893                 if( (r=base(ql))>=0 && (i=offset(qrtlen(p)))>=0) {
894                         makeor2(pqlri);
895                         return;
896                 } else if((r=base(qr))>=0 && (i=offset(qltlen(p)))>=0) {
897                         makeor2(pqrri);
898                         return;
ragge
1.12
899                 }
ragge
1.179
900         }
ragge
1.1
901
902
903 #endif
904
ragge
1.182
905 #if 0
ragge
1.179
906         if( (q->n_op==PLUS || q->n_op==MINUS) && qr->n_op == ICON &&
ragge
1.180
907