Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081005155531

Diff

Diff from 1.239 to:

Annotations

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

Annotated File View

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