Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:mickey:20071023094903

Diff

Diff from 1.205 to:

Annotations

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

Annotated File View

mickey
1.205
1 /*      $Id: reader.c,v 1.205 2007/10/23 09:49:03 mickey 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;
mickey
1.205
555         CDEBUG(("rewrite: %p, reg %s\n"p,
556             p->n_reg == -1"<none>" : rnames[DECRA(p->n_reg0)]));
ragge
1.187
557         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
558 }
559
ragge
1.69
560 void
ragge
1.72
561 gencode(NODE *pint cookie)
ragge
1.69
562 {
563         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
564         NODE *p1, *l, *r;
ragge
1.190
565         int o = optype(p->n_op);
ragge
1.188
566
567         l = p->n_left;
568         r = p->n_right;
ragge
1.69
569
ragge
1.186
570         if (TBLIDX(p->n_su) == 0) {
571                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
572                         gencode(r0);
ragge
1.185
573                 if (optype(p->n_op) != LTYPE)
ragge
1.188
574                         gencode(l0);
ragge
1.186
575                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
576                         gencode(r0);
ragge
1.185
577                 return;
578         }
ragge
1.69
579
ragge
1.170
580         CDEBUG(("gencode: node %p\n"p));
581
582         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
583                 return/* meaningless move to itself */
ragge
1.175
584
585         if (callop(p->n_op))
586                 lastcall(p); /* last chance before function args */
587         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
588                 /* Print out arguments first */
ragge
1.188
589                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
590                         gencode(p1->n_rightFOREFF);
591                 gencode(p1FOREFF);
ragge
1.190
592                 o = UTYPE/* avoid going down again */
ragge
1.175
593         }
594
ragge
1.190
595         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
596                 gencode(rINREGS);
597                 if (q->rewrite & RRIGHT)
598                         ckmove(pr);
599         }
ragge
1.190
600         if (o != LTYPE) {
ragge
1.188
601                 gencode(lINREGS);
602                 if (q->rewrite & RLEFT)
603                         ckmove(pl);
604         }
ragge
1.190
605         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
606                 gencode(rINREGS);
607                 if (q->rewrite & RRIGHT)
608                         ckmove(pr);
609         }
ragge
1.185
610
ragge
1.188
611         canon(p);
ragge
1.185
612
ragge
1.188
613         if (q->needs & NSPECIAL) {
614                 int rr = rspecial(qNRIGHT);
615                 int lr = rspecial(qNLEFT);
ragge
1.187
616
ragge
1.188
617                 if (rr >= 0) {
618                         if (r->n_op != REG)
619                                 comperr("gencode: rop != REG");
620                         if (rr != r->n_rval)
621                                 rmove(r->n_rvalrrr->n_type);
622                         r->n_rval = r->n_reg = rr;
623                 }
624                 if (lr >= 0) {
625                         if (l->n_op != REG)
ragge
1.192
626                                 comperr("gencode: %p lop != REG"p);
ragge
1.188
627                         if (lr != l->n_rval)
628                                 rmove(l->n_rvallrl->n_type);
629                         l->n_rval = l->n_reg = lr;
630                 }
631                 if (rr >= 0 && lr >= 0 && (l->n_reg == rr || r->n_reg == lr))
632                         comperr("gencode: cross-reg-move");
633         }
ragge
1.161
634
ragge
1.162
635         if (p->n_op == ASSIGN &&
636             p->n_left->n_op == REG && p->n_right->n_op == REG &&
637             p->n_left->n_rval == p->n_right->n_rval){
ragge
1.161
638                 /* do not emit anything */
ragge
1.170
639                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
640                 rewrite(pq->rewritecookie);
641                 return;
642         }
ragge
1.147
643
ragge
1.170
644         CDEBUG(("emitting node %p\n"p));
ragge
1.190
645         if (TBLIDX(p->n_su) == 0)
ragge
1.173
646                 return;
ragge
1.170
647
ragge
1.72
648         expand(pcookieq->cstring);
ragge
1.169
649         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
650             DECRA(p->n_reg0) != RETREG(p->n_type)) {
651                 CDEBUG(("gencode(%p) retreg\n"p));
652                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
653         } else if (q->needs & NSPECIAL) {
ragge
1.158
654                 int rr = rspecial(qNRES);
ragge
1.150
655
ragge
1.188
656                 if (rr >= 0 && DECRA(p->n_reg0) != rr) {
ragge
1.170
657                         CDEBUG(("gencode(%p) nspec retreg\n"p));
658                         rmove(rrDECRA(p->n_reg0), p->n_type);
659                 }
ragge
1.162
660         } else if ((q->rewrite & RESC1) &&
ragge
1.170
661             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
662                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
663                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.190
664         }
665 #if 0
666                 /* XXX - kolla upp det här */
667            else if (p->n_op == ASSIGN) {
ragge
1.176
668                 /* may need move added if RLEFT/RRIGHT */
669                 /* XXX should be handled in sucomp() */
670                 if ((q->rewrite & RLEFT) && (p->n_left->n_op == REG) &&
671                     (p->n_left->n_rval != DECRA(p->n_reg0)) &&
672                     TCLASS(p->n_su)) {
673                         rmove(p->n_left->n_rvalDECRA(p->n_reg0), p->n_type);
674                 } else if ((q->rewrite & RRIGHT) && (p->n_right->n_op == REG) &&
675                     (p->n_right->n_rval != DECRA(p->n_reg0)) &&
676                     TCLASS(p->n_su)) {
677                         rmove(p->n_right->n_rvalDECRA(p->n_reg0), p->n_type);
678                 }
ragge
1.149
679         }
ragge
1.190
680 #endif
ragge
1.160
681         rewrite(pq->rewritecookie);
ragge
1.2
682 }
ragge
1.1
683
684 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
ragge
1.204
685 size_t negrelsize = sizeof negrel / sizeof negrel[0];
ragge
1.1
686
ragge
1.30
687 #ifdef PCC_DEBUG
ragge
1.87
688 #undef  PRTABLE
ragge
1.174
689 void
ragge
1.8
690 e2print(NODE *pint downint *aint *b)
ragge
1.2
691 {
ragge
1.85
692 #ifdef PRTABLE
693         extern int tablesize;
694 #endif
ragge
1.1
695
ragge
1.197
696         prfil = stdout;
ragge
1.1
697         *a = *b = down+1;
698         whiledown >= 2 ){
ragge
1.148
699                 fprintf(prfil"\t");
ragge
1.1
700                 down -= 2;
701                 }
ragge
1.148
702         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
703
704
ragge
1.148
705         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
706         switchp->n_op ) { /* special cases */
ragge
1.1
707
708         case REG:
ragge
1.148
709                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
710                 break;
711
ragge
1.121
712         case TEMP:
ragge
1.148
713                 fprintf(prfil" " CONFMTp->n_lval);
ragge
1.121
714                 break;
715
ragge
1.1
716         case ICON:
717         case NAME:
718         case OREG:
ragge
1.148
719                 fprintf(prfil" " );
720                 adrput(prfilp );
ragge
1.1
721                 break;
722
723         case STCALL:
ragge
1.68
724         case USTCALL:
ragge
1.1
725         case STARG:
726         case STASG:
ragge
1.148
727                 fprintf(prfil" size=%d"p->n_stsize );
728                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
729                 break;
730                 }
731
ragge
1.148
732         fprintf(prfil", " );
733         tprint(prfilp->n_typep->n_qual);
734         fprintf(prfil", " );
ragge
1.156
735         {
736                 int gregn(struct regw *);
ragge
1.189
737                 if (p->n_reg == -1)
738                         fprintf(prfil"REG <undef>");
739                 else if (p->n_reg < 100000/* XXX */
ragge
1.170
740                         fprintf(prfil"REG %s"rnames[DECRA(p->n_reg0)]);
ragge
1.155
741                 else
ragge
1.156
742                         fprintf(prfil"TEMP %d"gregn(p->n_regw));
ragge
1.1
743                 }
ragge
1.151
744         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
ragge
1.85
745             TBLIDX(p->n_su), 
ragge
1.151
746             TCLASS(p->n_su)+'@',
ragge
1.85
747 #ifdef PRTABLE
748             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
749             table[TBLIDX(p->n_su)].cstring : "",
750 #else
751             "",
752 #endif
753             ltyp[LMASK&p->n_su],
ragge
1.70
754             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
755 }
ragge
1.30
756 #endif
ragge
1.1
757
758 #ifndef FIELDOPS
ragge
1.7
759 /*
760  * do this if there is no special hardware support for fields
761  */
ragge
1.174
762 static void
ragge
1.7
763 ffld(NODE *pint downint *down1int *down2 )
764 {
765         /*
766          * look for fields that are not in an lvalue context,
767          * and rewrite them...
768          */
769         NODE *shp;
770         int sovty;
ragge
1.1
771
ragge
1.13
772         *down1 =  asgopp->n_op );
ragge
1.1
773         *down2 = 0;
774
ragge
1.13
775         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
776
ragge
1.174
777                 if( !rewfld(p) ) return;
ragge
1.1
778
ragge
1.173
779                 ty = p->n_type;
ragge
1.13
780                 v = p->n_rval;
ragge
1.1
781                 s = UPKFSZ(v);
782 # ifdef RTOLBYTES
783                 o = UPKFOFF(v);  /* amount to shift */
784 # else
ragge
1.13
785                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
786 #endif
787
788                 /* make & mask part */
789
ragge
1.203
790                 if (ISUNSIGNED(ty)) {
ragge
1.1
791
ragge
1.203
792                         p->n_left->n_type = ty;
793                         p->n_op = AND;
794                         p->n_right = mklnode(ICON, ((CONSZ)1 << s)-10ty);
795
796                         /* now, if a shift is needed, do it */
797                         ifo != 0 ){
798                                 shp = mkbinode(RSp->n_left,
799                                     mklnode(ICONo0INT), ty);
800                                 p->n_left = shp;
801                                 /* whew! */
802                         }
803                 } else {
804                         /* must sign-extend, assume RS will do */
805                         /* if not, arch must use rewfld() */
806                         p->n_left->n_type = INT/* Ok? */
807                         p->n_op = RS;
808                         p->n_right = mklnode(ICONSZINT-s0INT);
809                         p->n_left = mkbinode(LSp->n_left
810                             mklnode(ICONSZINT-s-o0INT), INT);
ragge
1.1
811                 }
812         }
ragge
1.7
813 }
ragge
1.1
814 #endif
815
ragge
1.23
816 /*
817  * change left TEMPs into OREGs
ragge
1.40
818  */
819 void
820 deltemp(NODE *p)
821 {
ragge
1.116
822         struct tmpsave *w;
ragge
1.130
823         NODE *l;
ragge
1.40
824
ragge
1.116
825         if (p->n_op == TEMP) {
826                 /* Check if already existing */
827                 for (w = tmpsaveww = w->next)
828                         if (w->tempno == p->n_lval)
829                                 break;
830                 if (w == NULL) {
831                         /* new on stack */
832                         w = tmpalloc(sizeof(struct tmpsave));
833                         w->tempno = p->n_lval;
834                         w->tempaddr = BITOOR(freetemp(szty(p->n_type)));
835                         w->next = tmpsave;
836                         tmpsave = w;
837                 }
838                 p->n_op = OREG;
839                 p->n_rval = FPREG;
840                 p->n_lval = w->tempaddr;
841         } else if (p->n_op == ADDROF) {
ragge
1.90
842                 /* TEMPs are already converted to OREGs */
843                 if ((l = p->n_left)->n_op != OREG)
844                         comperr("bad U&");
845                 p->n_op = PLUS;
846                 l->n_op = REG;
847                 l->n_type = INCREF(l->n_type);
ragge
1.130
848                 p->n_right = mklnode(ICONl->n_lval0INT);
ragge
1.90
849         }
ragge
1.40
850 }
851
852 /*
ragge
1.48
853  * for pointer/integer arithmetic, set pointer at left node
854  */
855 static void
856 setleft(NODE *p)          
857 {        
858         NODE *q;
859
860         /* only additions for now */
861         if (p->n_op != PLUS)
862                 return;
863         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
864                 q = p->n_right;
865                 p->n_right = p->n_left;
866                 p->n_left = q;
867         }
868 }
869
ragge
1.180
870 /* It is OK to have these as externals */
871 static int oregr;
872 static CONSZ oregtemp;
873 static char *oregcp;
ragge
1.48
874 /*
ragge
1.23
875  * look for situations where we can turn * into OREG
ragge
1.180
876  * If sharp then do not allow temps.
ragge
1.23
877  */
ragge
1.179
878 int
ragge
1.180
879 oregok(NODE *pint sharp)
ragge
1.2
880 {
ragge
1.1
881
882         NODE *q;
ragge
1.2
883         NODE *ql, *qr;
ragge
1.180
884         int r;
885         CONSZ temp;
886         char *cp;
ragge
1.23
887
ragge
1.179
888         q = p->n_left;
ragge
1.182
889 #if 0
ragge
1.180
890         if ((q->n_op == REG || (q->n_op == TEMP && !sharp)) &&
891             q->n_rval == DECRA(q->n_reg0)) {
ragge
1.182
892 #endif
893         if (q->n_op == REG || (q->n_op == TEMP && !sharp)) {
ragge
1.180
894                 temp = q->n_lval;
895                 r = q->n_rval;
896                 cp = q->n_name;
ragge
1.179
897                 goto ormake;
898         }
ragge
1.1