Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20070915073738

Diff

Diff from 1.200 to:

Annotations

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

Annotated File View

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