Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20071226122322

Diff

Diff from 1.213 to:

Annotations

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

Annotated File View

ragge
1.213
1 /*      $Id: reader.c,v 1.213 2007/12/26 12:23:22 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 {
gmcgarry
1.208
258         NODE *p, *r;
259         struct optab *op;
ragge
1.149
260         int o;
ragge
1.124
261
ragge
1.125
262         switch (ip->type) {
263         case IP_NODE:
264                 p = ip->ip_node;
ragge
1.124
265
ragge
1.149
266                 nodepole = p;
ragge
1.180
267 //printf("bu:\n");
268 //fwalk(p, e2print, 0);
269                 canon(p); /* may convert stuff after genregs */
270 //fwalk(p, e2print, 0);
ragge
1.124
271                 switch (p->n_op) {
272                 case CBRANCH:
273                         /* Only emit branch insn if RESCC */
gmcgarry
1.208
274                         /* careful when an OPLOG has been elided */
275                         if (p->n_left->n_su == 0 && p->n_left->n_left != NULL) {
276                                 op = &table[TBLIDX(p->n_left->n_left->n_su)];
277                                 r = p->n_left;
278                         } else {
279                                 op = &table[TBLIDX(p->n_left->n_su)];
280                                 r = p;
281                         }
282                         if (op->rewrite & RESCC) {
ragge
1.124
283                                 o = p->n_left->n_op;
gmcgarry
1.208
284                                 gencode(rFORCC);
ragge
1.124
285                                 cbgen(op->n_right->n_lval);
gmcgarry
1.208
286                         } else {
287                                 gencode(rFORCC);
288                         }
ragge
1.124
289                         break;
290                 case FORCE:
ragge
1.151
291                         gencode(p->n_leftINREGS);
ragge
1.124
292                         break;
293                 default:
294                         if (p->n_op != REG || p->n_type != VOID/* XXX */
295                                 gencode(pFOREFF); /* Emit instructions */
296                 }
297
ragge
1.125
298                 tfree(p);
299                 break;
ragge
1.124
300         case IP_PROLOG:
301                 prologue((struct interpass_prolog *)ip);
302                 break;
303         case IP_EPILOG:
304                 eoftn((struct interpass_prolog *)ip);
305                 tmpsave = NULL/* Always forget old nodes */
ragge
1.174
306                 p2maxautooff = p2autooff = AUTOINIT/SZCHAR;
ragge
1.124
307                 break;
308         case IP_DEFLAB:
309                 deflab(ip->ip_lbl);
310                 break;
311         case IP_ASM:
312                 printf("\t%s\n"ip->ip_asm);
313                 break;
314         default:
315                 cerror("compile4 %d"ip->type);
316         }
ragge
1.123
317 }
ragge
1.124
318
ragge
1.30
319 #ifdef PCC_DEBUG
ragge
1.1
320 char *cnames[] = {
321         "SANY",
322         "SAREG",
323         "SBREG",
ragge
1.153
324         "SCREG",
325         "SDREG",
ragge
1.1
326         "SCC",
327         "SNAME",
328         "SCON",
329         "SFLD",
330         "SOREG",
331         "STARNM",
332         "STARREG",
333         "INTEMP",
334         "FORARG",
335         "SWADD",
336         0,
ragge
1.72
337 };
ragge
1.1
338
ragge
1.2
339 /*
340  * print a nice-looking description of cookie
341  */
ragge
1.70
342 char *
ragge
1.2
343 prcook(int cookie)
344 {
ragge
1.70
345         static char buf[50];
ragge
1.1
346         int iflag;
347
ragge
1.70
348         if (cookie & SPECIAL) {
349                 switch (cookie) {
350                 case SZERO:
351                         return "SZERO";
352                 case SONE:
353                         return "SONE";
354                 case SMONE:
355                         return "SMONE";
356                 default:
ragge
1.200
357                         snprintf(bufsizeof(buf), "SPECIAL+%d"cookie & ~SPECIAL);
ragge
1.70
358                         return buf;
ragge
1.1
359                 }
ragge
1.70
360         }
ragge
1.1
361
362         flag = 0;
ragge
1.70
363         buf[0] = 0;
364         for (i = 0cnames[i]; ++i) {
365                 if (cookie & (1<<i)) {
366                         if (flag)
ragge
1.200
367                                 strlcat(buf"|"sizeof(buf));
ragge
1.1
368                         ++flag;
ragge
1.200
369                         strlcat(bufcnames[i], sizeof(buf));
ragge
1.1
370                 }
ragge
1.70
371         }
372         return buf;
373 }
ragge
1.1
374
ragge
1.30
375 #endif
ragge
1.1
376
377 int odebug = 0;
378
ragge
1.151
379 int
ragge
1.69
380 geninsn(NODE *pint cookie)
381 {
ragge
1.71
382         NODE *p1, *p2;
ragge
1.151
383         int orv = 0;
ragge
1.69
384
385 #ifdef PCC_DEBUG
386         if (odebug) {
ragge
1.70
387                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
388                 fwalk(pe2print0);
389         }
390 #endif
391
392 again:  switch (o = p->n_op) {
ragge
1.71
393         case EQ:
394         case NE:
395         case LE:
396         case LT:
397         case GE:
398         case GT:
399         case ULE:
400         case ULT:
401         case UGE:
402         case UGT:
gmcgarry
1.208
403                 p1 = p->n_left;
404                 p2 = p->n_right;
ragge
1.210
405                 if (p2->n_op == ICON && p2->n_lval == 0 &&
406                     optype(p1->n_op) == BITYPE) {
gmcgarry
1.208
407                         if (findops(p1FORCC) == 0)
408                                 break;
409                 }
ragge
1.159
410                 rv = relops(p);
411                 break;
ragge
1.71
412
ragge
1.69
413         case PLUS:
414         case MINUS:
415         case MUL:
416         case DIV:
417         case MOD:
418         case AND:
419         case OR:
420         case ER:
421         case LS:
422         case RS:
ragge
1.151
423                 rv = findops(pcookie);
424                 break;
ragge
1.77
425
ragge
1.69
426         case ASSIGN:
ragge
1.174
427         case STASG:
ragge
1.151
428                 rv = findasg(pcookie);
429                 break;
ragge
1.159
430
ragge
1.178
431         case UMUL/* May turn into an OREG */
ragge
1.179
432                 rv = findumul(pcookie);
433                 break;
434
ragge
1.69
435         case REG:
ragge
1.144
436         case TEMP:
ragge
1.72
437         case NAME:
ragge
1.71
438         case ICON:
ragge
1.213
439         case FCON:
ragge
1.69
440         case OREG:
ragge
1.152
441                 rv = findleaf(pcookie);
442                 break;
ragge
1.69
443
ragge
1.172
444         case STCALL:
445         case CALL:
446                 /* CALL arguments are handled special */
447                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
448                         geninsn(p1->n_rightFOREFF);
449                 geninsn(p1FOREFF);
450                 /* FALLTHROUGH */
ragge
1.206
451         case FLD:
ragge
1.86
452         case COMPL:
ragge
1.85
453         case UMINUS:
ragge
1.71
454         case PCONV:
455         case SCONV:
ragge
1.198
456 /*      case INIT: */
ragge
1.70
457         case GOTO:
458         case FUNARG:
ragge
1.172
459         case STARG:
ragge
1.72
460         case UCALL:
ragge
1.103
461         case USTCALL:
ragge
1.207
462         case ADDROF:
ragge
1.155
463                 rv = finduni(pcookie);
464                 break;
ragge
1.69
465
ragge
1.71
466         case CBRANCH:
467                 p1 = p->n_left;
468                 p2 = p->n_right;
469                 p1->n_label = p2->n_lval;
470                 geninsn(p1FORCC);
ragge
1.187
471                 p->n_su = 0;
ragge
1.71
472                 break;
473
ragge
1.187
474         case FORCE/* XXX needed? */
ragge
1.151
475                 geninsn(p->n_leftINREGS);
ragge
1.187
476                 p->n_su = 0/* su calculations traverse left */
ragge
1.71
477                 break;
478
ragge
1.69
479         default:
ragge
1.174
480                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
481         }
ragge
1.160
482         if (rv == FFAIL)
483                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
484         if (rv == FRETRY)
485                 goto again;
ragge
1.153
486         return rv;
ragge
1.69
487 }
488
ragge
1.72
489 /*
490  * Store a given subtree in a temporary location.
491  * Return an OREG node where it is located.
492  */
493 NODE *
494 store(NODE *p)
ragge
1.2
495 {
ragge
1.130
496         extern struct interpass *storesave;
497         struct interpass *ip;
498         NODE *q, *r;
499         int s;
ragge
1.49
500
ragge
1.130
501         s = BITOOR(freetemp(szty(p->n_type)));
502         q = mklnode(OREGsFPREGp->n_type);
503         r = mklnode(OREGsFPREGp->n_type);
504         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
505
ragge
1.149
506         storesave = ip;
ragge
1.72
507         return r;
ragge
1.8
508 }
ragge
1.1
509
ragge
1.170
510 #ifdef PCC_DEBUG
511 #define CDEBUG(x) if (c2debug) printf x
512 #else
513 #define CDEBUG(x)
514 #endif
515
ragge
1.69
516 /*
ragge
1.188
517  * Do a register-register move if necessary.
518  */
519 static void
520 ckmove(NODE *pNODE *q)
521 {
ragge
1.189
522         if (q->n_op != REG || p->n_reg == -1)
ragge
1.188
523                 return/* no register */
524         if (DECRA(p->n_reg0) == DECRA(q->n_reg0))
525                 return/* no move necessary */
ragge
1.190
526         CDEBUG(("rmove: node %p, %s -> %s\n"prnames[DECRA(q->n_reg0)],
527             rnames[DECRA(p->n_reg0)]));
ragge
1.188
528         rmove(DECRA(q->n_reg0), DECRA(p->n_reg0), p->n_type);
529         q->n_reg = q->n_rval = DECRA(p->n_reg0);
530 }
531
532 /*
533  * Rewrite node to register after instruction emit.
ragge
1.75
534  */
535 static void
ragge
1.160
536 rewrite(NODE *pint rewriteint cookie)
ragge
1.75
537 {
ragge
1.79
538         NODE *l, *r;
539         int o;
540
ragge
1.80
541         l = getlr(p'L');
542         r = getlr(p'R');
ragge
1.79
543         o = p->n_op;
ragge
1.75
544         p->n_op = REG;
ragge
1.76
545         p->n_lval = 0;
ragge
1.95
546         p->n_name = "";
ragge
1.158
547
ragge
1.190
548         if (o == ASSIGN) {
549                 /* special rewrite care */
550                 int reg = DECRA(p->n_reg0);
ragge
1.191
551 #define TL(x) (TBLIDX(x->n_su) || x->n_op == REG)
ragge
1.190
552                 if (p->n_reg == -1)
553                         ;
ragge
1.191
554                 else if (TL(l) && (DECRA(l->n_reg0) == reg))
ragge
1.190
555                         ;
ragge
1.191
556                 else if (TL(r) && (DECRA(r->n_reg0) == reg))
ragge
1.190
557                         ;
ragge
1.191
558                 else if (TL(l))
ragge
1.190
559                         rmove(DECRA(l->n_reg0), regp->n_type);
ragge
1.191
560                 else if (TL(r))
ragge
1.190
561                         rmove(DECRA(r->n_reg0), regp->n_type);
562 #if 0
563                 else
564                         comperr("rewrite");
565 #endif
ragge
1.191
566 #undef TL
ragge
1.190
567         }
ragge
1.79
568         if (optype(o) != LTYPE)
569                 tfree(l);
570         if (optype(o) == BITYPE)
571                 tfree(r);
ragge
1.190
572         if (rewrite == 0)
573                 return;
mickey
1.205
574         CDEBUG(("rewrite: %p, reg %s\n"p,
575             p->n_reg == -1"<none>" : rnames[DECRA(p->n_reg0)]));
ragge
1.187
576         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
577 }
578
ragge
1.69
579 void
ragge
1.72
580 gencode(NODE *pint cookie)
ragge
1.69
581 {
582         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
583         NODE *p1, *l, *r;
ragge
1.190
584         int o = optype(p->n_op);
ragge
1.188
585
586         l = p->n_left;
587         r = p->n_right;
ragge
1.69
588
ragge
1.186
589         if (TBLIDX(p->n_su) == 0) {
590                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
591                         gencode(r0);
ragge
1.185
592                 if (optype(p->n_op) != LTYPE)
ragge
1.188
593                         gencode(l0);
ragge
1.186
594                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
595                         gencode(r0);
ragge
1.185
596                 return;
597         }
ragge
1.69
598
ragge
1.170
599         CDEBUG(("gencode: node %p\n"p));
600
601         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
602                 return/* meaningless move to itself */
ragge
1.175
603
604         if (callop(p->n_op))
605                 lastcall(p); /* last chance before function args */
606         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
607                 /* Print out arguments first */
ragge
1.188
608                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
609                         gencode(p1->n_rightFOREFF);
610                 gencode(p1FOREFF);
ragge
1.190
611                 o = UTYPE/* avoid going down again */
ragge
1.175
612         }
613
ragge
1.190
614         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
615                 gencode(rINREGS);
616                 if (q->rewrite & RRIGHT)
617                         ckmove(pr);
618         }
ragge
1.190
619         if (o != LTYPE) {
ragge
1.188
620                 gencode(lINREGS);
621                 if (q->rewrite & RLEFT)
622                         ckmove(pl);
623         }
ragge
1.190
624         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
625                 gencode(rINREGS);
626                 if (q->rewrite & RRIGHT)
627                         ckmove(pr);
628         }
ragge
1.185
629
ragge
1.188
630         canon(p);
ragge
1.185
631
ragge
1.188
632         if (q->needs & NSPECIAL) {
633                 int rr = rspecial(qNRIGHT);
634                 int lr = rspecial(qNLEFT);
ragge
1.187
635
ragge
1.188
636                 if (rr >= 0) {
gmcgarry
1.211
637 #ifdef PCC_DEBUG
638                         if (optype(p->n_op) != BITYPE)
639                                 comperr("gencode: rspecial borked");
640 #endif
ragge
1.188
641                         if (r->n_op != REG)
642                                 comperr("gencode: rop != REG");
643                         if (rr != r->n_rval)
644                                 rmove(r->n_rvalrrr->n_type);
645                         r->n_rval = r->n_reg = rr;
646                 }
647                 if (lr >= 0) {
648                         if (l->n_op != REG)
ragge
1.192
649                                 comperr("gencode: %p lop != REG"p);
ragge
1.188
650                         if (lr != l->n_rval)
651                                 rmove(l->n_rvallrl->n_type);
652                         l->n_rval = l->n_reg = lr;
653                 }
654                 if (rr >= 0 && lr >= 0 && (l->n_reg == rr || r->n_reg == lr))
655                         comperr("gencode: cross-reg-move");
656         }
ragge
1.161
657
ragge
1.162
658         if (p->n_op == ASSIGN &&
659             p->n_left->n_op == REG && p->n_right->n_op == REG &&
660             p->n_left->n_rval == p->n_right->n_rval){
ragge
1.161
661                 /* do not emit anything */
ragge
1.170
662                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
663                 rewrite(pq->rewritecookie);
664                 return;
665         }
ragge
1.147
666
ragge
1.170
667         CDEBUG(("emitting node %p\n"p));
ragge
1.190
668         if (TBLIDX(p->n_su) == 0)
ragge
1.173
669                 return;
ragge
1.170
670
ragge
1.72
671         expand(pcookieq->cstring);
ragge
1.169
672         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
673             DECRA(p->n_reg0) != RETREG(p->n_type)) {
674                 CDEBUG(("gencode(%p) retreg\n"p));
675                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
676         } else if (q->needs & NSPECIAL) {
ragge
1.158
677                 int rr = rspecial(qNRES);
ragge
1.150
678
ragge
1.188
679                 if (rr >= 0 && DECRA(p->n_reg0) != rr) {
ragge
1.170
680                         CDEBUG(("gencode(%p) nspec retreg\n"p));
681                         rmove(rrDECRA(p->n_reg0), p->n_type);
682                 }
ragge
1.162
683         } else if ((q->rewrite & RESC1) &&
ragge
1.170
684             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
685                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
686                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.190
687         }
688 #if 0
689                 /* XXX - kolla upp det här */
690            else if (p->n_op == ASSIGN) {
ragge
1.176
691                 /* may need move added if RLEFT/RRIGHT */
692                 /* XXX should be handled in sucomp() */
693                 if ((q->rewrite & RLEFT) && (p->n_left->n_op == REG) &&
694                     (p->n_left->n_rval != DECRA(p->n_reg0)) &&
695                     TCLASS(p->n_su)) {
696                         rmove(p->n_left->n_rvalDECRA(p->n_reg0), p->n_type);
697                 } else if ((q->rewrite & RRIGHT) && (p->n_right->n_op == REG) &&
698                     (p->n_right->n_rval != DECRA(p->n_reg0)) &&
699                     TCLASS(p->n_su)) {
700                         rmove(p->n_right->n_rvalDECRA(p->n_reg0), p->n_type);
701                 }
ragge
1.149
702         }
ragge
1.190
703 #endif
ragge
1.160
704         rewrite(pq->rewritecookie);
ragge
1.2
705 }
ragge
1.1
706
707 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
ragge
1.204
708 size_t negrelsize = sizeof negrel / sizeof negrel[0];
ragge
1.1
709
ragge
1.30
710 #ifdef PCC_DEBUG
ragge
1.87
711 #undef  PRTABLE
ragge
1.174
712 void
ragge
1.8
713 e2print(NODE *pint downint *aint *b)
ragge
1.2
714 {
ragge
1.85
715 #ifdef PRTABLE
716         extern int tablesize;
717 #endif
ragge
1.1
718
ragge
1.197
719         prfil = stdout;
ragge
1.1
720         *a = *b = down+1;
721         whiledown >= 2 ){
ragge
1.148
722                 fprintf(prfil"\t");
ragge
1.1
723                 down -= 2;
724                 }
ragge
1.148
725         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
726
727
ragge
1.148
728         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
729         switchp->n_op ) { /* special cases */
ragge
1.1
730
731         case REG:
ragge
1.148
732                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
733                 break;
734
ragge
1.121
735         case TEMP:
ragge
1.148
736                 fprintf(prfil" " CONFMTp->n_lval);
ragge
1.121
737                 break;
738
ragge
1.1
739         case ICON:
740         case NAME:
741         case OREG:
ragge
1.148
742                 fprintf(prfil" " );
743                 adrput(prfilp );
ragge
1.1
744                 break;
745
746         case STCALL:
ragge
1.68
747         case USTCALL:
ragge
1.1
748         case STARG:
749         case STASG:
ragge
1.148
750                 fprintf(prfil" size=%d"p->n_stsize );
751                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
752                 break;
753                 }
754
ragge
1.148
755         fprintf(prfil", " );
756         tprint(prfilp->n_typep->n_qual);
757         fprintf(prfil", " );
ragge
1.156
758         {
759                 int gregn(struct regw *);
ragge
1.189
760                 if (p->n_reg == -1)
761                         fprintf(prfil"REG <undef>");
mickey
1.212
762                 else if (0 <= p->n_reg &&
763                     p->n_reg < (ENCRD(MAXREGS) + ENCRA(MAXREGS,0))) /* XXX */
ragge
1.170
764                         fprintf(prfil"REG %s"rnames[DECRA(p->n_reg0)]);
ragge
1.155
765                 else
ragge
1.156
766                         fprintf(prfil"TEMP %d"gregn(p->n_regw));
ragge
1.1
767                 }
ragge
1.151
768         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
ragge
1.85
769             TBLIDX(p->n_su), 
ragge
1.151
770             TCLASS(p->n_su)+'@',
ragge
1.85
771 #ifdef PRTABLE
772             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
773             table[TBLIDX(p->n_su)].cstring : "",
774 #else
775             "",
776 #endif
777             ltyp[LMASK&p->n_su],
ragge
1.70
778             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
779 }
ragge
1.30
780 #endif
ragge
1.1
781
782 #ifndef FIELDOPS
ragge
1.7
783 /*
784  * do this if there is no special hardware support for fields
785  */
ragge
1.174
786 static void
ragge
1.7
787 ffld(NODE *pint downint *down1int *down2 )
788 {
789         /*
790          * look for fields that are not in an lvalue context,
791          * and rewrite them...
792          */
793         NODE *shp;
794         int sovty;
ragge
1.1
795
ragge
1.13
796         *down1 =  asgopp->n_op );
ragge
1.1
797         *down2 = 0;
798
ragge
1.13
799         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
800
ragge
1.174
801                 if( !rewfld(p) ) return;
ragge
1.1
802
ragge
1.173
803                 ty = p->n_type;
ragge
1.13
804                 v = p->n_rval;
ragge
1.1
805                 s = UPKFSZ(v);
806 # ifdef RTOLBYTES
807                 o = UPKFOFF(v);  /* amount to shift */
808 # else
ragge
1.13
809                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
810 #endif
811
812                 /* make & mask part */
813
ragge
1.203
814                 if (ISUNSIGNED(ty)) {
ragge
1.1
815
ragge
1.203
816                         p->n_left->n_type = ty;
817                         p->n_op = AND;
818                         p->n_right = mklnode(ICON, ((CONSZ)1 << s)-10ty);
819
820                         /* now, if a shift is needed, do it */
821                         ifo != 0 ){
822                                 shp = mkbinode(RSp->n_left,
823                                     mklnode(ICONo0INT), ty);
824                                 p->n_left = shp;
825                                 /* whew! */
826                         }
827                 } else {
828                         /* must sign-extend, assume RS will do */
829                         /* if not, arch must use rewfld() */
830                         p->n_left->n_type = INT/* Ok? */
831                         p->n_op = RS;
832                         p->n_right = mklnode(ICONSZINT-s0INT);
833                         p->n_left = mkbinode(LSp->n_left
834                             mklnode(ICONSZINT-s-o0INT), INT);
ragge
1.1
835                 }
836         }
ragge
1.7
837 }
ragge
1.1
838 #endif
839
ragge
1.23
840 /*
841  * change left TEMPs into OREGs
ragge
1.40
842  */
843 void
844 deltemp(NODE *p)
845 {
ragge
1.116
846         struct tmpsave *w;
ragge
1.130
847         NODE *l;
ragge
1.40
848
ragge
1.116
849         if (p->n_op == TEMP) {
850                 /* Check if already existing */
851                 for (w = tmpsaveww = w->next)
852                         if (w->tempno == p->n_lval)
853                                 break;
854                 if (w == NULL) {
855                         /* new on stack */
856                         w = tmpalloc(sizeof(struct tmpsave));
857                         w->tempno = p->n_lval;
858                         w->tempaddr = BITOOR(freetemp(szty(p->n_type)));
859                         w->next = tmpsave;
860                         tmpsave = w;
861                 }
862                 p->n_op = OREG;
863                 p->n_rval = FPREG;
864                 p->n_lval = w->tempaddr;
ragge
1.207
865         } else if (p->n_op == ADDROF && p->n_left->n_op != NAME) {
ragge
1.90
866                 /* TEMPs are already converted to OREGs */
867                 if ((l = p->n_left)->n_op != OREG)
868                         comperr("bad U&");
869                 p->n_op = PLUS;
870                 l->n_op = REG;
871                 l->n_type = INCREF(l->n_type);
ragge
1.130
872                 p->n_right = mklnode(ICONl->n_lval0INT);
ragge
1.90
873         }
ragge
1.40
874 }
875
876 /*
ragge
1.48
877  * for pointer/integer arithmetic, set pointer at left node
878  */
879 static void
880 setleft(NODE *p)          
881 {        
882         NODE *q;
883
884         /* only additions for now */
885         if (p->n_op != PLUS)
886                 return;
887         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
888                 q = p->n_right;
889                 p->n_right = p->n_left;
890                 p->n_left = q;
891         }
892 }
893
ragge
1.180
894 /* It is OK to have these as externals */
895 static int oregr;
896 static CONSZ oregtemp;
897 static char *oregcp;
ragge
1.48