Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081116211741

Diff

Diff from 1.244 to:

Annotations

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

Annotated File View

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