Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100501114316

Diff

Diff from 1.259 to:

Annotations

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

Annotated File View

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