Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110529131906

Diff

Diff from 1.273 to:

Annotations

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

Annotated File View

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