Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:mickey:20100327234611

Diff

Diff from 1.258 to:

Annotations

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

Annotated File View

mickey
1.258
1 /*      $Id: reader.c,v 1.258 2010/03/27 23:46:12 mickey 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
382 #if 0
383         DLIST_FOREACH(ip, &p2e->ipoleqelem) {
ragge
1.172
384                 if (ip->type != IP_NODE)
385                         continue;
386                 if (xtemps == 0)
ragge
1.243
387                         walkf(ip->ip_nodedeltemp0);
ragge
1.172
388         }
ragge
1.244
389 #endif
390
ragge
1.201
391         DLIST_INIT(&prepoleqelem);
ragge
1.244
392         DLIST_FOREACH(ip, &p2e->ipoleqelem) {
ragge
1.172
393                 if (ip->type != IP_NODE)
394                         continue;
395                 canon(ip->ip_node);
ragge
1.201
396                 if ((ip->ip_node = deluseless(ip->ip_node)) == NULL) {
ragge
1.172
397                         DLIST_REMOVE(ipqelem);
ragge
1.201
398                 } else while (!DLIST_ISEMPTY(&prepoleqelem)) {
gmcgarry
1.224
399                         struct interpass *tipp;
ragge
1.201
400
gmcgarry
1.224
401                         tipp = DLIST_NEXT(&prepoleqelem);
402                         DLIST_REMOVE(tippqelem);
403                         DLIST_INSERT_BEFORE(iptippqelem);
ragge
1.201
404                 }
ragge
1.172
405         }
406
ragge
1.244
407         fixxasm(p2e); /* setup for extended asm */
ragge
1.216
408
ragge
1.244
409         optimize(p2e);
410         ngenregs(p2e);
ragge
1.172
411
ragge
1.244
412         DLIST_FOREACH(ip, &p2e->ipoleqelem)
ragge
1.172
413                 emit(ip);
414 }
415
ragge
1.124
416 void
ragge
1.125
417 emit(struct interpass *ip)
ragge
1.124
418 {
gmcgarry
1.208
419         NODE *p, *r;
420         struct optab *op;
ragge
1.149
421         int o;
ragge
1.124
422
ragge
1.125
423         switch (ip->type) {
424         case IP_NODE:
425                 p = ip->ip_node;
ragge
1.124
426
ragge
1.149
427                 nodepole = p;
ragge
1.180
428                 canon(p); /* may convert stuff after genregs */
ragge
1.240
429                 if (c2debug > 1) {
430                         printf("emit IP_NODE:\n");
431                         fwalk(pe2print0);
432                 }
ragge
1.124
433                 switch (p->n_op) {
434                 case CBRANCH:
435                         /* Only emit branch insn if RESCC */
gmcgarry
1.208
436                         /* careful when an OPLOG has been elided */
437                         if (p->n_left->n_su == 0 && p->n_left->n_left != NULL) {
438                                 op = &table[TBLIDX(p->n_left->n_left->n_su)];
439                                 r = p->n_left;
440                         } else {
441                                 op = &table[TBLIDX(p->n_left->n_su)];
442                                 r = p;
443                         }
444                         if (op->rewrite & RESCC) {
ragge
1.124
445                                 o = p->n_left->n_op;
gmcgarry
1.208
446                                 gencode(rFORCC);
ragge
1.124
447                                 cbgen(op->n_right->n_lval);
gmcgarry
1.208
448                         } else {
449                                 gencode(rFORCC);
450                         }
ragge
1.124
451                         break;
452                 case FORCE:
ragge
1.151
453                         gencode(p->n_leftINREGS);
ragge
1.124
454                         break;
ragge
1.216
455                 case XASM:
456                         genxasm(p);
457                         break;
ragge
1.124
458                 default:
459                         if (p->n_op != REG || p->n_type != VOID/* XXX */
460                                 gencode(pFOREFF); /* Emit instructions */
461                 }
462
ragge
1.125
463                 tfree(p);
464                 break;
ragge
1.124
465         case IP_PROLOG:
466                 prologue((struct interpass_prolog *)ip);
467                 break;
468         case IP_EPILOG:
469                 eoftn((struct interpass_prolog *)ip);
ragge
1.174
470                 p2maxautooff = p2autooff = AUTOINIT/SZCHAR;
ragge
1.124
471                 break;
472         case IP_DEFLAB:
473                 deflab(ip->ip_lbl);
474                 break;
475         case IP_ASM:
gmcgarry
1.229
476                 printf("%s"ip->ip_asm);
ragge
1.124
477                 break;
478         default:
ragge
1.216
479                 cerror("emit %d"ip->type);
ragge
1.124
480         }
ragge
1.123
481 }
ragge
1.124
482
ragge
1.30
483 #ifdef PCC_DEBUG
ragge
1.1
484 char *cnames[] = {
485         "SANY",
486         "SAREG",
487         "SBREG",
ragge
1.153
488         "SCREG",
489         "SDREG",
ragge
1.1
490         "SCC",
491         "SNAME",
492         "SCON",
493         "SFLD",
494         "SOREG",
495         "STARNM",
496         "STARREG",
497         "INTEMP",
498         "FORARG",
499         "SWADD",
500         0,
ragge
1.72
501 };
ragge
1.1
502
ragge
1.2
503 /*
504  * print a nice-looking description of cookie
505  */
ragge
1.70
506 char *
ragge
1.2
507 prcook(int cookie)
508 {
ragge
1.70
509         static char buf[50];
ragge
1.1
510         int iflag;
511
ragge
1.70
512         if (cookie & SPECIAL) {
513                 switch (cookie) {
514                 case SZERO:
515                         return "SZERO";
516                 case SONE:
517                         return "SONE";
518                 case SMONE:
519                         return "SMONE";
520                 default:
ragge
1.200
521                         snprintf(bufsizeof(buf), "SPECIAL+%d"cookie & ~SPECIAL);
ragge
1.70
522                         return buf;
ragge
1.1
523                 }
ragge
1.70
524         }
ragge
1.1
525
526         flag = 0;
ragge
1.70
527         buf[0] = 0;
528         for (i = 0cnames[i]; ++i) {
529                 if (cookie & (1<<i)) {
530                         if (flag)
ragge
1.200
531                                 strlcat(buf"|"sizeof(buf));
ragge
1.1
532                         ++flag;
ragge
1.200
533                         strlcat(bufcnames[i], sizeof(buf));
ragge
1.1
534                 }
ragge
1.70
535         }
536         return buf;
537 }
ragge
1.30
538 #endif
ragge
1.1
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 &&
ragge
1.256
570                     (dope[p1->n_op] & (FLOFLG|DIVFLG|SIMPFLG|SHFFLG))) {
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;
gmcgarry
1.251
643                 p1->n_label = (int)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 */
gmcgarry
1.250
661 #if 0
662                 geninsn(p->n_left1 << p->n_label);
663 #endif
ragge
1.216
664                 break;
665
ragge
1.69
666         default:
ragge
1.174
667                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
668         }
ragge
1.236
669         if (rv == FFAIL && !q)
ragge
1.160
670                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
671         if (rv == FRETRY)
672                 goto again;
ragge
1.236
673 #ifdef PCC_DEBUG
674         if (odebug) {
675                 printf("geninsn(%p, %s) rv %d\n"pprcook(cookie), rv);
676                 fwalk(pe2print0);
677         }
678 #endif
ragge
1.153
679         return rv;
ragge
1.69
680 }
681
ragge
1.72
682 /*
683  * Store a given subtree in a temporary location.
684  * Return an OREG node where it is located.
685  */
686 NODE *
687 store(NODE *p)
ragge
1.2
688 {
ragge
1.130
689         extern struct interpass *storesave;
690         struct interpass *ip;
691         NODE *q, *r;
692         int s;
ragge
1.49
693
ragge
1.130
694         s = BITOOR(freetemp(szty(p->n_type)));
695         q = mklnode(OREGsFPREGp->n_type);
696         r = mklnode(OREGsFPREGp->n_type);
697         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
698
ragge
1.149
699         storesave = ip;
ragge
1.72
700         return r;
ragge
1.8
701 }
ragge
1.1
702
ragge
1.170
703 #ifdef PCC_DEBUG
704 #define CDEBUG(x) if (c2debug) printf x
705 #else
706 #define CDEBUG(x)
707 #endif
708
ragge
1.69
709 /*
ragge
1.188
710  * Do a register-register move if necessary.
711  */
712 static void
713 ckmove(NODE *pNODE *q)
714 {
ragge
1.189
715         if (q->n_op != REG || p->n_reg == -1)
ragge
1.188
716                 return/* no register */
717         if (DECRA(p->n_reg0) == DECRA(q->n_reg0))
718                 return/* no move necessary */
ragge
1.190
719         CDEBUG(("rmove: node %p, %s -> %s\n"prnames[DECRA(q->n_reg0)],
720             rnames[DECRA(p->n_reg0)]));
ragge
1.188
721         rmove(DECRA(q->n_reg0), DECRA(p->n_reg0), p->n_type);
722         q->n_reg = q->n_rval = DECRA(p->n_reg0);
723 }
724
725 /*
726  * Rewrite node to register after instruction emit.
ragge
1.75
727  */
728 static void
gmcgarry
1.224
729 rewrite(NODE *pint dorewriteint cookie)
ragge
1.75
730 {
ragge
1.79
731         NODE *l, *r;
732         int o;
733
ragge
1.80
734         l = getlr(p'L');
735         r = getlr(p'R');
ragge
1.79
736         o = p->n_op;
ragge
1.75
737         p->n_op = REG;
ragge
1.76
738         p->n_lval = 0;
ragge
1.95
739         p->n_name = "";
ragge
1.158
740
ragge
1.257
741         if (o == ASSIGN || o == STASG) {
ragge
1.190
742                 /* special rewrite care */
743                 int reg = DECRA(p->n_reg0);
ragge
1.191
744 #define TL(x) (TBLIDX(x->n_su) || x->n_op == REG)
ragge
1.190
745                 if (p->n_reg == -1)
746                         ;
ragge
1.191
747                 else if (TL(l) && (DECRA(l->n_reg0) == reg))
ragge
1.190
748                         ;
ragge
1.191
749                 else if (TL(r) && (DECRA(r->n_reg0) == reg))
ragge
1.190
750                         ;
ragge
1.191
751                 else if (TL(l))
ragge
1.190
752                         rmove(DECRA(l->n_reg0), regp->n_type);
ragge
1.191
753                 else if (TL(r))
ragge
1.190
754                         rmove(DECRA(r->n_reg0), regp->n_type);
755 #if 0
756                 else
757                         comperr("rewrite");
758 #endif
ragge
1.191
759 #undef TL
ragge
1.190
760         }
ragge
1.79
761         if (optype(o) != LTYPE)
762                 tfree(l);
763         if (optype(o) == BITYPE)
764                 tfree(r);
gmcgarry
1.224
765         if (dorewrite == 0)
ragge
1.190
766                 return;
mickey
1.205
767         CDEBUG(("rewrite: %p, reg %s\n"p,
768             p->n_reg == -1"<none>" : rnames[DECRA(p->n_reg0)]));
ragge
1.187
769         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
770 }
771
ragge
1.228
772 #ifndef XASM_TARGARG
773 #define XASM_TARGARG(x,y) 0
774 #endif
775
ragge
1.216
776 /*
777  * printout extended assembler.
778  */
779 void
780 genxasm(NODE *p)
781 {
782         NODE *q, **nary;
783         int n = 1o = 0;
784         char *w;
785
ragge
1.228
786         if (p->n_left->n_op != ICON || p->n_left->n_type != STRTY) {
787                 for (q = p->n_leftq->n_op == CMq = q->n_left)
788                         n++;
ragge
1.254
789                 nary = tmpcalloc(sizeof(NODE *)*(n+1));
ragge
1.228
790                 o = n;
791                 for (q = p->n_leftq->n_op == CMq = q->n_left) {
792                         gencode(q->n_right->n_leftINREGS);
793                         nary[--o] = q->n_right;
794                 }
795                 gencode(q->n_leftINREGS);
796                 nary[--o] = q;
797         } else
798                 nary = 0;
ragge
1.216
799
800         w = p->n_name;
801         putchar('\t');
802         while (*w != 0) {
803                 if (*w == '%') {
ragge
1.225
804                         if (w[1] == '%')
805                                 putchar('%');
ragge
1.228
806                         else if (XASM_TARGARG(wnary))
807                                 ; /* handled by target */
ragge
1.225
808                         else if (w[1] < '0' || w[1] > (n + '0'))
ragge
1.228
809                                 uerror("bad xasm arg number %c"w[1]);
ragge
1.253
810                         else {
811                                 if (w[1] == (n + '0'))
812                                         q = nary[(int)w[1]-'0' - 1]; /* XXX */
813                                 else
814                                         q = nary[(int)w[1]-'0'];
815                                 adrput(stdoutq->n_left);
816                         }
ragge
1.216
817                         w++;
ragge
1.228
818                 } else if (*w == '\\') { /* Always 3-digit octal */
819                         int num = *++w - '0';
820                         num = (num << 3) + *++w - '0';
821                         num = (num << 3) + *++w - '0';
822                         putchar(num);
ragge
1.216
823                 } else
824                         putchar(*w);
825                 w++;
826         }
827         putchar('\n');
828 }
829
ragge
1.69
830 void
ragge
1.72
831 gencode(NODE *pint cookie)
ragge
1.69
832 {
833         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
834         NODE *p1, *l, *r;
ragge
1.190
835         int o = optype(p->n_op);
ragge
1.240
836 #ifdef FINDMOPS
837         int ismops = (p->n_op == ASSIGN && (p->n_flags & 1));
838 #endif
ragge
1.188
839
840         l = p->n_left;
841         r = p->n_right;
ragge
1.69
842
ragge
1.186
843         if (TBLIDX(p->n_su) == 0) {
844                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
845                         gencode(r0);
ragge
1.185
846                 if (optype(p->n_op) != LTYPE)
ragge
1.188
847                         gencode(l0);
ragge
1.186
848                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
849                         gencode(r0);
ragge
1.185
850                 return;
851         }
ragge
1.69
852
ragge
1.170
853         CDEBUG(("gencode: node %p\n"p));
854
855         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
856                 return/* meaningless move to itself */
ragge
1.175
857
858         if (callop(p->n_op))
859                 lastcall(p); /* last chance before function args */
860         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
861                 /* Print out arguments first */
ragge
1.188
862                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
863                         gencode(p1->n_rightFOREFF);
864                 gencode(p1FOREFF);
ragge
1.190
865                 o = UTYPE/* avoid going down again */
ragge
1.175
866         }
867
ragge
1.190
868         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
869                 gencode(rINREGS);
870                 if (q->rewrite & RRIGHT)
871                         ckmove(pr);
872         }
ragge
1.190
873         if (o != LTYPE) {
ragge
1.188
874                 gencode(lINREGS);
ragge
1.240
875 #ifdef FINDMOPS
876                 if (ismops)
877                         ;
878                 else
879 #endif
880                      if (q->rewrite & RLEFT)
ragge
1.188
881                         ckmove(pl);
882         }
ragge
1.190
883         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
884                 gencode(rINREGS);
885                 if (q->rewrite & RRIGHT)
886                         ckmove(pr);
887         }
ragge
1.185
888
ragge
1.236
889 #ifdef FINDMOPS
ragge
1.240
890         if (ismops) {