Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20071128030208

Diff

Diff from 1.211 to:

Annotations

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

Annotated File View

gmcgarry
1.211
1 /*      $Id: reader.c,v 1.211 2007/11/28 03:02:08 gmcgarry 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.69
439         case OREG:
ragge
1.152
440                 rv = findleaf(pcookie);
441                 break;
ragge
1.69
442
ragge
1.172
443         case STCALL:
444         case CALL:
445                 /* CALL arguments are handled special */
446                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
447                         geninsn(p1->n_rightFOREFF);
448                 geninsn(p1FOREFF);
449                 /* FALLTHROUGH */
ragge
1.206
450         case FLD:
ragge
1.86
451         case COMPL:
ragge
1.85
452         case UMINUS:
ragge
1.71
453         case PCONV:
454         case SCONV:
ragge
1.198
455 /*      case INIT: */
ragge
1.70
456         case GOTO:
457         case FUNARG:
ragge
1.172
458         case STARG:
ragge
1.72
459         case UCALL:
ragge
1.103
460         case USTCALL:
ragge
1.207
461         case ADDROF:
ragge
1.155
462                 rv = finduni(pcookie);
463                 break;
ragge
1.69
464
ragge
1.71
465         case CBRANCH:
466                 p1 = p->n_left;
467                 p2 = p->n_right;
468                 p1->n_label = p2->n_lval;
469                 geninsn(p1FORCC);
ragge
1.187
470                 p->n_su = 0;
ragge
1.71
471                 break;
472
ragge
1.187
473         case FORCE/* XXX needed? */
ragge
1.151
474                 geninsn(p->n_leftINREGS);
ragge
1.187
475                 p->n_su = 0/* su calculations traverse left */
ragge
1.71
476                 break;
477
ragge
1.69
478         default:
ragge
1.174
479                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
480         }
ragge
1.160
481         if (rv == FFAIL)
482                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
483         if (rv == FRETRY)
484                 goto again;
ragge
1.153
485         return rv;
ragge
1.69
486 }
487
ragge
1.72
488 /*
489  * Store a given subtree in a temporary location.
490  * Return an OREG node where it is located.
491  */
492 NODE *
493 store(NODE *p)
ragge
1.2
494 {
ragge
1.130
495         extern struct interpass *storesave;
496         struct interpass *ip;
497         NODE *q, *r;
498         int s;
ragge
1.49
499
ragge
1.130
500         s = BITOOR(freetemp(szty(p->n_type)));
501         q = mklnode(OREGsFPREGp->n_type);
502         r = mklnode(OREGsFPREGp->n_type);
503         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
504
ragge
1.149
505         storesave = ip;
ragge
1.72
506         return r;
ragge
1.8
507 }
ragge
1.1
508
ragge
1.170
509 #ifdef PCC_DEBUG
510 #define CDEBUG(x) if (c2debug) printf x
511 #else
512 #define CDEBUG(x)
513 #endif
514
ragge
1.69
515 /*
ragge
1.188
516  * Do a register-register move if necessary.
517  */
518 static void
519 ckmove(NODE *pNODE *q)
520 {
ragge
1.189
521         if (q->n_op != REG || p->n_reg == -1)
ragge
1.188
522                 return/* no register */
523         if (DECRA(p->n_reg0) == DECRA(q->n_reg0))
524                 return/* no move necessary */
ragge
1.190
525         CDEBUG(("rmove: node %p, %s -> %s\n"prnames[DECRA(q->n_reg0)],
526             rnames[DECRA(p->n_reg0)]));
ragge
1.188
527         rmove(DECRA(q->n_reg0), DECRA(p->n_reg0), p->n_type);
528         q->n_reg = q->n_rval = DECRA(p->n_reg0);
529 }
530
531 /*
532  * Rewrite node to register after instruction emit.
ragge
1.75
533  */
534 static void
ragge
1.160
535 rewrite(NODE *pint rewriteint cookie)
ragge
1.75
536 {
ragge
1.79
537         NODE *l, *r;
538         int o;
539
ragge
1.80
540         l = getlr(p'L');
541         r = getlr(p'R');
ragge
1.79
542         o = p->n_op;
ragge
1.75
543         p->n_op = REG;
ragge
1.76
544         p->n_lval = 0;
ragge
1.95
545         p->n_name = "";
ragge
1.158
546
ragge
1.190
547         if (o == ASSIGN) {
548                 /* special rewrite care */
549                 int reg = DECRA(p->n_reg0);
ragge
1.191
550 #define TL(x) (TBLIDX(x->n_su) || x->n_op == REG)
ragge
1.190
551                 if (p->n_reg == -1)
552                         ;
ragge
1.191
553                 else if (TL(l) && (DECRA(l->n_reg0) == reg))
ragge
1.190
554                         ;
ragge
1.191
555                 else if (TL(r) && (DECRA(r->n_reg0) == reg))
ragge
1.190
556                         ;
ragge
1.191
557                 else if (TL(l))
ragge
1.190
558                         rmove(DECRA(l->n_reg0), regp->n_type);
ragge
1.191
559                 else if (TL(r))
ragge
1.190
560                         rmove(DECRA(r->n_reg0), regp->n_type);
561 #if 0
562                 else
563                         comperr("rewrite");
564 #endif
ragge
1.191
565 #undef TL
ragge
1.190
566         }
ragge
1.79
567         if (optype(o) != LTYPE)
568                 tfree(l);
569         if (optype(o) == BITYPE)
570                 tfree(r);
ragge
1.190
571         if (rewrite == 0)
572                 return;
mickey
1.205
573         CDEBUG(("rewrite: %p, reg %s\n"p,
574             p->n_reg == -1"<none>" : rnames[DECRA(p->n_reg0)]));
ragge
1.187
575         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
576 }
577
ragge
1.69
578 void
ragge
1.72
579 gencode(NODE *pint cookie)
ragge
1.69
580 {
581         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
582         NODE *p1, *l, *r;
ragge
1.190
583         int o = optype(p->n_op);
ragge
1.188
584
585         l = p->n_left;
586         r = p->n_right;
ragge
1.69
587
ragge
1.186
588         if (TBLIDX(p->n_su) == 0) {
589                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
590                         gencode(r0);
ragge
1.185
591                 if (optype(p->n_op) != LTYPE)
ragge
1.188
592                         gencode(l0);
ragge
1.186
593                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
594                         gencode(r0);
ragge
1.185
595                 return;
596         }
ragge
1.69
597
ragge
1.170
598         CDEBUG(("gencode: node %p\n"p));
599
600         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
601                 return/* meaningless move to itself */
ragge
1.175
602
603         if (callop(p->n_op))
604                 lastcall(p); /* last chance before function args */
605         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
606                 /* Print out arguments first */
ragge
1.188
607                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
608                         gencode(p1->n_rightFOREFF);
609                 gencode(p1FOREFF);
ragge
1.190
610                 o = UTYPE/* avoid going down again */
ragge
1.175
611         }
612
ragge
1.190
613         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
614                 gencode(rINREGS);
615                 if (q->rewrite & RRIGHT)
616                         ckmove(pr);
617         }
ragge
1.190
618         if (o != LTYPE) {
ragge
1.188
619                 gencode(lINREGS);
620                 if (q->rewrite & RLEFT)
621                         ckmove(pl);
622         }
ragge
1.190
623         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
624                 gencode(rINREGS);
625                 if (q->rewrite & RRIGHT)
626                         ckmove(pr);
627         }
ragge
1.185
628
ragge
1.188
629         canon(p);
ragge
1.185
630
ragge
1.188
631         if (q->needs & NSPECIAL) {
632                 int rr = rspecial(qNRIGHT);
633                 int lr = rspecial(qNLEFT);
ragge
1.187
634
ragge
1.188
635                 if (rr >= 0) {
gmcgarry
1.211
636 #ifdef PCC_DEBUG
637                         if (optype(p->n_op) != BITYPE)
638                                 comperr("gencode: rspecial borked");
639 #endif
ragge
1.188
640                         if (r->n_op != REG)
641                                 comperr("gencode: rop != REG");
642                         if (rr != r->n_rval)
643                                 rmove(r->n_rvalrrr->n_type);
644                         r->n_rval = r->n_reg = rr;
645                 }
646                 if (lr >= 0) {
647                         if (l->n_op != REG)
ragge
1.192
648                                 comperr("gencode: %p lop != REG"p);
ragge
1.188
649                         if (lr != l->n_rval)
650                                 rmove(l->n_rvallrl->n_type);
651                         l->n_rval = l->n_reg = lr;
652                 }
653                 if (rr >= 0 && lr >= 0 && (l->n_reg == rr || r->n_reg == lr))
654                         comperr("gencode: cross-reg-move");
655         }
ragge
1.161
656
ragge
1.162
657         if (p->n_op == ASSIGN &&
658             p->n_left->n_op == REG && p->n_right->n_op == REG &&
659             p->n_left->n_rval == p->n_right->n_rval){
ragge
1.161
660                 /* do not emit anything */
ragge
1.170
661                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
662                 rewrite(pq->rewritecookie);
663                 return;
664         }
ragge
1.147
665
ragge
1.170
666         CDEBUG(("emitting node %p\n"p));
ragge
1.190
667         if (TBLIDX(p->n_su) == 0)
ragge
1.173
668                 return;
ragge
1.170
669
ragge
1.72
670         expand(pcookieq->cstring);
ragge
1.169
671         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
672             DECRA(p->n_reg0) != RETREG(p->n_type)) {
673                 CDEBUG(("gencode(%p) retreg\n"p));
674                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
675         } else if (q->needs & NSPECIAL) {
ragge
1.158
676                 int rr = rspecial(qNRES);
ragge
1.150
677
ragge
1.188
678                 if (rr >= 0 && DECRA(p->n_reg0) != rr) {
ragge
1.170
679                         CDEBUG(("gencode(%p) nspec retreg\n"p));
680                         rmove(rrDECRA(p->n_reg0), p->n_type);
681                 }
ragge
1.162
682         } else if ((q->rewrite & RESC1) &&
ragge
1.170
683             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
684                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
685                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.190
686         }
687 #if 0
688                 /* XXX - kolla upp det här */
689            else if (p->n_op == ASSIGN) {
ragge
1.176
690                 /* may need move added if RLEFT/RRIGHT */
691                 /* XXX should be handled in sucomp() */
692                 if ((q->rewrite & RLEFT) && (p->n_left->n_op == REG) &&
693                     (p->n_left->n_rval != DECRA(p->n_reg0)) &&
694                     TCLASS(p->n_su)) {
695                         rmove(p->n_left->n_rvalDECRA(p->n_reg0), p->n_type);
696                 } else if ((q->rewrite & RRIGHT) && (p->n_right->n_op == REG) &&
697                     (p->n_right->n_rval != DECRA(p->n_reg0)) &&
698                     TCLASS(p->n_su)) {
699                         rmove(p->n_right->n_rvalDECRA(p->n_reg0), p->n_type);
700                 }
ragge
1.149
701         }
ragge
1.190
702 #endif
ragge
1.160
703         rewrite(pq->rewritecookie);
ragge
1.2
704 }
ragge
1.1
705
706 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
ragge
1.204
707 size_t negrelsize = sizeof negrel / sizeof negrel[0];
ragge
1.1
708
ragge
1.30
709 #ifdef PCC_DEBUG
ragge
1.87
710 #undef  PRTABLE
ragge
1.174
711 void
ragge
1.8
712 e2print(NODE *pint downint *aint *b)
ragge
1.2
713 {
ragge
1.85
714 #ifdef PRTABLE
715         extern int tablesize;
716 #endif
ragge
1.1
717
ragge
1.197
718         prfil = stdout;
ragge
1.1
719         *a = *b = down+1;
720         whiledown >= 2 ){
ragge
1.148
721                 fprintf(prfil"\t");
ragge
1.1
722                 down -= 2;
723                 }
ragge
1.148
724         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
725
726
ragge
1.148
727         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
728         switchp->n_op ) { /* special cases */
ragge
1.1
729
730         case REG:
ragge
1.148
731                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
732                 break;
733
ragge
1.121
734         case TEMP:
ragge
1.148
735                 fprintf(prfil" " CONFMTp->n_lval);
ragge
1.121
736                 break;
737
ragge
1.1
738         case ICON:
739         case NAME:
740         case OREG:
ragge
1.148
741                 fprintf(prfil" " );
742                 adrput(prfilp );
ragge
1.1
743                 break;
744
745         case STCALL:
ragge
1.68
746         case USTCALL:
ragge
1.1
747         case STARG:
748         case STASG:
ragge
1.148
749                 fprintf(prfil" size=%d"p->n_stsize );
750                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
751                 break;
752                 }
753
ragge
1.148
754         fprintf(prfil", " );
755         tprint(prfilp->n_typep->n_qual);
756         fprintf(prfil", " );
ragge
1.156
757         {
758                 int gregn(struct regw *);
ragge
1.189
759                 if (p->n_reg == -1)
760                         fprintf(prfil"REG <undef>");
761                 else if (p->n_reg < 100000/* XXX */
ragge
1.170
762                         fprintf(prfil"REG %s"rnames[DECRA(p->n_reg0)]);
ragge
1.155
763                 else
ragge
1.156
764                         fprintf(prfil"TEMP %d"gregn(p->n_regw));
ragge
1.1
765                 }
ragge
1.151
766         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
ragge
1.85
767             TBLIDX(p->n_su), 
ragge
1.151
768             TCLASS(p->n_su)+'@',
ragge
1.85
769 #ifdef PRTABLE
770             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
771             table[TBLIDX(p->n_su)].cstring : "",
772 #else
773             "",
774 #endif
775             ltyp[LMASK&p->n_su],
ragge
1.70
776             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
777 }
ragge
1.30
778 #endif
ragge
1.1
779
780 #ifndef FIELDOPS
ragge
1.7
781 /*
782  * do this if there is no special hardware support for fields
783  */
ragge
1.174
784 static void
ragge
1.7
785 ffld(NODE *pint downint *down1int *down2 )
786 {
787         /*
788          * look for fields that are not in an lvalue context,
789          * and rewrite them...
790          */
791         NODE *shp;
792         int sovty;
ragge
1.1
793
ragge
1.13
794         *down1 =  asgopp->n_op );
ragge
1.1
795         *down2 = 0;
796
ragge
1.13
797         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
798
ragge
1.174
799                 if( !rewfld(p) ) return;
ragge
1.1
800
ragge
1.173
801                 ty = p->n_type;
ragge
1.13
802                 v = p->n_rval;
ragge
1.1
803                 s = UPKFSZ(v);
804 # ifdef RTOLBYTES
805                 o = UPKFOFF(v);  /* amount to shift */
806 # else
ragge
1.13
807                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
808 #endif
809
810                 /* make & mask part */
811
ragge
1.203
812                 if (ISUNSIGNED(ty)) {
ragge
1.1
813
ragge
1.203
814                         p->n_left->n_type = ty;
815                         p->n_op = AND;
816                         p->n_right = mklnode(ICON, ((CONSZ)1 << s)-10ty);
817
818                         /* now, if a shift is needed, do it */
819                         ifo != 0 ){
820                                 shp = mkbinode(RSp->n_left,
821                                     mklnode(ICONo0INT), ty);
822                                 p->n_left = shp;
823                                 /* whew! */
824                         }
825                 } else {
826                         /* must sign-extend, assume RS will do */
827                         /* if not, arch must use rewfld() */
828                         p->n_left->n_type = INT/* Ok? */
829                         p->n_op = RS;
830                         p->n_right = mklnode(ICONSZINT-s0INT);
831                         p->n_left = mkbinode(LSp->n_left
832                             mklnode(ICONSZINT-s-o0INT), INT);
ragge
1.1
833                 }
834         }
ragge
1.7
835 }
ragge
1.1
836 #endif
837
ragge
1.23
838 /*
839  * change left TEMPs into OREGs
ragge
1.40
840  */
841 void
842 deltemp(NODE *p)
843 {
ragge
1.116
844         struct tmpsave *w;
ragge
1.130
845         NODE *l;
ragge
1.40
846
ragge
1.116
847         if (p->n_op == TEMP) {
848                 /* Check if already existing */
849                 for (w = tmpsaveww = w->next)
850                         if (w->tempno == p->n_lval)
851                                 break;
852                 if (w == NULL) {
853                         /* new on stack */
854                         w = tmpalloc(sizeof(struct tmpsave));
855                         w->tempno = p->n_lval;
856                         w->tempaddr = BITOOR(freetemp(szty(p->n_type)));
857                         w->next = tmpsave;
858                         tmpsave = w;
859                 }
860                 p->n_op = OREG;
861                 p->n_rval = FPREG;
862                 p->n_lval = w->tempaddr;
ragge
1.207
863         } else if (p->n_op == ADDROF && p->n_left->n_op != NAME) {
ragge
1.90
864                 /* TEMPs are already converted to OREGs */
865                 if ((l = p->n_left)->n_op != OREG)
866                         comperr("bad U&");
867                 p->n_op = PLUS;
868                 l->n_op = REG;
869                 l->n_type = INCREF(l->n_type);
ragge
1.130
870                 p->n_right = mklnode(ICONl->n_lval0INT);
ragge
1.90
871         }
ragge
1.40
872 }
873
874 /*
ragge
1.48
875  * for pointer/integer arithmetic, set pointer at left node
876  */
877 static void
878 setleft(NODE *p)          
879 {        
880         NODE *q;
881
882         /* only additions for now */
883         if (p->n_op != PLUS)
884                 return;
885         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
886                 q = p->n_right;
887                 p->n_right = p->n_left;
888                 p->n_left = q;
889         }
890 }
891
ragge
1.180
892 /* It is OK to have these as externals */
893 static int oregr;
894 static CONSZ oregtemp;
895 static char *oregcp;
ragge
1.48
896 /*
ragge
1.23
897  * look for situations where we can turn * into OREG
ragge
1.180
898  * If sharp&