Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081005080652

Diff

Diff from 1.238 to:

Annotations

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

Annotated File View

ragge
1.238
1 /*      $Id: reader.c,v 1.238 2008/10/05 08:06:52 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.236
64  * Everything is entered via pass2_compile().  No functions are 
65  * allowed to recurse back into pass2_compile().
ragge
1.123
66  */
67
ragge
1.1
68 # include "pass2.h"
69
ragge
1.70
70 #include <string.h>
ragge
1.71
71 #include <stdarg.h>
ragge
1.94
72 #include <stdlib.h>
ragge
1.70
73
ragge
1.1
74 /*      some storage declarations */
75 int nrecur;
76 int lflag;
ragge
1.9
77 int x2debug;
ragge
1.1
78 int udebug = 0;
ragge
1.103
79 int thisline;
ragge
1.72
80 int fregs;
ragge
1.123
81 int p2autooffp2maxautooff;
ragge
1.1
82
ragge
1.72
83 NODE *nodepole;
ragge
1.197
84 FILE *prfil;
ragge
1.238
85 struct interpass prepole;
ragge
1.23
86
ragge
1.37
87 void saveip(struct interpass *ip);
ragge
1.40
88 void deltemp(NODE *p);
ragge
1.232
89 static void cvtemps(struct interpass *ipoleint opint off);
ragge
1.72
90 NODE *store(NODE *);
ragge
1.216
91 static void fixxasm(struct interpass *ip);
ragge
1.65
92
ragge
1.72
93 static void gencode(NODE *pint cookie);
ragge
1.216
94 static void genxasm(NODE *p);
ragge
1.69
95
ragge
1.150
96 char *ltyp[] = { """LREG""LOREG""LTEMP" };
97 char *rtyp[] = { """RREG""ROREG""RTEMP" };
ragge
1.37
98
ragge
1.121
99 /* used when removing nodes */
100 struct tmpsave {
101         struct tmpsave *next;
102         CONSZ tempaddr;
103         int tempno;
104 } *tmpsave;
105
ragge
1.26
106 #ifdef PCC_DEBUG
107 static void
108 cktree(NODE *p)
109 {
110         if (p->n_op > MAXOP)
ragge
1.218
111                 cerror("%p) op %d slipped through"pp->n_op);
ragge
1.199
112         if (BTYPE(p->n_type) > MAXTYPES)
ragge
1.218
113                 cerror("%p) type %x slipped through"pp->n_type);
ragge
1.35
114         if (p->n_op == CBRANCH && !logop(p->n_left->n_op))
ragge
1.218
115                 cerror("%p) not logop branch"p);
ragge
1.47
116         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
ragge
1.218
117                 cerror("%p) asgop %d slipped through"pp->n_op);
ragge
1.26
118 }
119 #endif
ragge
1.8
120
ragge
1.130
121 /*
ragge
1.89
122  * Check if a node has side effects.
123  */
124 static int
125 isuseless(NODE *n)
126 {
127         switch (n->n_op) {
ragge
1.216
128         case XASM:
ragge
1.89
129         case FUNARG:
130         case UCALL:
131         case UFORTCALL:
132         case FORCE:
133         case ASSIGN:
134         case CALL:
135         case FORTCALL:
136         case CBRANCH:
137         case RETURN:
138         case GOTO:
139         case STCALL:
140         case USTCALL:
141         case STASG:
142         case STARG:
143                 return 0;
144         default:
145                 return 1;
146         }
147 }
148
ragge
1.130
149 /*
150  * Delete statements with no meaning (like a+b; or 513.4;)
151  */
ragge
1.238
152 NODE *
ragge
1.89
153 deluseless(NODE *p)
154 {
155         struct interpass *ip;
156         NODE *l, *r;
157
158         if (optype(p->n_op) == LTYPE) {
159                 nfree(p);
160                 return NULL;
161         }
162         if (isuseless(p) == 0)
163                 return p;
164
165         if (optype(p->n_op) == UTYPE) {
166                 l = p->n_left;
167                 nfree(p);
168                 return deluseless(l);
169         }
170
171         /* Be sure that both leaves may be valid */
172         l = deluseless(p->n_left);
173         r = deluseless(p->n_right);
174         nfree(p);
175         if (l && r) {
ragge
1.201
176                 ip = ipnode(l);
177                 DLIST_INSERT_AFTER(&prepoleipqelem);
ragge
1.89
178                 return r;
179         } else if (l)
180                 return l;
181         else if (r)
182                 return r;
183         return NULL;
184 }
185
ragge
1.172
186 static struct interpass ipole;
ragge
1.174
187 struct interpass_prolog *ipp, *epp;
ragge
1.172
188
189 /*
190  * Receives interpass structs from pass1.
191  */
192 void
193 pass2_compile(struct interpass *ip)
194 {
195         if (ip->type == IP_PROLOG) {
196                 tmpsave = NULL;
ragge
1.174
197                 ipp = (struct interpass_prolog *)ip;
ragge
1.172
198                 DLIST_INIT(&ipoleqelem);
199         }
200         DLIST_INSERT_BEFORE(&ipoleipqelem);
201         if (ip->type != IP_EPILOG)
202                 return;
203
204 #ifdef PCC_DEBUG
205         if (e2debug) {
206                 printf("Entering pass2\n");
207                 printip(&ipole);
208         }
209 #endif
ragge
1.174
210
ragge
1.172
211         epp = (struct interpass_prolog *)DLIST_PREV(&ipoleqelem);
212         p2maxautooff = p2autooff = epp->ipp_autos;
ragge
1.174
213
214         myreader(&ipole); /* local massage of input */
215
ragge
1.172
216         DLIST_FOREACH(ip, &ipoleqelem) {
217                 if (ip->type != IP_NODE)
218                         continue;
219                 if (xtemps == 0)
220                         walkf(ip->ip_nodedeltemp);
221         }
ragge
1.201
222         DLIST_INIT(&prepoleqelem);
ragge
1.172
223         DLIST_FOREACH(ip, &ipoleqelem) {
224                 if (ip->type != IP_NODE)
225                         continue;
226                 canon(ip->ip_node);
gmcgarry
1.220
227 #ifdef PCC_DEBUG
ragge
1.172
228                 walkf(ip->ip_nodecktree);
gmcgarry
1.220
229 #endif
ragge
1.201
230                 if ((ip->ip_node = deluseless(ip->ip_node)) == NULL) {
ragge
1.172
231                         DLIST_REMOVE(ipqelem);
ragge
1.201
232                 } else while (!DLIST_ISEMPTY(&prepoleqelem)) {
gmcgarry
1.224
233                         struct interpass *tipp;
ragge
1.201
234
gmcgarry
1.224
235                         tipp = DLIST_NEXT(&prepoleqelem);
236                         DLIST_REMOVE(tippqelem);
237                         DLIST_INSERT_BEFORE(iptippqelem);
ragge
1.201
238                 }
ragge
1.172
239         }
240
ragge
1.216
241         fixxasm(&ipole); /* setup for extended asm */
242
ragge
1.172
243         optimize(&ipole);
244         ngenregs(&ipole);
245
246         DLIST_FOREACH(ip, &ipoleqelem)
247                 emit(ip);
248 }
249
ragge
1.124
250 void
ragge
1.125
251 emit(struct interpass *ip)
ragge
1.124
252 {
gmcgarry
1.208
253         NODE *p, *r;
254         struct optab *op;
ragge
1.149
255         int o;
ragge
1.124
256
ragge
1.125
257         switch (ip->type) {
258         case IP_NODE:
259                 p = ip->ip_node;
ragge
1.124
260
ragge
1.149
261                 nodepole = p;
ragge
1.180
262 //printf("bu:\n");
263 //fwalk(p, e2print, 0);
264                 canon(p); /* may convert stuff after genregs */
265 //fwalk(p, e2print, 0);
ragge
1.124
266                 switch (p->n_op) {
267                 case CBRANCH:
268                         /* Only emit branch insn if RESCC */
gmcgarry
1.208
269                         /* careful when an OPLOG has been elided */
270                         if (p->n_left->n_su == 0 && p->n_left->n_left != NULL) {
271                                 op = &table[TBLIDX(p->n_left->n_left->n_su)];
272                                 r = p->n_left;
273                         } else {
274                                 op = &table[TBLIDX(p->n_left->n_su)];
275                                 r = p;
276                         }
277                         if (op->rewrite & RESCC) {
ragge
1.124
278                                 o = p->n_left->n_op;
gmcgarry
1.208
279                                 gencode(rFORCC);
ragge
1.124
280                                 cbgen(op->n_right->n_lval);
gmcgarry
1.208
281                         } else {
282                                 gencode(rFORCC);
283                         }
ragge
1.124
284                         break;
285                 case FORCE:
ragge
1.151
286                         gencode(p->n_leftINREGS);
ragge
1.124
287                         break;
ragge
1.216
288                 case XASM:
289                         genxasm(p);
290                         break;
ragge
1.124
291                 default:
292                         if (p->n_op != REG || p->n_type != VOID/* XXX */
293                                 gencode(pFOREFF); /* Emit instructions */
294                 }
295
ragge
1.125
296                 tfree(p);
297                 break;
ragge
1.124
298         case IP_PROLOG:
299                 prologue((struct interpass_prolog *)ip);
300                 break;
301         case IP_EPILOG:
302                 eoftn((struct interpass_prolog *)ip);
303                 tmpsave = NULL/* Always forget old nodes */
ragge
1.174
304                 p2maxautooff = p2autooff = AUTOINIT/SZCHAR;
ragge
1.124
305                 break;
306         case IP_DEFLAB:
307                 deflab(ip->ip_lbl);
308                 break;
309         case IP_ASM:
gmcgarry
1.229
310                 printf("%s"ip->ip_asm);
ragge
1.124
311                 break;
312         default:
ragge
1.216
313                 cerror("emit %d"ip->type);
ragge
1.124
314         }
ragge
1.123
315 }
ragge
1.124
316
ragge
1.30
317 #ifdef PCC_DEBUG
ragge
1.1
318 char *cnames[] = {
319         "SANY",
320         "SAREG",
321         "SBREG",
ragge
1.153
322         "SCREG",
323         "SDREG",
ragge
1.1
324         "SCC",
325         "SNAME",
326         "SCON",
327         "SFLD",
328         "SOREG",
329         "STARNM",
330         "STARREG",
331         "INTEMP",
332         "FORARG",
333         "SWADD",
334         0,
ragge
1.72
335 };
ragge
1.1
336
ragge
1.2
337 /*
338  * print a nice-looking description of cookie
339  */
ragge
1.70
340 char *
ragge
1.2
341 prcook(int cookie)
342 {
ragge
1.70
343         static char buf[50];
ragge
1.1
344         int iflag;
345
ragge
1.70
346         if (cookie & SPECIAL) {
347                 switch (cookie) {
348                 case SZERO:
349                         return "SZERO";
350                 case SONE:
351                         return "SONE";
352                 case SMONE:
353                         return "SMONE";
354                 default:
ragge
1.200
355                         snprintf(bufsizeof(buf), "SPECIAL+%d"cookie & ~SPECIAL);
ragge
1.70
356                         return buf;
ragge
1.1
357                 }
ragge
1.70
358         }
ragge
1.1
359
360         flag = 0;
ragge
1.70
361         buf[0] = 0;
362         for (i = 0cnames[i]; ++i) {
363                 if (cookie & (1<<i)) {
364                         if (flag)
ragge
1.200
365                                 strlcat(buf"|"sizeof(buf));
ragge
1.1
366                         ++flag;
ragge
1.200
367                         strlcat(bufcnames[i], sizeof(buf));
ragge
1.1
368                 }
ragge
1.70
369         }
370         return buf;
371 }
ragge
1.1
372
ragge
1.30
373 #endif
ragge
1.1
374
375 int odebug = 0;
376
ragge
1.151
377 int
ragge
1.69
378 geninsn(NODE *pint cookie)
379 {
ragge
1.71
380         NODE *p1, *p2;
ragge
1.236
381         int qorv = 0;
ragge
1.69
382
383 #ifdef PCC_DEBUG
384         if (odebug) {
ragge
1.70
385                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
386                 fwalk(pe2print0);
387         }
388 #endif
389
ragge
1.236
390         q = cookie & QUIET;
391         cookie &= ~QUIET/* XXX - should not be necessary */
392
ragge
1.69
393 again:  switch (o = p->n_op) {
ragge
1.71
394         case EQ:
395         case NE:
396         case LE:
397         case LT:
398         case GE:
399         case GT:
400         case ULE:
401         case ULT:
402         case UGE:
403         case UGT:
gmcgarry
1.208
404                 p1 = p->n_left;
405                 p2 = p->n_right;
ragge
1.210
406                 if (p2->n_op == ICON && p2->n_lval == 0 &&
407                     optype(p1->n_op) == BITYPE) {
ragge
1.236
408 #ifdef mach_pdp11 /* XXX all targets? */
409                         if ((rv = geninsn(p1FORCC|QUIET)) != FFAIL)
410                                 break;
411 #else
412                         if (findops(p1FORCC) > 0)
gmcgarry
1.208
413                                 break;
ragge
1.236
414 #endif
gmcgarry
1.208
415                 }
ragge
1.159
416                 rv = relops(p);
417                 break;
ragge
1.71
418
ragge
1.69
419         case PLUS:
420         case MINUS:
421         case MUL:
422         case DIV:
423         case MOD:
424         case AND:
425         case OR:
426         case ER:
427         case LS:
428         case RS:
ragge
1.151
429                 rv = findops(pcookie);
430                 break;
ragge
1.77
431
ragge
1.69
432         case ASSIGN:
ragge
1.236
433 #ifdef FINDMOPS
434                 if ((rv = findmops(pcookie)) != FFAIL)
435                         break;
436                 /* FALLTHROUGH */
437 #endif
ragge
1.174
438         case STASG:
ragge
1.151
439                 rv = findasg(pcookie);
440                 break;
ragge
1.159
441
ragge
1.178
442         case UMUL/* May turn into an OREG */
ragge
1.179
443                 rv = findumul(pcookie);
444                 break;
445
ragge
1.69
446         case REG:
ragge
1.144
447         case TEMP:
ragge
1.72
448         case NAME:
ragge
1.71
449         case ICON:
ragge
1.213
450         case FCON:
ragge
1.69
451         case OREG:
ragge
1.152
452                 rv = findleaf(pcookie);
453                 break;
ragge
1.69
454
ragge
1.172
455         case STCALL:
456         case CALL:
457                 /* CALL arguments are handled special */
458                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
459                         geninsn(p1->n_rightFOREFF);
460                 geninsn(p1FOREFF);
461                 /* FALLTHROUGH */
ragge
1.206
462         case FLD:
ragge
1.86
463         case COMPL:
ragge
1.85
464         case UMINUS:
ragge
1.71
465         case PCONV:
466         case SCONV:
ragge
1.198
467 /*      case INIT: */
ragge
1.70
468         case GOTO:
469         case FUNARG:
ragge
1.172
470         case STARG:
ragge
1.72
471         case UCALL:
ragge
1.103
472         case USTCALL:
ragge
1.207
473         case ADDROF:
ragge
1.155
474                 rv = finduni(pcookie);
475                 break;
ragge
1.69
476
ragge
1.71
477         case CBRANCH:
478                 p1 = p->n_left;
479                 p2 = p->n_right;
480                 p1->n_label = p2->n_lval;
481                 geninsn(p1FORCC);
ragge
1.187
482                 p->n_su = 0;
ragge
1.71
483                 break;
484
ragge
1.187
485         case FORCE/* XXX needed? */
ragge
1.151
486                 geninsn(p->n_leftINREGS);
ragge
1.187
487                 p->n_su = 0/* su calculations traverse left */
ragge
1.71
488                 break;
489
ragge
1.216
490         case XASM:
491                 for (p1 = p->n_leftp1->n_op == CMp1 = p1->n_left)
492                         geninsn(p1->n_rightFOREFF);
493                 geninsn(p1FOREFF);
494                 break;  /* all stuff already done? */
495
496         case XARG:
497                 /* generate code for correct class here */
ragge
1.221
498 //              geninsn(p->n_left, 1 << p->n_label);
ragge
1.216
499                 break;
500
ragge
1.69
501         default:
ragge
1.174
502                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
503         }
ragge
1.236
504         if (rv == FFAIL && !q)
ragge
1.160
505                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
506         if (rv == FRETRY)
507                 goto again;
ragge
1.236
508 #ifdef PCC_DEBUG
509         if (odebug) {
510                 printf("geninsn(%p, %s) rv %d\n"pprcook(cookie), rv);
511                 fwalk(pe2print0);
512         }
513 #endif
ragge
1.153
514         return rv;
ragge
1.69
515 }
516
ragge
1.72
517 /*
518  * Store a given subtree in a temporary location.
519  * Return an OREG node where it is located.
520  */
521 NODE *
522 store(NODE *p)
ragge
1.2
523 {
ragge
1.130
524         extern struct interpass *storesave;
525         struct interpass *ip;
526         NODE *q, *r;
527         int s;
ragge
1.49
528
ragge
1.130
529         s = BITOOR(freetemp(szty(p->n_type)));
530         q = mklnode(OREGsFPREGp->n_type);
531         r = mklnode(OREGsFPREGp->n_type);
532         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
533
ragge
1.149
534         storesave = ip;
ragge
1.72
535         return r;
ragge
1.8
536 }
ragge
1.1
537
ragge
1.170
538 #ifdef PCC_DEBUG
539 #define CDEBUG(x) if (c2debug) printf x
540 #else
541 #define CDEBUG(x)
542 #endif
543
ragge
1.69
544 /*
ragge
1.188
545  * Do a register-register move if necessary.
546  */
547 static void
548 ckmove(NODE *pNODE *q)
549 {
ragge
1.189
550         if (q->n_op != REG || p->n_reg == -1)
ragge
1.188
551                 return/* no register */
552         if (DECRA(p->n_reg0) == DECRA(q->n_reg0))
553                 return/* no move necessary */
ragge
1.190
554         CDEBUG(("rmove: node %p, %s -> %s\n"prnames[DECRA(q->n_reg0)],
555             rnames[DECRA(p->n_reg0)]));
ragge
1.188
556         rmove(DECRA(q->n_reg0), DECRA(p->n_reg0), p->n_type);
557         q->n_reg = q->n_rval = DECRA(p->n_reg0);
558 }
559
560 /*
561  * Rewrite node to register after instruction emit.
ragge
1.75
562  */
563 static void
gmcgarry
1.224
564 rewrite(NODE *pint dorewriteint cookie)
ragge
1.75
565 {
ragge
1.79
566         NODE *l, *r;
567         int o;
568
ragge
1.80
569         l = getlr(p'L');
570         r = getlr(p'R');
ragge
1.79
571         o = p->n_op;
ragge
1.75
572         p->n_op = REG;
ragge
1.76
573         p->n_lval = 0;
ragge
1.95
574         p->n_name = "";
ragge
1.158
575
ragge
1.190
576         if (o == ASSIGN) {
577                 /* special rewrite care */
578                 int reg = DECRA(p->n_reg0);
ragge
1.191
579 #define TL(x) (TBLIDX(x->n_su) || x->n_op == REG)
ragge
1.190
580                 if (p->n_reg == -1)
581                         ;
ragge
1.191
582                 else if (TL(l) && (DECRA(l->n_reg0) == reg))
ragge
1.190
583                         ;
ragge
1.191
584                 else if (TL(r) && (DECRA(r->n_reg0) == reg))
ragge
1.190
585                         ;
ragge
1.191
586                 else if (TL(l))
ragge
1.190
587                         rmove(DECRA(l->n_reg0), regp->n_type);
ragge
1.191
588                 else if (TL(r))
ragge
1.190
589                         rmove(DECRA(r->n_reg0), regp->n_type);
590 #if 0
591                 else
592                         comperr("rewrite");
593 #endif
ragge
1.191
594 #undef TL
ragge
1.190
595         }
ragge
1.79
596         if (optype(o) != LTYPE)
597                 tfree(l);
598         if (optype(o) == BITYPE)
599                 tfree(r);
gmcgarry
1.224
600         if (dorewrite == 0)
ragge
1.190
601                 return;
mickey
1.205
602         CDEBUG(("rewrite: %p, reg %s\n"p,
603             p->n_reg == -1"<none>" : rnames[DECRA(p->n_reg0)]));
ragge
1.187
604         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
605 }
606
ragge
1.228
607 #ifndef XASM_TARGARG
608 #define XASM_TARGARG(x,y) 0
609 #endif
610
ragge
1.216
611 /*
612  * printout extended assembler.
613  */
614 void
615 genxasm(NODE *p)
616 {
617         NODE *q, **nary;
618         int n = 1o = 0;
619         char *w;
620
ragge
1.228
621         if (p->n_left->n_op != ICON || p->n_left->n_type != STRTY) {
622                 for (q = p->n_leftq->n_op == CMq = q->n_left)
623                         n++;
624                 nary = tmpalloc(sizeof(NODE *)*n);
625                 o = n;
626                 for (q = p->n_leftq->n_op == CMq = q->n_left) {
627                         gencode(q->n_right->n_leftINREGS);
628                         nary[--o] = q->n_right;
629                 }
630                 gencode(q->n_leftINREGS);
631                 nary[--o] = q;
632         } else
633                 nary = 0;
ragge
1.216
634
635         w = p->n_name;
636         putchar('\t');
637         while (*w != 0) {
638                 if (*w == '%') {
ragge
1.225
639                         if (w[1] == '%')
640                                 putchar('%');
ragge
1.228
641                         else if (XASM_TARGARG(wnary))
642                                 ; /* handled by target */
ragge
1.225
643                         else if (w[1] < '0' || w[1] > (n + '0'))
ragge
1.228
644                                 uerror("bad xasm arg number %c"w[1]);
ragge
1.216
645                         else
ragge
1.221
646                                 adrput(stdoutnary[(int)w[1]-'0']->n_left);
ragge
1.216
647                         w++;
ragge
1.228
648                 } else if (*w == '\\') { /* Always 3-digit octal */
649                         int num = *++w - '0';
650                         num = (num << 3) + *++w - '0';
651                         num = (num << 3) + *++w - '0';
652                         putchar(num);
ragge
1.216
653                 } else
654                         putchar(*w);
655                 w++;
656         }
657         putchar('\n');
658 }
659
ragge
1.69
660 void
ragge
1.72
661 gencode(NODE *pint cookie)
ragge
1.69
662 {
663         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
664         NODE *p1, *l, *r;
ragge
1.190
665         int o = optype(p->n_op);
ragge
1.188
666
667         l = p->n_left;
668         r = p->n_right;
ragge
1.69
669
ragge
1.186
670         if (TBLIDX(p->n_su) == 0) {
671                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
672                         gencode(r0);
ragge
1.185
673                 if (optype(p->n_op) != LTYPE)
ragge
1.188
674                         gencode(l0);
ragge
1.186
675                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
676                         gencode(r0);
ragge
1.185
677                 return;
678         }
ragge
1.69
679
ragge
1.170
680         CDEBUG(("gencode: node %p\n"p));
681
682         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
683                 return/* meaningless move to itself */
ragge
1.175
684
685         if (callop(p->n_op))
686                 lastcall(p); /* last chance before function args */
687         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
688                 /* Print out arguments first */
ragge
1.188
689                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
690                         gencode(p1->n_rightFOREFF);
691                 gencode(p1FOREFF);
ragge
1.190
692                 o = UTYPE/* avoid going down again */
ragge
1.175
693         }
694
ragge
1.190
695         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
696                 gencode(rINREGS);
697                 if (q->rewrite & RRIGHT)
698                         ckmove(pr);
699         }
ragge
1.190
700         if (o != LTYPE) {
ragge
1.188
701                 gencode(lINREGS);
702                 if (q->rewrite & RLEFT)
703                         ckmove(pl);
704         }
ragge
1.190
705         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
706                 gencode(rINREGS);
707                 if (q->rewrite & RRIGHT)
708                         ckmove(pr);
709         }
ragge
1.185
710
ragge
1.236
711 #ifdef FINDMOPS
712         if (p->n_op == ASSIGN && (p->n_flags & 1)) {
713                 /* reduce right tree to make expand() work */
714                 if (optype(r->n_op) != LTYPE) {
715                         r = tcopy(r->n_right);
716                         tfree(p->n_right);
717                         p->n_right = r;
718                 }
719         }
720 #endif
721
ragge
1.188
722         canon(p);
ragge
1.185
723
ragge
1.188
724         if (q->needs & NSPECIAL) {
725                 int rr = rspecial(qNRIGHT);
726                 int lr = rspecial(qNLEFT);
ragge
1.187
727
ragge
1.188
728                 if (rr >= 0) {
gmcgarry
1.211
729 #ifdef PCC_DEBUG
730                         if (optype(p->n_op) != BITYPE)
731                                 comperr("gencode: rspecial borked");
732 #endif
ragge
1.188
733                         if (r->n_op != REG)
734                                 comperr("gencode: rop != REG");
735                         if (rr != r->n_rval)
736                                 rmove(r->n_rvalrrr->n_type);
737                         r->n_rval = r->n_reg = rr;
738                 }
739                 if (lr >= 0) {
740                         if (l->n_op != REG)
ragge
1.192
741                                 comperr("gencode: %p lop != REG"p);
ragge
1.188
742                         if (lr != l->n_rval)
743                                 rmove(l->n_rvallrl->n_type);
744                         l->n_rval = l->n_reg = lr;
745                 }
746                 if (rr >= 0 && lr >= 0 && (l->n_reg == rr || r->n_reg == lr))
747                         comperr("gencode: cross-reg-move");
748         }
ragge
1.161
749
ragge
1.162
750         if (p->n_op == ASSIGN &&
751             p->n_left->n_op == REG && p->n_right->n_op == REG &&
ragge
1.237
752             p->n_left->n_rval == p->n_right->n_rval &&
753             (q->visit & FORCC) == 0) { /* XXX should check if necessary */
ragge
1.161
754                 /* do not emit anything */
ragge
1.170
755                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
756                 rewrite(pq->rewritecookie);
757                 return;
758         }
ragge
1.147
759
ragge
1.170
760         CDEBUG(("emitting node %p\n"p));
ragge
1.190
761         if (TBLIDX(p->n_su) == 0)
ragge
1.173
762                 return;
ragge
1.170
763
ragge
1.72
764         expand(pcookieq->cstring);
ragge
1.169
765         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
766             DECRA(p->n_reg0) != RETREG(p->n_type)) {
767                 CDEBUG(("gencode(%p) retreg\n"p));
768                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
769         } else if (q->needs & NSPECIAL) {
ragge
1.158
770                 int rr = rspecial(qNRES);
ragge
1.150
771
ragge
1.188
772                 if (rr >= 0 && DECRA(p->n_reg0) != rr) {
ragge
1.170
773                         CDEBUG(("gencode(%p) nspec retreg\n"p));
774                         rmove(rrDECRA(p->n_reg0), p->n_type);
775                 }
ragge
1.162
776         } else if ((q->rewrite & RESC1) &&
ragge
1.170
777             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
778                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
779                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.190
780         }
781 #if 0
782                 /* XXX - kolla upp det här */
783            else if (p->n_op == ASSIGN) {
ragge
1.176
784                 /* may need move added if RLEFT/RRIGHT */
785                 /* XXX should be handled in sucomp() */
786                 if ((q->rewrite & RLEFT) && (p->n_left->n_op == REG) &&
787                     (p->n_left->n_rval != DECRA(p->n_reg0)) &&
788                     TCLASS(p->n_su)) {
789                         rmove(p->n_left->n_rvalDECRA(p->n_reg0), p->n_type);
790                 } else if ((q->rewrite & RRIGHT) && (p->n_right->n_op == REG) &&
791                     (p->n_right->n_rval != DECRA(p->n_reg0)) &&
792                     TCLASS(p->n_su)) {
793                         rmove(p->n_right->n_rvalDECRA(p->n_reg0), p->n_type);
794                 }
ragge
1.149
795         }
ragge
1.190
796 #endif
ragge
1.160
797         rewrite(pq->rewritecookie);
ragge
1.2
798 }
ragge
1.1
799
800 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
ragge
1.204
801 size_t negrelsize = sizeof negrel / sizeof negrel[0];
ragge
1.1
802
ragge
1.30
803 #ifdef PCC_DEBUG
ragge
1.87
804 #undef  PRTABLE
ragge
1.174
805 void
ragge
1.8
806 e2print(NODE *pint downint *aint *b)
ragge
1.2
807 {
ragge
1.85
808 #ifdef PRTABLE
809         extern int tablesize;
810 #endif
ragge
1.1
811
ragge
1.197
812         prfil = stdout;
ragge
1.1
813         *a = *b = down+1;
814         whiledown >= 2 ){
ragge
1.148
815                 fprintf(prfil"\t");
ragge
1.1
816                 down -= 2;
817                 }
ragge
1.148
818         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
819
820
ragge
1.148
821         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
822         switchp->n_op ) { /* special cases */
ragge
1.1
823
824         case REG:
ragge
1.148
825                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
826                 break;
827
ragge
1.121
828         case TEMP:
ragge
1.214
829                 fprintf(prfil" %d"regno(p));
ragge
1.121
830                 break;
831
ragge
1.216
832         case XASM:
833         case XARG:
834                 fprintf(prfil" '%s'"p->n_name);
835                 break;
836
ragge
1.1
837         case ICON:
838         case NAME:
839         case OREG:
ragge
1.148
840                 fprintf(prfil" " );
841                 adrput(prfilp );
ragge
1.1
842                 break;
843
844         case STCALL:
ragge
1.68
845         case USTCALL:
ragge
1.1
846         case STARG:
847         case STASG:
ragge
1.148
848                 fprintf(prfil" size=%d"p->n_stsize );
849                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
850                 break;
851                 }
852
ragge
1.148
853         fprintf(prfil", " );
854         tprint(prfilp->n_typep->n_qual);
855         fprintf(prfil", " );
ragge
1.215
856
857         prtreg(prfilp);
ragge
1.151
858         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
ragge
1.85
859             TBLIDX(p->n_su), 
ragge
1.151
860             TCLASS(p->n_su)+'@',
ragge
1.85
861 #ifdef PRTABLE
862             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
863             table[TBLIDX(p->n_su)].cstring : "",
864 #else
865             "",
866 #endif
867             ltyp[LMASK&p->n_su],
ragge
1.70
868             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
869 }
ragge
1.30
870 #endif
ragge
1.1
871
872 #ifndef FIELDOPS
ragge
1.7
873 /*
874  * do this if there is no special hardware support for fields
875  */
ragge
1.174
876 static void
ragge
1.7
877 ffld(NODE *pint downint *down1int *down2 )
878 {
879         /*
880          * look for fields that are not in an lvalue context,
881          * and rewrite them...
882          */
883         NODE *shp;
884         int sovty;
ragge
1.1
885
ragge
1.13
886         *down1 =  asgopp->n_op );
ragge
1.1
887         *down2 = 0;
888
ragge
1.13
889