Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081122160735

Diff

Diff from 1.246 to:

Annotations

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

Annotated File View

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