Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080730154105

Diff

Diff from 1.234 to:

Annotations

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

Annotated File View

ragge
1.234
1 /*      $Id: reader.c,v 1.234 2008/07/30 15:41:05 ragge Exp $   */
ragge
1.72
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
ragge
1.31
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
ragge
1.1
62
ragge
1.123
63 /*
ragge
1.174
64  * Everything is entered via pass2_compile().  Three functions are 
65  * allowed to recurse into pass2_compile(), so be careful:
66  * - deluseless()
ragge
1.123
67  * - myreader()
ragge
1.174
68  * Especially in myreader note that trees may be rewritten twice if
69  * things are not carefully handled.
ragge
1.123
70  */
71
ragge
1.1
72 # include "pass2.h"
73
ragge
1.70
74 #include <string.h>
ragge
1.71
75 #include <stdarg.h>
ragge
1.94
76 #include <stdlib.h>
ragge
1.70
77
ragge
1.1
78 /*      some storage declarations */
79 int nrecur;
80 int lflag;
ragge
1.9
81 int x2debug;
ragge
1.1
82 int udebug = 0;
ragge
1.103
83 int thisline;
ragge
1.72
84 int fregs;
ragge
1.123
85 int p2autooffp2maxautooff;
ragge
1.1
86
ragge
1.72
87 NODE *nodepole;
ragge
1.197
88 FILE *prfil;
ragge
1.201
89 static struct interpass prepole;
ragge
1.23
90
ragge
1.37
91 void saveip(struct interpass *ip);
ragge
1.40
92 void deltemp(NODE *p);
ragge
1.232
93 static void cvtemps(struct interpass *ipoleint opint off);
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);
gmcgarry
1.220
231 #ifdef PCC_DEBUG
ragge
1.172
232                 walkf(ip->ip_nodecktree);
gmcgarry
1.220
233 #endif
ragge
1.201
234                 if ((ip->ip_node = deluseless(ip->ip_node)) == NULL) {
ragge
1.172
235                         DLIST_REMOVE(ipqelem);
ragge
1.201
236                 } else while (!DLIST_ISEMPTY(&prepoleqelem)) {
gmcgarry
1.224
237                         struct interpass *tipp;
ragge
1.201
238
gmcgarry
1.224
239                         tipp = DLIST_NEXT(&prepoleqelem);
240                         DLIST_REMOVE(tippqelem);
241                         DLIST_INSERT_BEFORE(iptippqelem);
ragge
1.201
242                 }
ragge
1.172
243         }
244
ragge
1.216
245         fixxasm(&ipole); /* setup for extended asm */
246
ragge
1.172
247         optimize(&ipole);
248         ngenregs(&ipole);
249
250         DLIST_FOREACH(ip, &ipoleqelem)
251                 emit(ip);
252 }
253
ragge
1.124
254 void
ragge
1.125
255 emit(struct interpass *ip)
ragge
1.124
256 {
gmcgarry
1.208
257         NODE *p, *r;
258         struct optab *op;
ragge
1.149
259         int o;
ragge
1.124
260
ragge
1.125
261         switch (ip->type) {
262         case IP_NODE:
263                 p = ip->ip_node;
ragge
1.124
264
ragge
1.149
265                 nodepole = p;
ragge
1.180
266 //printf("bu:\n");
267 //fwalk(p, e2print, 0);
268                 canon(p); /* may convert stuff after genregs */
269 //fwalk(p, e2print, 0);
ragge
1.124
270                 switch (p->n_op) {
271                 case CBRANCH:
272                         /* Only emit branch insn if RESCC */
gmcgarry
1.208
273                         /* careful when an OPLOG has been elided */
274                         if (p->n_left->n_su == 0 && p->n_left->n_left != NULL) {
275                                 op = &table[TBLIDX(p->n_left->n_left->n_su)];
276                                 r = p->n_left;
277                         } else {
278                                 op = &table[TBLIDX(p->n_left->n_su)];
279                                 r = p;
280                         }
281                         if (op->rewrite & RESCC) {
ragge
1.124
282                                 o = p->n_left->n_op;
gmcgarry
1.208
283                                 gencode(rFORCC);
ragge
1.124
284                                 cbgen(op->n_right->n_lval);
gmcgarry
1.208
285                         } else {
286                                 gencode(rFORCC);
287                         }
ragge
1.124
288                         break;
289                 case FORCE:
ragge
1.151
290                         gencode(p->n_leftINREGS);
ragge
1.124
291                         break;
ragge
1.216
292                 case XASM:
293                         genxasm(p);
294                         break;
ragge
1.124
295                 default:
296                         if (p->n_op != REG || p->n_type != VOID/* XXX */
297                                 gencode(pFOREFF); /* Emit instructions */
298                 }
299
ragge
1.125
300                 tfree(p);
301                 break;
ragge
1.124
302         case IP_PROLOG:
303                 prologue((struct interpass_prolog *)ip);
304                 break;
305         case IP_EPILOG:
306                 eoftn((struct interpass_prolog *)ip);
307                 tmpsave = NULL/* Always forget old nodes */
ragge
1.174
308                 p2maxautooff = p2autooff = AUTOINIT/SZCHAR;
ragge
1.124
309                 break;
310         case IP_DEFLAB:
311                 deflab(ip->ip_lbl);
312                 break;
313         case IP_ASM:
gmcgarry
1.229
314                 printf("%s"ip->ip_asm);
ragge
1.124
315                 break;
316         default:
ragge
1.216
317                 cerror("emit %d"ip->type);
ragge
1.124
318         }
ragge
1.123
319 }
ragge
1.124
320
ragge
1.30
321 #ifdef PCC_DEBUG
ragge
1.1
322 char *cnames[] = {
323         "SANY",
324         "SAREG",
325         "SBREG",
ragge
1.153
326         "SCREG",
327         "SDREG",
ragge
1.1
328         "SCC",
329         "SNAME",
330         "SCON",
331         "SFLD",
332         "SOREG",
333         "STARNM",
334         "STARREG",
335         "INTEMP",
336         "FORARG",
337         "SWADD",
338         0,
ragge
1.72
339 };
ragge
1.1
340
ragge
1.2
341 /*
342  * print a nice-looking description of cookie
343  */
ragge
1.70
344 char *
ragge
1.2
345 prcook(int cookie)
346 {
ragge
1.70
347         static char buf[50];
ragge
1.1
348         int iflag;
349
ragge
1.70
350         if (cookie & SPECIAL) {
351                 switch (cookie) {
352                 case SZERO:
353                         return "SZERO";
354                 case SONE:
355                         return "SONE";
356                 case SMONE:
357                         return "SMONE";
358                 default:
ragge
1.200
359                         snprintf(bufsizeof(buf), "SPECIAL+%d"cookie & ~SPECIAL);
ragge
1.70
360                         return buf;
ragge
1.1
361                 }
ragge
1.70
362         }
ragge
1.1
363
364         flag = 0;
ragge
1.70
365         buf[0] = 0;
366         for (i = 0cnames[i]; ++i) {
367                 if (cookie & (1<<i)) {
368                         if (flag)
ragge
1.200
369                                 strlcat(buf"|"sizeof(buf));
ragge
1.1
370                         ++flag;
ragge
1.200
371                         strlcat(bufcnames[i], sizeof(buf));
ragge
1.1
372                 }
ragge
1.70
373         }
374         return buf;
375 }
ragge
1.1
376
ragge
1.30
377 #endif
ragge
1.1
378
379 int odebug = 0;
380
ragge
1.151
381 int
ragge
1.69
382 geninsn(NODE *pint cookie)
383 {
ragge
1.71
384         NODE *p1, *p2;
ragge
1.151
385         int orv = 0;
ragge
1.69
386
387 #ifdef PCC_DEBUG
388         if (odebug) {
ragge
1.70
389                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
390                 fwalk(pe2print0);
391         }
392 #endif
393
394 again:  switch (o = p->n_op) {
ragge
1.71
395         case EQ:
396         case NE:
397         case LE:
398         case LT:
399         case GE:
400         case GT:
401         case ULE:
402         case ULT:
403         case UGE:
404         case UGT:
gmcgarry
1.208
405                 p1 = p->n_left;
406                 p2 = p->n_right;
ragge
1.210
407                 if (p2->n_op == ICON && p2->n_lval == 0 &&
408                     optype(p1->n_op) == BITYPE) {
gmcgarry
1.208
409                         if (findops(p1FORCC) == 0)
410                                 break;
411                 }
ragge
1.159
412                 rv = relops(p);
413                 break;
ragge
1.71
414
ragge
1.69
415         case PLUS:
416         case MINUS:
417         case MUL:
418         case DIV:
419         case MOD:
420         case AND:
421         case OR:
422         case ER:
423         case LS:
424         case RS:
ragge
1.151
425                 rv = findops(pcookie);
426                 break;
ragge
1.77
427
ragge
1.69
428         case ASSIGN:
ragge
1.174
429         case STASG:
ragge
1.151
430                 rv = findasg(pcookie);
431                 break;
ragge
1.159
432
ragge
1.178
433         case UMUL/* May turn into an OREG */
ragge
1.179
434                 rv = findumul(pcookie);
435                 break;
436
ragge
1.69
437         case REG:
ragge
1.144
438         case TEMP:
ragge
1.72
439         case NAME:
ragge
1.71
440         case ICON:
ragge
1.213
441         case FCON:
ragge
1.69
442         case OREG:
ragge
1.152
443                 rv = findleaf(pcookie);
444                 break;
ragge
1.69
445
ragge
1.172
446         case STCALL:
447         case CALL:
448                 /* CALL arguments are handled special */
449                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
450                         geninsn(p1->n_rightFOREFF);
451                 geninsn(p1FOREFF);
452                 /* FALLTHROUGH */
ragge
1.206
453         case FLD:
ragge
1.86
454         case COMPL:
ragge
1.85
455         case UMINUS:
ragge
1.71
456         case PCONV:
457         case SCONV:
ragge
1.198
458 /*      case INIT: */
ragge
1.70
459         case GOTO:
460         case FUNARG:
ragge
1.172
461         case STARG:
ragge
1.72
462         case UCALL:
ragge
1.103
463         case USTCALL:
ragge
1.207
464         case ADDROF:
ragge
1.155
465                 rv = finduni(pcookie);
466                 break;
ragge
1.69
467
ragge
1.71
468         case CBRANCH:
469                 p1 = p->n_left;
470                 p2 = p->n_right;
471                 p1->n_label = p2->n_lval;
472                 geninsn(p1FORCC);
ragge
1.187
473                 p->n_su = 0;
ragge
1.71
474                 break;
475
ragge
1.187
476         case FORCE/* XXX needed? */
ragge
1.151
477                 geninsn(p->n_leftINREGS);
ragge
1.187
478                 p->n_su = 0/* su calculations traverse left */
ragge
1.71
479                 break;
480
ragge
1.216
481         case XASM:
482                 for (p1 = p->n_leftp1->n_op == CMp1 = p1->n_left)
483                         geninsn(p1->n_rightFOREFF);
484                 geninsn(p1FOREFF);
485                 break;  /* all stuff already done? */
486
487         case XARG:
488                 /* generate code for correct class here */
ragge
1.221
489 //              geninsn(p->n_left, 1 << p->n_label);
ragge
1.216
490                 break;
491
ragge
1.69
492         default:
ragge
1.174
493                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
494         }
ragge
1.160
495         if (rv == FFAIL)
496                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
497         if (rv == FRETRY)
498                 goto again;
ragge
1.153
499         return rv;
ragge
1.69
500 }
501
ragge
1.72
502 /*
503  * Store a given subtree in a temporary location.
504  * Return an OREG node where it is located.
505  */
506 NODE *
507 store(NODE *p)
ragge
1.2
508 {
ragge
1.130
509         extern struct interpass *storesave;
510         struct interpass *ip;
511         NODE *q, *r;
512         int s;
ragge
1.49
513
ragge
1.130
514         s = BITOOR(freetemp(szty(p->n_type)));
515         q = mklnode(OREGsFPREGp->n_type);
516         r = mklnode(OREGsFPREGp->n_type);
517         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
518
ragge
1.149
519         storesave = ip;
ragge
1.72
520         return r;
ragge
1.8
521 }
ragge
1.1
522
ragge
1.170
523 #ifdef PCC_DEBUG
524 #define CDEBUG(x) if (c2debug) printf x
525 #else
526 #define CDEBUG(x)
527 #endif
528
ragge
1.69
529 /*
ragge
1.188
530  * Do a register-register move if necessary.
531  */
532 static void
533 ckmove(NODE *pNODE *q)
534 {
ragge
1.189
535         if (q->n_op != REG || p->n_reg == -1)
ragge
1.188
536                 return/* no register */
537         if (DECRA(p->n_reg0) == DECRA(q->n_reg0))
538                 return/* no move necessary */
ragge
1.190
539         CDEBUG(("rmove: node %p, %s -> %s\n"prnames[DECRA(q->n_reg0)],
540             rnames[DECRA(p->n_reg0)]));
ragge
1.188
541         rmove(DECRA(q->n_reg0), DECRA(p->n_reg0), p->n_type);
542         q->n_reg = q->n_rval = DECRA(p->n_reg0);
543 }
544
545 /*
546  * Rewrite node to register after instruction emit.
ragge
1.75
547  */
548 static void
gmcgarry
1.224
549 rewrite(NODE *pint dorewriteint cookie)
ragge
1.75
550 {
ragge
1.79
551         NODE *l, *r;
552         int o;
553
ragge
1.80
554         l = getlr(p'L');
555         r = getlr(p'R');
ragge
1.79
556         o = p->n_op;
ragge
1.75
557         p->n_op = REG;
ragge
1.76
558         p->n_lval = 0;
ragge
1.95
559         p->n_name = "";
ragge
1.158
560
ragge
1.190
561         if (o == ASSIGN) {
562                 /* special rewrite care */
563                 int reg = DECRA(p->n_reg0);
ragge
1.191
564 #define TL(x) (TBLIDX(x->n_su) || x->n_op == REG)
ragge
1.190
565                 if (p->n_reg == -1)
566                         ;
ragge
1.191
567                 else if (TL(l) && (DECRA(l->n_reg0) == reg))
ragge
1.190
568                         ;
ragge
1.191
569                 else if (TL(r) && (DECRA(r->n_reg0) == reg))
ragge
1.190
570                         ;
ragge
1.191
571                 else if (TL(l))
ragge
1.190
572                         rmove(DECRA(l->n_reg0), regp->n_type);
ragge
1.191
573                 else if (TL(r))
ragge
1.190
574                         rmove(DECRA(r->n_reg0), regp->n_type);
575 #if 0
576                 else
577                         comperr("rewrite");
578 #endif
ragge
1.191
579 #undef TL
ragge
1.190
580         }
ragge
1.79
581         if (optype(o) != LTYPE)
582                 tfree(l);
583         if (optype(o) == BITYPE)
584                 tfree(r);
gmcgarry
1.224
585         if (dorewrite == 0)
ragge
1.190
586                 return;
mickey
1.205
587         CDEBUG(("rewrite: %p, reg %s\n"p,
588             p->n_reg == -1"<none>" : rnames[DECRA(p->n_reg0)]));
ragge
1.187
589         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
590 }
591
ragge
1.228
592 #ifndef XASM_TARGARG
593 #define XASM_TARGARG(x,y) 0
594 #endif
595
ragge
1.216
596 /*
597  * printout extended assembler.
598  */
599 void
600 genxasm(NODE *p)
601 {
602         NODE *q, **nary;
603         int n = 1o = 0;
604         char *w;
605
ragge
1.228
606         if (p->n_left->n_op != ICON || p->n_left->n_type != STRTY) {
607                 for (q = p->n_leftq->n_op == CMq = q->n_left)
608                         n++;
609                 nary = tmpalloc(sizeof(NODE *)*n);
610                 o = n;
611                 for (q = p->n_leftq->n_op == CMq = q->n_left) {
612                         gencode(q->n_right->n_leftINREGS);
613                         nary[--o] = q->n_right;
614                 }
615                 gencode(q->n_leftINREGS);
616                 nary[--o] = q;
617         } else
618                 nary = 0;
ragge
1.216
619
620         w = p->n_name;
621         putchar('\t');
622         while (*w != 0) {
623                 if (*w == '%') {
ragge
1.225
624                         if (w[1] == '%')
625                                 putchar('%');
ragge
1.228
626                         else if (XASM_TARGARG(wnary))
627                                 ; /* handled by target */
ragge
1.225
628                         else if (w[1] < '0' || w[1] > (n + '0'))
ragge
1.228
629                                 uerror("bad xasm arg number %c"w[1]);
ragge
1.216
630                         else
ragge
1.221
631                                 adrput(stdoutnary[(int)w[1]-'0']->n_left);
ragge
1.216
632                         w++;
ragge
1.228
633                 } else if (*w == '\\') { /* Always 3-digit octal */
634                         int num = *++w - '0';
635                         num = (num << 3) + *++w - '0';
636                         num = (num << 3) + *++w - '0';
637                         putchar(num);
ragge
1.216
638                 } else
639                         putchar(*w);
640                 w++;
641         }
642         putchar('\n');
643 }
644
ragge
1.69
645 void
ragge
1.72
646 gencode(NODE *pint cookie)
ragge
1.69
647 {
648         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
649         NODE *p1, *l, *r;
ragge
1.190
650         int o = optype(p->n_op);
ragge
1.188
651
652         l = p->n_left;
653         r = p->n_right;
ragge
1.69
654
ragge
1.186
655         if (TBLIDX(p->n_su) == 0) {
656                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
657                         gencode(r0);
ragge
1.185
658                 if (optype(p->n_op) != LTYPE)
ragge
1.188
659                         gencode(l0);
ragge
1.186
660                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
661                         gencode(r0);
ragge
1.185
662                 return;
663         }
ragge
1.69
664
ragge
1.170
665         CDEBUG(("gencode: node %p\n"p));
666
667         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
668                 return/* meaningless move to itself */
ragge
1.175
669
670         if (callop(p->n_op))
671                 lastcall(p); /* last chance before function args */
672         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
673                 /* Print out arguments first */
ragge
1.188
674                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
675                         gencode(p1->n_rightFOREFF);
676                 gencode(p1FOREFF);
ragge
1.190
677                 o = UTYPE/* avoid going down again */
ragge
1.175
678         }
679
ragge
1.190
680         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
681                 gencode(rINREGS);
682                 if (q->rewrite & RRIGHT)
683                         ckmove(pr);
684         }
ragge
1.190
685         if (o != LTYPE) {
ragge
1.188
686                 gencode(lINREGS);
687                 if (q->rewrite & RLEFT)
688                         ckmove(pl);
689         }
ragge
1.190
690         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
691                 gencode(rINREGS);
692                 if (q->rewrite & RRIGHT)
693                         ckmove(pr);
694         }
ragge
1.185
695
ragge
1.188
696         canon(p);
ragge
1.185
697
ragge
1.188
698         if (q->needs & NSPECIAL) {
699                 int rr = rspecial(qNRIGHT);
700                 int lr = rspecial(qNLEFT);
ragge
1.187
701
ragge
1.188
702                 if (rr >= 0) {
gmcgarry
1.211
703 #ifdef PCC_DEBUG
704                         if (optype(p->n_op) != BITYPE)
705                                 comperr("gencode: rspecial borked");
706 #endif
ragge
1.188
707                         if (r->n_op != REG)
708                                 comperr("gencode: rop != REG");
709                         if (rr != r->n_rval)
710                                 rmove(r->n_rvalrrr->n_type);
711                         r->n_rval = r->n_reg = rr;
712                 }
713                 if (lr >= 0) {
714                         if (l->n_op != REG)
ragge
1.192
715                                 comperr("gencode: %p lop != REG"p);
ragge
1.188
716                         if (lr != l->n_rval)
717                                 rmove(l->n_rvallrl->n_type);
718                         l->n_rval = l->n_reg = lr;
719                 }
720                 if (rr >= 0 && lr >= 0 && (l->n_reg == rr || r->n_reg == lr))
721                         comperr("gencode: cross-reg-move");
722         }
ragge
1.161
723
ragge
1.162
724         if (p->n_op == ASSIGN &&
725             p->n_left->n_op == REG && p->n_right->n_op == REG &&
726             p->n_left->n_rval == p->n_right->n_rval){
ragge
1.161
727                 /* do not emit anything */
ragge
1.170
728                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
729                 rewrite(pq->rewritecookie);
730                 return;
731         }
ragge
1.147
732
ragge
1.170
733         CDEBUG(("emitting node %p\n"p));
ragge
1.190
734         if (TBLIDX(p->n_su) == 0)
ragge
1.173
735                 return;
ragge
1.170
736
ragge
1.72
737         expand(pcookieq->cstring);
ragge
1.169
738         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
739             DECRA(p->n_reg0) != RETREG(p->n_type)) {
740                 CDEBUG(("gencode(%p) retreg\n"p));
741                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
742         } else if (q->needs & NSPECIAL) {
ragge
1.158
743                 int rr = rspecial(qNRES);
ragge
1.150
744
ragge
1.188
745                 if (rr >= 0 && DECRA(p->n_reg0) != rr) {
ragge
1.170
746                         CDEBUG(("gencode(%p) nspec retreg\n"p));
747                         rmove(rrDECRA(p->n_reg0), p->n_type);
748                 }
ragge
1.162
749         } else if ((q->rewrite & RESC1) &&
ragge
1.170
750             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
751                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
752                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.190
753         }
754 #if 0
755                 /* XXX - kolla upp det här */
756            else if (p->n_op == ASSIGN) {
ragge
1.176
757                 /* may need move added if RLEFT/RRIGHT */
758                 /* XXX should be handled in sucomp() */
759                 if ((q->rewrite & RLEFT) && (p->n_left->n_op == REG) &&
760                     (p->n_left->n_rval != DECRA(p->n_reg0)) &&
761                     TCLASS(p->n_su)) {
762                         rmove(p->n_left->n_rvalDECRA(p->n_reg0), p->n_type);
763                 } else if ((q->rewrite & RRIGHT) && (p->n_right->n_op == REG) &&
764                     (p->n_right->n_rval != DECRA(p->n_reg0)) &&
765                     TCLASS(p->n_su)) {
766                         rmove(p->n_right->n_rvalDECRA(p->n_reg0), p->n_type);
767                 }
ragge
1.149
768         }
ragge
1.190
769 #endif
ragge
1.160
770         rewrite(pq->rewritecookie);
ragge
1.2
771 }
ragge
1.1
772
773 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
ragge
1.204
774 size_t negrelsize = sizeof negrel / sizeof negrel[0];
ragge
1.1
775
ragge
1.30
776 #ifdef PCC_DEBUG
ragge
1.87
777 #undef  PRTABLE
ragge
1.174
778 void
ragge
1.8
779 e2print(NODE *pint downint *aint *b)
ragge
1.2
780 {
ragge
1.85
781 #ifdef PRTABLE
782         extern int tablesize;
783 #endif
ragge
1.1
784
ragge
1.197
785         prfil = stdout;
ragge
1.1
786         *a = *b = down+1;
787         whiledown >= 2 ){
ragge
1.148
788                 fprintf(prfil"\t");
ragge
1.1
789                 down -= 2;
790                 }
ragge
1.148
791         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
792
793
ragge
1.148
794         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
795         switchp->n_op ) { /* special cases */
ragge
1.1
796
797         case REG:
ragge
1.148
798                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
799                 break;
800
ragge
1.121
801         case TEMP:
ragge
1.214
802                 fprintf(prfil" %d"regno(p));
ragge
1.121
803                 break;
804
ragge
1.216
805         case XASM:
806         case XARG:
807                 fprintf(prfil" '%s'"p->n_name);
808                 break;
809
ragge
1.1
810         case ICON:
811         case NAME:
812         case OREG:
ragge
1.148
813                 fprintf(prfil" " );
814                 adrput(prfilp );
ragge
1.1
815                 break;
816
817         case STCALL:
ragge
1.68
818         case USTCALL:
ragge
1.1
819         case STARG:
820         case STASG:
ragge
1.148
821                 fprintf(prfil" size=%d"p->n_stsize );
822                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
823                 break;
824                 }
825
ragge
1.148
826         fprintf(prfil", " );
827         tprint(prfilp->n_typep->n_qual);
828         fprintf(prfil", " );
ragge
1.215
829
830         prtreg(prfilp);
ragge
1.151
831         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
ragge
1.85
832             TBLIDX(p->n_su), 
ragge
1.151
833             TCLASS(p->n_su)+'@',
ragge
1.85
834 #ifdef PRTABLE
835             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
836             table[TBLIDX(p->n_su)].cstring : "",
837 #else
838             "",
839 #endif
840             ltyp[LMASK&p->n_su],
ragge
1.70
841             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
842 }
ragge
1.30
843 #endif
ragge
1.1
844
845 #ifndef FIELDOPS
ragge
1.7
846 /*
847  * do this if there is no special hardware support for fields
848  */
ragge
1.174
849 static void
ragge
1.7
850 ffld(NODE *pint downint *down1int *down2 )
851 {
852         /*
853          * look for fields that are not in an lvalue context,
854          * and rewrite them...
855          */
856         NODE *shp;
857         int sovty;
ragge
1.1
858
ragge
1.13
859         *down1 =  asgopp->n_op );
ragge
1.1
860         *down2 = 0;
861
ragge
1.13
862         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
863
ragge
1.174
864                 if( !rewfld(p) ) return;
ragge
1.1
865
ragge
1.173
866                 ty = p->n_type;
ragge
1.13
867                 v = p->n_rval;
ragge
1.1
868                 s = UPKFSZ(v);
869 # ifdef RTOLBYTES
870                 o = UPKFOFF(v);  /* amount to shift */
871 # else
ragge
1.13
872                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
873 #endif
874
875                 /* make & mask part */
876
ragge
1.203
877                 if (ISUNSIGNED(ty)) {
ragge
1.1
878
ragge
1.203
879                         p->n_left->n_type = ty;
880                         p->n_op = AND;
881                         p->n_right = mklnode(ICON, ((CONSZ)1 << s)-10ty);
882
883                         /* now, if a shift is needed, do it */
884                         ifo != 0 ){
885                                 shp = mkbinode(RSp->n_left,
886                                     mklnode(ICONo0INT), ty);
887                                 p->n_left = shp;