Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081118162130

Diff

Diff from 1.245 to:

Annotations

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

Annotated File View

ragge
1.245
1 /*      $Id: reader.c,v 1.245 2008/11/18 16:21:30 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;
ragge
1.245
314         MARK mark;
ragge
1.244
315
ragge
1.172
316         if (ip->type == IP_PROLOG) {
ragge
1.244
317                 memset(p2e0sizeof(struct p2env));
ragge
1.172
318                 tmpsave = NULL;
ragge
1.244
319                 p2e->ipp = (struct interpass_prolog *)ip;
320                 DLIST_INIT(&p2e->ipoleqelem);
ragge
1.172
321         }
ragge
1.244
322         DLIST_INSERT_BEFORE(&p2e->ipoleipqelem);
ragge
1.172
323         if (ip->type != IP_EPILOG)
324                 return;
325
326 #ifdef PCC_DEBUG
327         if (e2debug) {
328                 printf("Entering pass2\n");
ragge
1.244
329                 printip(&p2e->ipole);
ragge
1.172
330         }
331 #endif
ragge
1.174
332
ragge
1.244
333         p2e->epp = (struct interpass_prolog *)DLIST_PREV(&p2e->ipoleqelem);
334         p2maxautooff = p2autooff = p2e->epp->ipp_autos;
ragge
1.174
335
ragge
1.241
336 #ifdef PCC_DEBUG
ragge
1.244
337         sanitychecks(p2e);
ragge
1.241
338 #endif
ragge
1.244
339         myreader(&p2e->ipole); /* local massage of input */
ragge
1.174
340
ragge
1.244
341         /*
342          * Do initial modification of the trees.  Two loops;
343          * - first, search for ADDROF of TEMPs, these must be
344          *   converterd to OREGs on stack.
345          * - second, do the actual conversions, in case of not xtemps
346          *   convert all temporaries to stack references.
347          */
ragge
1.245
348         markset(&mark);
ragge
1.244
349         if (p2e->epp->ip_tmpnum != p2e->ipp->ip_tmpnum) {
350                 addrp = tmpcalloc(sizeof(int) *
351                     (p2e->epp->ip_tmpnum - p2e->ipp->ip_tmpnum));
352                 addrp -= p2e->ipp->ip_tmpnum;
353         } else
354                 addrp = NULL;
355         if (xtemps) {
356                 DLIST_FOREACH(ip, &p2e->ipoleqelem) {
357                         if (ip->type == IP_NODE)
358                                 walkf(ip->ip_nodefindaofaddrp);
359                 }
360         }
361         DLIST_FOREACH(ip, &p2e->ipoleqelem) {
362                 if (ip->type == IP_NODE)
363                         walkf(ip->ip_nodedeltempaddrp);
364         }
ragge
1.245
365         markfree(&mark);
ragge
1.244
366
367 #ifdef PCC_DEBUG
368         if (e2debug) {
369                 printf("Efter ADDROF/TEMP\n");
370                 printip(&p2e->ipole);
371         }
372 #endif
373
374 #if 0
375         DLIST_FOREACH(ip, &p2e->ipoleqelem) {
ragge
1.172
376                 if (ip->type != IP_NODE)
377                         continue;
378                 if (xtemps == 0)
ragge
1.243
379                         walkf(ip->ip_nodedeltemp0);
ragge
1.172
380         }
ragge
1.244
381 #endif
382
ragge
1.201
383         DLIST_INIT(&prepoleqelem);
ragge
1.244
384         DLIST_FOREACH(ip, &p2e->ipoleqelem) {
ragge
1.172
385                 if (ip->type != IP_NODE)
386                         continue;
387                 canon(ip->ip_node);
ragge
1.201
388                 if ((ip->ip_node = deluseless(ip->ip_node)) == NULL) {
ragge
1.172
389                         DLIST_REMOVE(ipqelem);
ragge
1.201
390                 } else while (!DLIST_ISEMPTY(&prepoleqelem)) {
gmcgarry
1.224
391                         struct interpass *tipp;
ragge
1.201
392
gmcgarry
1.224
393                         tipp = DLIST_NEXT(&prepoleqelem);
394                         DLIST_REMOVE(tippqelem);
395                         DLIST_INSERT_BEFORE(iptippqelem);
ragge
1.201
396                 }
ragge
1.172
397         }
398
ragge
1.244
399         fixxasm(p2e); /* setup for extended asm */
ragge
1.216
400
ragge
1.244
401         optimize(p2e);
402         ngenregs(p2e);
ragge
1.172
403
ragge
1.244
404         DLIST_FOREACH(ip, &p2e->ipoleqelem)
ragge
1.172
405                 emit(ip);
406 }
407
ragge
1.124
408 void
ragge
1.125
409 emit(struct interpass *ip)
ragge
1.124
410 {
gmcgarry
1.208
411         NODE *p, *r;
412         struct optab *op;
ragge
1.149
413         int o;
ragge
1.124
414
ragge
1.125
415         switch (ip->type) {
416         case IP_NODE:
417                 p = ip->ip_node;
ragge
1.124
418
ragge
1.149
419                 nodepole = p;
ragge
1.180
420                 canon(p); /* may convert stuff after genregs */
ragge
1.240
421                 if (c2debug > 1) {
422                         printf("emit IP_NODE:\n");
423                         fwalk(pe2print0);
424                 }
ragge
1.124
425                 switch (p->n_op) {
426                 case CBRANCH:
427                         /* Only emit branch insn if RESCC */
gmcgarry
1.208
428                         /* careful when an OPLOG has been elided */
429                         if (p->n_left->n_su == 0 && p->n_left->n_left != NULL) {
430                                 op = &table[TBLIDX(p->n_left->n_left->n_su)];
431                                 r = p->n_left;
432                         } else {
433                                 op = &table[TBLIDX(p->n_left->n_su)];
434                                 r = p;
435                         }
436                         if (op->rewrite & RESCC) {
ragge
1.124
437                                 o = p->n_left->n_op;
gmcgarry
1.208
438                                 gencode(rFORCC);
ragge
1.124
439                                 cbgen(op->n_right->n_lval);
gmcgarry
1.208
440                         } else {
441                                 gencode(rFORCC);
442                         }
ragge
1.124
443                         break;
444                 case FORCE:
ragge
1.151
445                         gencode(p->n_leftINREGS);
ragge
1.124
446                         break;
ragge
1.216
447                 case XASM:
448                         genxasm(p);
449                         break;
ragge
1.124
450                 default:
451                         if (p->n_op != REG || p->n_type != VOID/* XXX */
452                                 gencode(pFOREFF); /* Emit instructions */
453                 }
454
ragge
1.125
455                 tfree(p);
456                 break;
ragge
1.124
457         case IP_PROLOG:
458                 prologue((struct interpass_prolog *)ip);
459                 break;
460         case IP_EPILOG:
461                 eoftn((struct interpass_prolog *)ip);
462                 tmpsave = NULL/* Always forget old nodes */
ragge
1.174
463                 p2maxautooff = p2autooff = AUTOINIT/SZCHAR;
ragge
1.124
464                 break;
465         case IP_DEFLAB:
466                 deflab(ip->ip_lbl);
467                 break;
468         case IP_ASM:
gmcgarry
1.229
469                 printf("%s"ip->ip_asm);
ragge
1.124
470                 break;
471         default:
ragge
1.216
472                 cerror("emit %d"ip->type);
ragge
1.124
473         }
ragge
1.123
474 }
ragge
1.124
475
ragge
1.30
476 #ifdef PCC_DEBUG
ragge
1.1
477 char *cnames[] = {
478         "SANY",
479         "SAREG",
480         "SBREG",
ragge
1.153
481         "SCREG",
482         "SDREG",
ragge
1.1
483         "SCC",
484         "SNAME",
485         "SCON",
486         "SFLD",
487         "SOREG",
488         "STARNM",
489         "STARREG",
490         "INTEMP",
491         "FORARG",
492         "SWADD",
493         0,
ragge
1.72
494 };
ragge
1.1
495
ragge
1.2
496 /*
497  * print a nice-looking description of cookie
498  */
ragge
1.70
499 char *
ragge
1.2
500 prcook(int cookie)
501 {
ragge
1.70
502         static char buf[50];
ragge
1.1
503         int iflag;
504
ragge
1.70
505         if (cookie & SPECIAL) {
506                 switch (cookie) {
507                 case SZERO:
508                         return "SZERO";
509                 case SONE:
510                         return "SONE";
511                 case SMONE:
512                         return "SMONE";
513                 default:
ragge
1.200
514                         snprintf(bufsizeof(buf), "SPECIAL+%d"cookie & ~SPECIAL);
ragge
1.70
515                         return buf;
ragge
1.1
516                 }
ragge
1.70
517         }
ragge
1.1
518
519         flag = 0;
ragge
1.70
520         buf[0] = 0;
521         for (i = 0cnames[i]; ++i) {
522                 if (cookie & (1<<i)) {
523                         if (flag)
ragge
1.200
524                                 strlcat(buf"|"sizeof(buf));
ragge
1.1
525                         ++flag;
ragge
1.200
526                         strlcat(bufcnames[i], sizeof(buf));
ragge
1.1
527                 }
ragge
1.70
528         }
529         return buf;
530 }
ragge
1.1
531
ragge
1.30
532 #endif
ragge
1.1
533
534 int odebug = 0;
535
ragge
1.151
536 int
ragge
1.69
537 geninsn(NODE *pint cookie)
538 {
ragge
1.71
539         NODE *p1, *p2;
ragge
1.236
540         int qorv = 0;
ragge
1.69
541
542 #ifdef PCC_DEBUG
543         if (odebug) {
ragge
1.70
544                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
545                 fwalk(pe2print0);
546         }
547 #endif
548
ragge
1.236
549         q = cookie & QUIET;
550         cookie &= ~QUIET/* XXX - should not be necessary */
551
ragge
1.69
552 again:  switch (o = p->n_op) {
ragge
1.71
553         case EQ:
554         case NE:
555         case LE:
556         case LT:
557         case GE:
558         case GT:
559         case ULE:
560         case ULT:
561         case UGE:
562         case UGT:
gmcgarry
1.208
563                 p1 = p->n_left;
564                 p2 = p->n_right;
ragge
1.210
565                 if (p2->n_op == ICON && p2->n_lval == 0 &&
566                     optype(p1->n_op) == BITYPE) {
ragge
1.236
567 #ifdef mach_pdp11 /* XXX all targets? */
568                         if ((rv = geninsn(p1FORCC|QUIET)) != FFAIL)
569                                 break;
570 #else
571                         if (findops(p1FORCC) > 0)
gmcgarry
1.208
572                                 break;
ragge
1.236
573 #endif
gmcgarry
1.208
574                 }
ragge
1.159
575                 rv = relops(p);
576                 break;
ragge
1.71
577
ragge
1.69
578         case PLUS:
579         case MINUS:
580         case MUL:
581         case DIV:
582         case MOD:
583         case AND:
584         case OR:
585         case ER:
586         case LS:
587         case RS:
ragge
1.151
588                 rv = findops(pcookie);
589                 break;
ragge
1.77
590
ragge
1.69
591         case ASSIGN:
ragge
1.236
592 #ifdef FINDMOPS
593                 if ((rv = findmops(pcookie)) != FFAIL)
594                         break;
595                 /* FALLTHROUGH */
596 #endif
ragge
1.174
597         case STASG:
ragge
1.151
598                 rv = findasg(pcookie);
599                 break;
ragge
1.159
600
ragge
1.178
601         case UMUL/* May turn into an OREG */
ragge
1.179
602                 rv = findumul(pcookie);
603                 break;
604
ragge
1.69
605         case REG:
ragge
1.144
606         case TEMP:
ragge
1.72
607         case NAME:
ragge
1.71
608         case ICON:
ragge
1.213
609         case FCON:
ragge
1.69
610         case OREG:
ragge
1.152
611                 rv = findleaf(pcookie);
612                 break;
ragge
1.69
613
ragge
1.172
614         case STCALL:
615         case CALL:
616                 /* CALL arguments are handled special */
617                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
ragge
1.239
618                         (void)geninsn(p1->n_rightFOREFF);
619                 (void)geninsn(p1FOREFF);
ragge
1.172
620                 /* FALLTHROUGH */
ragge
1.206
621         case FLD:
ragge
1.86
622         case COMPL:
ragge
1.85
623         case UMINUS:
ragge
1.71
624         case PCONV:
625         case SCONV:
ragge
1.198
626 /*      case INIT: */
ragge
1.70
627         case GOTO:
628         case FUNARG:
ragge
1.172
629         case STARG:
ragge
1.72
630         case UCALL:
ragge
1.103
631         case USTCALL:
ragge
1.207
632         case ADDROF:
ragge
1.155
633                 rv = finduni(pcookie);
634                 break;
ragge
1.69
635
ragge
1.71
636         case CBRANCH:
637                 p1 = p->n_left;
638                 p2 = p->n_right;
639                 p1->n_label = p2->n_lval;
ragge
1.239
640                 (void)geninsn(p1FORCC);
ragge
1.187
641                 p->n_su = 0;
ragge
1.71
642                 break;
643
ragge
1.187
644         case FORCE/* XXX needed? */
ragge
1.239
645                 (void)geninsn(p->n_leftINREGS);
ragge
1.187
646                 p->n_su = 0/* su calculations traverse left */
ragge
1.71
647                 break;
648
ragge
1.216
649         case XASM:
650                 for (p1 = p->n_leftp1->n_op == CMp1 = p1->n_left)
ragge
1.239
651                         (void)geninsn(p1->n_rightFOREFF);
652                 (void)geninsn(p1FOREFF);
ragge
1.216
653                 break;  /* all stuff already done? */
654
655         case XARG:
656                 /* generate code for correct class here */
ragge
1.221
657 //              geninsn(p->n_left, 1 << p->n_label);
ragge
1.216
658                 break;
659
ragge
1.69
660         default:
ragge
1.174
661                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
662         }
ragge
1.236
663         if (rv == FFAIL && !q)
ragge
1.160
664                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
665         if (rv == FRETRY)
666                 goto again;
ragge
1.236
667 #ifdef PCC_DEBUG
668         if (odebug) {
669                 printf("geninsn(%p, %s) rv %d\n"pprcook(cookie), rv);
670                 fwalk(pe2print0);
671         }
672 #endif
ragge
1.153
673         return rv;
ragge
1.69
674 }
675
ragge
1.72
676 /*
677  * Store a given subtree in a temporary location.
678  * Return an OREG node where it is located.
679  */
680 NODE *
681 store(NODE *p)
ragge
1.2
682 {
ragge
1.130
683         extern struct interpass *storesave;
684         struct interpass *ip;
685         NODE *q, *r;
686         int s;
ragge
1.49
687
ragge
1.130
688         s = BITOOR(freetemp(szty(p->n_type)));
689         q = mklnode(OREGsFPREGp->n_type);
690         r = mklnode(OREGsFPREGp->n_type);
691         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
692
ragge
1.149
693         storesave = ip;
ragge
1.72
694         return r;
ragge
1.8
695 }
ragge
1.1
696
ragge
1.170
697 #ifdef PCC_DEBUG
698 #define CDEBUG(x) if (c2debug) printf x
699 #else
700 #define CDEBUG(x)
701 #endif
702
ragge
1.69
703 /*
ragge
1.188
704  * Do a register-register move if necessary.
705  */
706 static void
707 ckmove(NODE *pNODE *q)
708 {
ragge
1.189
709         if (q->n_op != REG || p->n_reg == -1)
ragge
1.188
710                 return/* no register */
711         if (DECRA(p->n_reg0) == DECRA(q->n_reg0))
712                 return/* no move necessary */
ragge
1.190
713         CDEBUG(("rmove: node %p, %s -> %s\n"prnames[DECRA(q->n_reg0)],
714             rnames[DECRA(p->n_reg0)]));
ragge
1.188
715         rmove(DECRA(q->n_reg0), DECRA(p->n_reg0), p->n_type);
716         q->n_reg = q->n_rval = DECRA(p->n_reg0);
717 }
718
719 /*
720  * Rewrite node to register after instruction emit.
ragge
1.75
721  */
722 static void
gmcgarry
1.224
723 rewrite(NODE *pint dorewriteint cookie)
ragge
1.75
724 {
ragge
1.79
725         NODE *l, *r;
726         int o;
727
ragge
1.80
728         l = getlr(p'L');
729         r = getlr(p'R');
ragge
1.79
730         o = p->n_op;
ragge
1.75
731         p->n_op = REG;
ragge
1.76
732         p->n_lval = 0;
ragge
1.95
733         p->n_name = "";
ragge
1.158
734
ragge
1.190
735         if (o == ASSIGN) {
736                 /* special rewrite care */
737                 int reg = DECRA(p->n_reg0);
ragge
1.191
738 #define TL(x) (TBLIDX(x->n_su) || x->n_op == REG)
ragge
1.190
739                 if (p->n_reg == -1)
740                         ;
ragge
1.191
741                 else if (TL(l) && (DECRA(l->n_reg0) == reg))
ragge
1.190
742                         ;
ragge
1.191
743                 else if (TL(r) && (DECRA(r->n_reg0) == reg))
ragge
1.190
744                         ;
ragge
1.191
745                 else if (TL(l))
ragge
1.190
746                         rmove(DECRA(l->n_reg0), regp->n_type);
ragge
1.191
747                 else if (TL(r))
ragge
1.190
748                         rmove(DECRA(r->n_reg0), regp->n_type);
749 #if 0
750                 else
751                         comperr("rewrite");
752 #endif
ragge
1.191
753 #undef TL
ragge
1.190
754         }
ragge
1.79
755         if (optype(o) != LTYPE)
756                 tfree(l);
757         if (optype(o) == BITYPE)
758                 tfree(r);
gmcgarry
1.224
759         if (dorewrite == 0)
ragge
1.190
760                 return;
mickey
1.205
761         CDEBUG(("rewrite: %p, reg %s\n"p,
762             p->n_reg == -1"<none>" : rnames[DECRA(p->n_reg0)]));
ragge
1.187
763         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
764 }
765
ragge
1.228
766 #ifndef XASM_TARGARG
767 #define XASM_TARGARG(x,y) 0
768 #endif
769
ragge
1.216
770 /*
771  * printout extended assembler.
772  */
773 void
774 genxasm(NODE *p)
775 {
776         NODE *q, **nary;
777         int n = 1o = 0;
778         char *w;
779
ragge
1.228
780         if (p->n_left->n_op != ICON || p->n_left->n_type != STRTY) {
781                 for (q = p->n_leftq->n_op == CMq = q->n_left)
782                         n++;
783                 nary = tmpalloc(sizeof(NODE *)*n);
784                 o = n;
785                 for (q = p->n_leftq->n_op == CMq = q->n_left) {
786                         gencode(q->n_right->n_leftINREGS);
787                         nary[--o] = q->n_right;
788                 }
789                 gencode(q->n_leftINREGS);
790                 nary[--o] = q;
791         } else
792                 nary = 0;
ragge
1.216
793
794         w = p->n_name;
795         putchar('\t');
796         while (*w != 0) {
797                 if (*w == '%') {
ragge
1.225
798                         if (w[1] == '%')
799                                 putchar('%');
ragge
1.228
800                         else if (XASM_TARGARG(wnary))
801                                 ; /* handled by target */
ragge
1.225
802                         else if (w[1] < '0' || w[1] > (n + '0'))
ragge
1.228
803                                 uerror("bad xasm arg number %c"w[1]);
ragge
1.216
804                         else
ragge
1.221
805                                 adrput(stdoutnary[(int)w[1]-'0']->n_left);
ragge
1.216
806                         w++;
ragge
1.228
807                 } else if (*w == '\\') { /* Always 3-digit octal */
808                         int num = *++w - '0';
809                         num = (num << 3) + *++w - '0';
810                         num = (num << 3) + *++w - '0';
811                         putchar(num);
ragge
1.216
812                 } else
813                         putchar(*w);
814                 w++;
815         }
816         putchar('\n');
817 }
818
ragge
1.69
819 void
ragge
1.72
820 gencode(NODE *pint cookie)
ragge
1.69
821 {
822         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
823         NODE *p1, *l, *r;
ragge
1.190
824         int o = optype(p->n_op);
ragge
1.240
825 #ifdef FINDMOPS
826         int ismops = (p->n_op == ASSIGN && (p->n_flags & 1));
827 #endif
ragge
1.188
828
829         l = p->n_left;
830         r = p->n_right;
ragge
1.69
831
ragge
1.186
832         if (TBLIDX(p->n_su) == 0) {
833                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
834                         gencode(r0);
ragge
1.185
835                 if (optype(p->n_op) != LTYPE)
ragge
1.188
836                         gencode(l0);
ragge
1.186
837                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
838                         gencode(r0);
ragge
1.185
839                 return;
840         }
ragge
1.69
841
ragge
1.170
842         CDEBUG(("gencode: node %p\n"p));
843
844         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
845                 return/* meaningless move to itself */
ragge
1.175
846
847         if (callop(p->n_op))
848                 lastcall(p); /* last chance before function args */
849         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
850                 /* Print out arguments first */
ragge
1.188
851                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
852                         gencode(p1->n_rightFOREFF);
853                 gencode(p1FOREFF);
ragge
1.190
854                 o = UTYPE/* avoid going down again */
ragge
1.175
855         }
856
ragge
1.190
857         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
858                 gencode(rINREGS);
859                 if (q->rewrite & RRIGHT)
860                         ckmove(pr);
861         }
ragge
1.190
862         if (o != LTYPE) {
ragge
1.188
863                 gencode(lINREGS);
ragge
1.240
864 #ifdef FINDMOPS
865                 if (ismops)
866                         ;
867                 else
868 #endif
869                      if (q->rewrite & RLEFT)
ragge
1.188
870                         ckmove(pl);
871         }
ragge
1.190
872         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
873                 gencode(rINREGS);
874                 if (q->rewrite & RRIGHT)
875                         ckmove(pr);
876         }
ragge
1.185
877
ragge
1.236
878 #ifdef FINDMOPS
ragge
1.240
879         if (ismops) {
ragge
1.236
880                 /* reduce right tree to make expand() work */
881                 if (optype(r->n_op) != LTYPE) {
ragge
1.240
882                         p->n_op = r->n_op;
ragge
1.236
883                         r = tcopy(r->n_right);
884                         tfree(p->n_right);
885                         p->n_right = r;
886                 }
887         }
888 #endif
889
ragge
1.188
890         canon(p);
ragge
1.185
891
ragge
1.188
892         if (q->needs & NSPECIAL) {
893                 int rr = rspecial(qNRIGHT);
894                 int lr = rspecial(qNLEFT);
ragge
1.187
895