Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20071116224122

Diff

Diff from 1.209 to:

Annotations

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

Annotated File View

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