Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20070924162336

Diff

Diff from 1.202 to:

Annotations

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

Annotated File View

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