Quick Search:

View

Revision:
Expand:  
Changeset: r-1-0-0:ragge:20110315172318

Diff

Diff from 1.268.2.1 to:

Annotations

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

Annotated File View

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