Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20080320002815

Diff

Diff from 1.219 to:

Annotations

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

Annotated File View

gmcgarry
1.219
1 /*      $Id: reader.c,v 1.219 2008/03/20 00:28:15 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);
ragge
1.40
92 void deltemp(NODE *p);
93 void cvtemps(struct interpass *epil);
ragge
1.72
94 NODE *store(NODE *);
ragge
1.216
95 static void fixxasm(struct interpass *ip);
ragge
1.65
96
ragge
1.72
97 static void gencode(NODE *pint cookie);
ragge
1.216
98 static void genxasm(NODE *p);
ragge
1.69
99
ragge
1.150
100 char *ltyp[] = { """LREG""LOREG""LTEMP" };
101 char *rtyp[] = { """RREG""ROREG""RTEMP" };
ragge
1.37
102
ragge
1.121
103 /* used when removing nodes */
104 struct tmpsave {
105         struct tmpsave *next;
106         CONSZ tempaddr;
107         int tempno;
108 } *tmpsave;
109
ragge
1.26
110 #ifdef PCC_DEBUG
111 static void
112 cktree(NODE *p)
113 {
114         if (p->n_op > MAXOP)
ragge
1.218
115                 cerror("%p) op %d slipped through"pp->n_op);
ragge
1.199
116         if (BTYPE(p->n_type) > MAXTYPES)
ragge
1.218
117                 cerror("%p) type %x slipped through"pp->n_type);
ragge
1.35
118         if (p->n_op == CBRANCH && !logop(p->n_left->n_op))
ragge
1.218
119                 cerror("%p) not logop branch"p);
ragge
1.47
120         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
ragge
1.218
121                 cerror("%p) asgop %d slipped through"pp->n_op);
ragge
1.26
122 }
123 #endif
ragge
1.8
124
ragge
1.130
125 /*
ragge
1.89
126  * Check if a node has side effects.
127  */
128 static int
129 isuseless(NODE *n)
130 {
131         switch (n->n_op) {
ragge
1.216
132         case XASM:
ragge
1.89
133         case FUNARG:
134         case UCALL:
135         case UFORTCALL:
136         case FORCE:
137         case ASSIGN:
138         case CALL:
139         case FORTCALL:
140         case CBRANCH:
141         case RETURN:
142         case GOTO:
143         case STCALL:
144         case USTCALL:
145         case STASG:
146         case STARG:
147                 return 0;
148         default:
149                 return 1;
150         }
151 }
152
ragge
1.130
153 /*
154  * Delete statements with no meaning (like a+b; or 513.4;)
155  */
ragge
1.89
156 static NODE *
157 deluseless(NODE *p)
158 {
159         struct interpass *ip;
160         NODE *l, *r;
161
162         if (optype(p->n_op) == LTYPE) {
163                 nfree(p);
164                 return NULL;
165         }
166         if (isuseless(p) == 0)
167                 return p;
168
169         if (optype(p->n_op) == UTYPE) {
170                 l = p->n_left;
171                 nfree(p);
172                 return deluseless(l);
173         }
174
175         /* Be sure that both leaves may be valid */
176         l = deluseless(p->n_left);
177         r = deluseless(p->n_right);
178         nfree(p);
179         if (l && r) {
ragge
1.201
180                 ip = ipnode(l);
181                 DLIST_INSERT_AFTER(&prepoleipqelem);
ragge
1.89
182                 return r;
183         } else if (l)
184                 return l;
185         else if (r)
186                 return r;
187         return NULL;
188 }
189
ragge
1.172
190 static struct interpass ipole;
ragge
1.174
191 struct interpass_prolog *ipp, *epp;
ragge
1.172
192
193 /*
194  * Receives interpass structs from pass1.
195  */
196 void
197 pass2_compile(struct interpass *ip)
198 {
199         if (ip->type == IP_PROLOG) {
200                 tmpsave = NULL;
ragge
1.174
201                 ipp = (struct interpass_prolog *)ip;
ragge
1.172
202                 DLIST_INIT(&ipoleqelem);
203         }
204         DLIST_INSERT_BEFORE(&ipoleipqelem);
205         if (ip->type != IP_EPILOG)
206                 return;
207
208 #ifdef PCC_DEBUG
209         if (e2debug) {
210                 printf("Entering pass2\n");
211                 printip(&ipole);
212         }
213 #endif
ragge
1.174
214
ragge
1.172
215         epp = (struct interpass_prolog *)DLIST_PREV(&ipoleqelem);
216         p2maxautooff = p2autooff = epp->ipp_autos;
ragge
1.174
217
218         myreader(&ipole); /* local massage of input */
219
ragge
1.172
220         DLIST_FOREACH(ip, &ipoleqelem) {
221                 if (ip->type != IP_NODE)
222                         continue;
223                 if (xtemps == 0)
224                         walkf(ip->ip_nodedeltemp);
225         }
ragge
1.201
226         DLIST_INIT(&prepoleqelem);
ragge
1.172
227         DLIST_FOREACH(ip, &ipoleqelem) {
228                 if (ip->type != IP_NODE)
229                         continue;
230                 canon(ip->ip_node);
231                 walkf(ip->ip_nodecktree);
ragge
1.201
232                 if ((ip->ip_node = deluseless(ip->ip_node)) == NULL) {
ragge
1.172
233                         DLIST_REMOVE(ipqelem);
ragge
1.201
234                 } else while (!DLIST_ISEMPTY(&prepoleqelem)) {
235                         struct interpass *ipp;
236
237                         ipp = DLIST_NEXT(&prepoleqelem);
238                         DLIST_REMOVE(ippqelem);
239                         DLIST_INSERT_BEFORE(ipippqelem);
240                 }
ragge
1.172
241         }
242
ragge
1.216
243         fixxasm(&ipole); /* setup for extended asm */
244
ragge
1.172
245         optimize(&ipole);
246         ngenregs(&ipole);
247
248         DLIST_FOREACH(ip, &ipoleqelem)
249                 emit(ip);
250 }
251
ragge
1.124
252 void
ragge
1.125
253 emit(struct interpass *ip)
ragge
1.124
254 {
gmcgarry
1.208
255         NODE *p, *r;
256         struct optab *op;
ragge
1.149
257         int o;
ragge
1.124
258
ragge
1.125
259         switch (ip->type) {
260         case IP_NODE:
261                 p = ip->ip_node;
ragge
1.124
262
ragge
1.149
263                 nodepole = p;
ragge
1.180
264 //printf("bu:\n");
265 //fwalk(p, e2print, 0);
266                 canon(p); /* may convert stuff after genregs */
267 //fwalk(p, e2print, 0);
ragge
1.124
268                 switch (p->n_op) {
269                 case CBRANCH:
270                         /* Only emit branch insn if RESCC */
gmcgarry
1.208
271                         /* careful when an OPLOG has been elided */
272                         if (p->n_left->n_su == 0 && p->n_left->n_left != NULL) {
273                                 op = &table[TBLIDX(p->n_left->n_left->n_su)];
274                                 r = p->n_left;
275                         } else {
276                                 op = &table[TBLIDX(p->n_left->n_su)];
277                                 r = p;
278                         }
279                         if (op->rewrite & RESCC) {
ragge
1.124
280                                 o = p->n_left->n_op;
gmcgarry
1.208
281                                 gencode(rFORCC);
ragge
1.124
282                                 cbgen(op->n_right->n_lval);
gmcgarry
1.208
283                         } else {
284                                 gencode(rFORCC);
285                         }
ragge
1.124
286                         break;
287                 case FORCE:
ragge
1.151
288                         gencode(p->n_leftINREGS);
ragge
1.124
289                         break;
ragge
1.216
290                 case XASM:
291                         genxasm(p);
292                         break;
ragge
1.124
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:
ragge
1.217
312                 printf("%s"ip->ip_asm);
ragge
1.124
313                 break;
314         default:
ragge
1.216
315                 cerror("emit %d"ip->type);
ragge
1.124
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.216
479         case XASM:
480                 for (p1 = p->n_leftp1->n_op == CMp1 = p1->n_left)
481                         geninsn(p1->n_rightFOREFF);
482                 geninsn(p1FOREFF);
483                 break;  /* all stuff already done? */
484
485         case XARG:
486                 /* generate code for correct class here */
487                 geninsn(p->n_left1 << p->n_label);
488                 break;
489
ragge
1.69
490         default:
ragge
1.174
491                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
492         }
ragge
1.160
493         if (rv == FFAIL)
494                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
495         if (rv == FRETRY)
496                 goto again;
ragge
1.153
497         return rv;
ragge
1.69
498 }
499
ragge
1.72
500 /*
501  * Store a given subtree in a temporary location.
502  * Return an OREG node where it is located.
503  */
504 NODE *
505 store(NODE *p)
ragge
1.2
506 {
ragge
1.130
507         extern struct interpass *storesave;
508         struct interpass *ip;
509         NODE *q, *r;
510         int s;
ragge
1.49
511
ragge
1.130
512         s = BITOOR(freetemp(szty(p->n_type)));
513         q = mklnode(OREGsFPREGp->n_type);
514         r = mklnode(OREGsFPREGp->n_type);
515         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
516
ragge
1.149
517         storesave = ip;
ragge
1.72
518         return r;
ragge
1.8
519 }
ragge
1.1
520
ragge
1.170
521 #ifdef PCC_DEBUG
522 #define CDEBUG(x) if (c2debug) printf x
523 #else
524 #define CDEBUG(x)
525 #endif
526
ragge
1.69
527 /*
ragge
1.188
528  * Do a register-register move if necessary.
529  */
530 static void
531 ckmove(NODE *pNODE *q)
532 {
ragge
1.189
533         if (q->n_op != REG || p->n_reg == -1)
ragge
1.188
534                 return/* no register */
535         if (DECRA(p->n_reg0) == DECRA(q->n_reg0))
536                 return/* no move necessary */
ragge
1.190
537         CDEBUG(("rmove: node %p, %s -> %s\n"prnames[DECRA(q->n_reg0)],
538             rnames[DECRA(p->n_reg0)]));
ragge
1.188
539         rmove(DECRA(q->n_reg0), DECRA(p->n_reg0), p->n_type);
540         q->n_reg = q->n_rval = DECRA(p->n_reg0);
541 }
542
543 /*
544  * Rewrite node to register after instruction emit.
ragge
1.75
545  */
546 static void
ragge
1.160
547 rewrite(NODE *pint rewriteint cookie)
ragge
1.75
548 {
ragge
1.79
549         NODE *l, *r;
550         int o;
551
ragge
1.80
552         l = getlr(p'L');
553         r = getlr(p'R');
ragge
1.79
554         o = p->n_op;
ragge
1.75
555         p->n_op = REG;
ragge
1.76
556         p->n_lval = 0;
ragge
1.95
557         p->n_name = "";
ragge
1.158
558
ragge
1.190
559         if (o == ASSIGN) {
560                 /* special rewrite care */
561                 int reg = DECRA(p->n_reg0);
ragge
1.191
562 #define TL(x) (TBLIDX(x->n_su) || x->n_op == REG)
ragge
1.190
563                 if (p->n_reg == -1)
564                         ;
ragge
1.191
565                 else if (TL(l) && (DECRA(l->n_reg0) == reg))
ragge
1.190
566                         ;
ragge
1.191
567                 else if (TL(r) && (DECRA(r->n_reg0) == reg))
ragge
1.190
568                         ;
ragge
1.191
569                 else if (TL(l))
ragge
1.190
570                         rmove(DECRA(l->n_reg0), regp->n_type);
ragge
1.191
571                 else if (TL(r))
ragge
1.190
572                         rmove(DECRA(r->n_reg0), regp->n_type);
573 #if 0
574                 else
575                         comperr("rewrite");
576 #endif
ragge
1.191
577 #undef TL
ragge
1.190
578         }
ragge
1.79
579         if (optype(o) != LTYPE)
580                 tfree(l);
581         if (optype(o) == BITYPE)
582                 tfree(r);
ragge
1.190
583         if (rewrite == 0)
584                 return;
mickey
1.205
585         CDEBUG(("rewrite: %p, reg %s\n"p,
586             p->n_reg == -1"<none>" : rnames[DECRA(p->n_reg0)]));
ragge
1.187
587         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
588 }
589
ragge
1.216
590 /*
591  * printout extended assembler.
592  */
593 void
594 genxasm(NODE *p)
595 {
596         NODE *q, **nary;
597         int n = 1o = 0;
598         char *w;
599
600         for (q = p->n_leftq->n_op == CMq = q->n_left)
601                 n++;
602         nary = tmpalloc(sizeof(NODE *)*n);
603         o = n;
604         for (q = p->n_leftq->n_op == CMq = q->n_left) {
605                 gencode(q->n_right->n_leftINREGS);
606                 nary[--o] = q->n_right;
607         }
608         gencode(q->n_leftINREGS);
609         nary[--o] = q;
610
611         w = p->n_name;
612         putchar('\t');
613         while (*w != 0) {
614                 if (*w == '%') {
615                         if (w[1] < '1' || w[1] > (n + '0'))
616                                 uerror("bad xasm arg number");
617                         else
618                                 adrput(stdoutnary[(int)w[1]-'1']->n_left);
619                         w++;
620                 } else
621                         putchar(*w);
622                 w++;
623         }
624         putchar('\n');
625 }
626
ragge
1.69
627 void
ragge
1.72
628 gencode(NODE *pint cookie)
ragge
1.69
629 {
630         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
631         NODE *p1, *l, *r;
ragge
1.190
632         int o = optype(p->n_op);
ragge
1.188
633
634         l = p->n_left;
635         r = p->n_right;
ragge
1.69
636
ragge
1.186
637         if (TBLIDX(p->n_su) == 0) {
638                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
639                         gencode(r0);
ragge
1.185
640                 if (optype(p->n_op) != LTYPE)
ragge
1.188
641                         gencode(l0);
ragge
1.186
642                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
643                         gencode(r0);
ragge
1.185
644                 return;
645         }
ragge
1.69
646
ragge
1.170
647         CDEBUG(("gencode: node %p\n"p));
648
649         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
650                 return/* meaningless move to itself */
ragge
1.175
651
652         if (callop(p->n_op))
653                 lastcall(p); /* last chance before function args */
654         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
655                 /* Print out arguments first */
ragge
1.188
656                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
657                         gencode(p1->n_rightFOREFF);
658                 gencode(p1FOREFF);
ragge
1.190
659                 o = UTYPE/* avoid going down again */
ragge
1.175
660         }
661
ragge
1.190
662         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
663                 gencode(rINREGS);
664                 if (q->rewrite & RRIGHT)
665                         ckmove(pr);
666         }
ragge
1.190
667         if (o != LTYPE) {
ragge
1.188
668                 gencode(lINREGS);
669                 if (q->rewrite & RLEFT)
670                         ckmove(pl);
671         }
ragge
1.190
672         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
673                 gencode(rINREGS);
674                 if (q->rewrite & RRIGHT)
675                         ckmove(pr);
676         }
ragge
1.185
677
ragge
1.188
678         canon(p);
ragge
1.185
679
ragge
1.188
680         if (q->needs & NSPECIAL) {
681                 int rr = rspecial(qNRIGHT);
682                 int lr = rspecial(qNLEFT);
ragge
1.187
683
ragge
1.188
684                 if (rr >= 0) {
gmcgarry
1.211
685 #ifdef PCC_DEBUG
686                         if (optype(p->n_op) != BITYPE)
687                                 comperr("gencode: rspecial borked");
688 #endif
ragge
1.188
689                         if (r->n_op != REG)
690                                 comperr("gencode: rop != REG");
691                         if (rr != r->n_rval)
692                                 rmove(r->n_rvalrrr->n_type);
693                         r->n_rval = r->n_reg = rr;
694                 }
695                 if (lr >= 0) {
696                         if (l->n_op != REG)
ragge
1.192
697                                 comperr("gencode: %p lop != REG"p);
ragge
1.188
698                         if (lr != l->n_rval)
699                                 rmove(l->n_rvallrl->n_type);
700                         l->n_rval = l->n_reg = lr;
701                 }
702                 if (rr >= 0 && lr >= 0 && (l->n_reg == rr || r->n_reg == lr))
703                         comperr("gencode: cross-reg-move");
704         }
ragge
1.161
705
ragge
1.162
706         if (p->n_op == ASSIGN &&
707             p->n_left->n_op == REG && p->n_right->n_op == REG &&
708             p->n_left->n_rval == p->n_right->n_rval){
ragge
1.161
709                 /* do not emit anything */
ragge
1.170
710                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
711                 rewrite(pq->rewritecookie);
712                 return;
713         }
ragge
1.147
714
ragge
1.170
715         CDEBUG(("emitting node %p\n"p));
ragge
1.190
716         if (TBLIDX(p->n_su) == 0)
ragge
1.173
717                 return;
ragge
1.170
718
ragge
1.72
719         expand(pcookieq->cstring);
ragge
1.169
720         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
721             DECRA(p->n_reg0) != RETREG(p->n_type)) {
722                 CDEBUG(("gencode(%p) retreg\n"p));
723                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
724         } else if (q->needs & NSPECIAL) {
ragge
1.158
725                 int rr = rspecial(qNRES);
ragge
1.150
726
ragge
1.188
727                 if (rr >= 0 && DECRA(p->n_reg0) != rr) {
ragge
1.170
728                         CDEBUG(("gencode(%p) nspec retreg\n"p));
729                         rmove(rrDECRA(p->n_reg0), p->n_type);
730                 }
ragge
1.162
731         } else if ((q->rewrite & RESC1) &&
ragge
1.170
732             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
733                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
734                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.190
735         }
736 #if 0
737                 /* XXX - kolla upp det här */
738            else if (p->n_op == ASSIGN) {
ragge
1.176
739                 /* may need move added if RLEFT/RRIGHT */
740                 /* XXX should be handled in sucomp() */
741                 if ((q->rewrite & RLEFT) && (p->n_left->n_op == REG) &&
742                     (p->n_left->n_rval != DECRA(p->n_reg0)) &&
743                     TCLASS(p->n_su)) {
744                         rmove(p->n_left->n_rvalDECRA(p->n_reg0), p->n_type);
745                 } else if ((q->rewrite & RRIGHT) && (p->n_right->n_op == REG) &&
746                     (p->n_right->n_rval != DECRA(p->n_reg0)) &&
747                     TCLASS(p->n_su)) {
748                         rmove(p->n_right->n_rvalDECRA(p->n_reg0), p->n_type);
749                 }
ragge
1.149
750         }
ragge
1.190
751 #endif
ragge
1.160
752         rewrite(pq->rewritecookie);
ragge
1.2
753 }
ragge
1.1
754
755 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
ragge
1.204
756 size_t negrelsize = sizeof negrel / sizeof negrel[0];
ragge
1.1
757
ragge
1.30
758 #ifdef PCC_DEBUG
ragge
1.87
759 #undef  PRTABLE
ragge
1.174
760 void
ragge
1.8
761 e2print(NODE *pint downint *aint *b)
ragge
1.2
762 {
ragge
1.85
763 #ifdef PRTABLE
764         extern int tablesize;
765 #endif
ragge
1.1
766
ragge
1.197
767         prfil = stdout;
ragge
1.1
768         *a = *b = down+1;
769         whiledown >= 2 ){
ragge
1.148
770                 fprintf(prfil"\t");
ragge
1.1
771                 down -= 2;
772                 }
ragge
1.148
773         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
774
775
ragge
1.148
776         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
777         switchp->n_op ) { /* special cases */
ragge
1.1
778
779         case REG:
ragge
1.148
780                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
781                 break;
782
ragge
1.121
783         case TEMP:
ragge
1.214
784                 fprintf(prfil" %d"regno(p));
ragge
1.121
785                 break;
786
ragge
1.216
787         case XASM:
788         case XARG:
789                 fprintf(prfil" '%s'"p->n_name);
790                 break;
791
ragge
1.1
792         case ICON:
793         case NAME:
794         case OREG:
ragge
1.148
795                 fprintf(prfil" " );
796                 adrput(prfilp );
ragge
1.1
797                 break;
798
799         case STCALL:
ragge
1.68
800         case USTCALL:
ragge
1.1
801         case STARG:
802         case STASG:
ragge
1.148
803                 fprintf(prfil" size=%d"p->n_stsize );
804                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
805                 break;
806                 }
807
ragge
1.148
808         fprintf(prfil", " );
809         tprint(prfilp->n_typep->n_qual);
810         fprintf(prfil", " );
ragge
1.215
811
812         prtreg(prfilp);
ragge
1.151
813         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
ragge
1.85
814             TBLIDX(p->n_su), 
ragge
1.151
815             TCLASS(p->n_su)+'@',
ragge
1.85
816 #ifdef PRTABLE
817             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
818             table[TBLIDX(p->n_su)].cstring : "",
819 #else
820             "",
821 #endif
822             ltyp[LMASK&p->n_su],
ragge
1.70
823             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
824 }
ragge
1.30
825 #endif
ragge
1.1
826
827 #ifndef FIELDOPS
ragge
1.7
828 /*
829  * do this if there is no special hardware support for fields
830  */
ragge
1.174
831 static void
ragge
1.7
832 ffld(NODE *pint downint *down1int *down2 )
833 {
834         /*
835          * look for fields that are not in an lvalue context,
836          * and rewrite them...
837          */
838         NODE *shp;
839         int sovty;
ragge
1.1
840
ragge
1.13
841         *down1 =  asgopp->n_op );
ragge
1.1
842         *down2 = 0;
843
ragge
1.13
844         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
845
ragge
1.174
846                 if( !rewfld(p) ) return;
ragge
1.1
847
ragge
1.173
848                 ty = p->n_type;
ragge
1.13
849                 v = p->n_rval;
ragge
1.1
850                 s = UPKFSZ(v);
851 # ifdef RTOLBYTES
852                 o = UPKFOFF(v);  /* amount to shift */
853 # else
ragge
1.13
854                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
855 #endif
856
857                 /* make & mask part */
858
ragge
1.203
859                 if (ISUNSIGNED(ty)) {
ragge
1.1
860
ragge
1.203
861                         p->n_left->n_type = ty;
862                         p->n_op = AND;
863                         p->n_right = mklnode(ICON, ((CONSZ)1 << s)-10ty);
864
865                         /* now, if a shift is needed, do it */
866                         ifo != 0 ){
867                                 shp = mkbinode(RSp->n_left,
868                                     mklnode(ICONo0INT), ty);
869                                 p->n_left = shp;
870                                 /* whew! */
871                         }
872                 } else {
873                         /* must sign-extend, assume RS will do */
874                         /* if not, arch must use rewfld() */
875                         p->n_left->n_type = INT/* Ok? */
876                         p->n_op = RS;
877                         p->n_right = mklnode(ICONSZINT-s0INT);
878                         p->n_left = mkbinode(LSp->n_left
879                             mklnode(ICONSZINT-s-o0INT), INT);
ragge
1.1
880                 }
881         }
ragge
1.7
882 }
ragge
1.1
883 #endif
884
ragge
1.23
885 /*
886  * change left TEMPs into OREGs
ragge
1.40
887  */
888 void
889 deltemp(NODE *p)
890 {
ragge
1.116
891         struct tmpsave *w;
gmcgarry
1.219
892         NODE *l, *r;
ragge
1.40
893
ragge
1.116
894         if (p->n_op == TEMP) {
895                 /* Check if already existing */
896                 for (w = tmpsaveww = w->next)
ragge
1.214
897                         if (w->tempno == regno(p))
ragge
1.116
898