Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20150823184031

Diff

Diff from 1.297 to:

Annotations

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

Annotated File View

ragge
1.297
1 /*      $Id: reader.c,v 1.297 2015/08/23 18:40:31 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  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
ragge
1.31
27 /*
28  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
29  *
30  * Redistribution and use in source and binary forms, with or without
31  * modification, are permitted provided that the following conditions
32  * are met:
33  *
34  * Redistributions of source code and documentation must retain the above
35  * copyright notice, this list of conditions and the following disclaimer.
36  * Redistributions in binary form must reproduce the above copyright
37  * notice, this list of conditionsand the following disclaimer in the
38  * documentation and/or other materials provided with the distribution.
39  * All advertising materials mentioning features or use of this software
40  * must display the following acknowledgement:
41  *      This product includes software developed or owned by Caldera
42  *      International, Inc.
43  * Neither the name of Caldera International, Inc. nor the names of other
44  * contributors may be used to endorse or promote products derived from
45  * this software without specific prior written permission.
46  *
47  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
48  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
49  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
52  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
56  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
57  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
58  * POSSIBILITY OF SUCH DAMAGE.
59  */
ragge
1.1
60
ragge
1.123
61 /*
ragge
1.236
62  * Everything is entered via pass2_compile().  No functions are 
63  * allowed to recurse back into pass2_compile().
ragge
1.123
64  */
65
ragge
1.1
66 # include "pass2.h"
67
ragge
1.70
68 #include <string.h>
ragge
1.71
69 #include <stdarg.h>
ragge
1.94
70 #include <stdlib.h>
ragge
1.70
71
ragge
1.1
72 /*      some storage declarations */
73 int nrecur;
ragge
1.103
74 int thisline;
ragge
1.72
75 int fregs;
ragge
1.123
76 int p2autooffp2maxautooff;
ragge
1.1
77
ragge
1.72
78 NODE *nodepole;
ragge
1.238
79 struct interpass prepole;
ragge
1.23
80
ragge
1.37
81 void saveip(struct interpass *ip);
ragge
1.243
82 void deltemp(NODE *pvoid *);
ragge
1.232
83 static void cvtemps(struct interpass *ipoleint opint off);
ragge
1.242
84 static void fixxasm(struct p2env *);
ragge
1.65
85
ragge
1.72
86 static void gencode(NODE *pint cookie);
ragge
1.216
87 static void genxasm(NODE *p);
ragge
1.271
88 static void afree(void);
ragge
1.69
89
ragge
1.246
90 struct p2env p2env;
ragge
1.121
91
ragge
1.296
92 int crslab2 = 11
93 /*
94  * Return a number for internal labels.
95  */
ragge
1.246
96 int
97 getlab2(void)
98 {
ragge
1.296
99         crslab2++;
100         if (crslab2 < p2env.ipp->ip_lblnum || crslab2 >= p2env.epp->ip_lblnum)
101                 comperr("getlab2 %d outside boundaries %d-%d",
102                     crslab2p2env.ipp->ip_lblnump2env.epp->ip_lblnum);
103         return crslab2++;
ragge
1.246
104 }
ragge
1.241
105
ragge
1.296
106
ragge
1.26
107 #ifdef PCC_DEBUG
ragge
1.241
108 static int *lbldef, *lbluse;
ragge
1.26
109 static void
ragge
1.243
110 cktree(NODE *pvoid *arg)
ragge
1.26
111 {
ragge
1.241
112         int i;
113
ragge
1.26
114         if (p->n_op > MAXOP)
ragge
1.218
115                 cerror("%p) op %d slipped through"pp->n_op);
ragge
1.273
116 #ifndef FIELDOPS
117         if (p->n_op == FLD)
118                 cerror("%p) FLD slipped through"p);
119 #endif
ragge
1.199
120         if (BTYPE(p->n_type) > MAXTYPES)
ragge
1.218
121                 cerror("%p) type %x slipped through"pp->n_type);
ragge
1.241
122         if (p->n_op == CBRANCH) {
123                  if (!logop(p->n_left->n_op))
124                         cerror("%p) not logop branch"p);
gmcgarry
1.251
125                 i = (int)p->n_right->n_lval;
ragge
1.242
126                 if (i < p2env.ipp->ip_lblnum || i >= p2env.epp->ip_lblnum)
ragge
1.241
127                         cerror("%p) label %d outside boundaries %d-%d",
ragge
1.242
128                             pip2env.ipp->ip_lblnump2env.epp->ip_lblnum);
129                 lbluse[i-p2env.ipp->ip_lblnum] = 1;
ragge
1.241
130         }
ragge
1.47
131         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
ragge
1.218
132                 cerror("%p) asgop %d slipped through"pp->n_op);
ragge
1.241
133         if (p->n_op == TEMP &&
ragge
1.242
134             (regno(p) < p2env.ipp->ip_tmpnum || regno(p) >= p2env.epp->ip_tmpnum))
ragge
1.241
135                 cerror("%p) temporary %d outside boundaries %d-%d",
ragge
1.242
136                     pregno(p), p2env.ipp->ip_tmpnump2env.epp->ip_tmpnum);
ragge
1.249
137         if (p->n_op == GOTO && p->n_left->n_op == ICON) {
gmcgarry
1.251
138                 i = (int)p->n_left->n_lval;
ragge
1.242
139                 if (i < p2env.ipp->ip_lblnum || i >= p2env.epp->ip_lblnum)
ragge
1.241
140                         cerror("%p) label %d outside boundaries %d-%d",
ragge
1.242
141                             pip2env.ipp->ip_lblnump2env.epp->ip_lblnum);
142                 lbluse[i-p2env.ipp->ip_lblnum] = 1;
ragge
1.241
143         }
144 }
145
146 /*
147  * Check that the trees are in a suitable state for pass2.
148  */
149 static void
ragge
1.244
150 sanitychecks(struct p2env *p2e)
ragge
1.241
151 {
152         struct interpass *ip;
ragge
1.295
153         int isz;
154
155         sz = sizeof(int) * (p2e->epp->ip_lblnum - p2e->ipp->ip_lblnum);
156         lbldef = xcalloc(sz1);
157         lbluse = xcalloc(sz1);
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
ragge
1.295
175         free(lbldef);
176         free(lbluse);
ragge
1.26
177 }
178 #endif
ragge
1.8
179
ragge
1.130
180 /*
ragge
1.244
181  * Look if a temporary comes from a on-stack argument, in that case
182  * use the already existing stack position instead of moving it to
183  * a new place, and remove the move-to-temp statement.
184  */
185 static int
ragge
1.289
186 stkarg(int tnrint (*soff)[2])
ragge
1.244
187 {
188         struct p2env *p2e = &p2env;
189         struct interpass *ip;
190         NODE *p;
191
ragge
1.248
192         ip = DLIST_NEXT((struct interpass *)p2e->ippqelem);
193         while (ip->type != IP_DEFLAB/* search for first DEFLAB */
194                 ip = DLIST_NEXT(ipqelem);
195
ragge
1.244
196         ip = DLIST_NEXT(ipqelem); /* first NODE */
197
198         for (; ip->type != IP_DEFLABip = DLIST_NEXT(ipqelem)) {
199                 if (ip->type != IP_NODE)
200                         continue;
201
202                 p = ip->ip_node;
ragge
1.247
203                 if (p->n_op == XASM)
204                         continue/* XXX - hack for x86 PIC */
ragge
1.264
205 #ifdef notdef
ragge
1.244
206                 if (p->n_op != ASSIGN || p->n_left->n_op != TEMP)
207                         comperr("temparg");
208 #endif
ragge
1.264
209                 if (p->n_op != ASSIGN || p->n_left->n_op != TEMP)
210                         continue/* unknown tree */
211
ragge
1.244
212                 if (p->n_right->n_op != OREG && p->n_right->n_op != UMUL)
213                         continue/* arg in register */
214                 if (tnr != regno(p->n_left))
215                         continue/* wrong assign */
216                 p = p->n_right;
217                 if (p->n_op == UMUL &&
218                     p->n_left->n_op == PLUS &&
219                     p->n_left->n_left->n_op == REG &&
ragge
1.274
220                     p->n_left->n_right->n_op == ICON) {
ragge
1.289
221                         soff[0][0] = regno(p->n_left->n_left);
222                         soff[0][1] = (int)p->n_left->n_right->n_lval;
ragge
1.274
223                 } else if (p->n_op == OREG) {
ragge
1.289
224                         soff[0][0] = regno(p);
225                         soff[0][1] = (int)p->n_lval;
ragge
1.274
226                 } else
ragge
1.244
227                         comperr("stkarg: bad arg");
228                 tfree(ip->ip_node);
229                 DLIST_REMOVE(ipqelem);
230                 return 1;
231         }
232         return 0;
233 }
234
235 /*
236  * See if an ADDROF is somewhere inside the expression tree.
237  * If so, fill in the offset table.
238  */
239 static void
240 findaof(NODE *pvoid *arg)
241 {
ragge
1.289
242         int (*aof)[2] = arg;
ragge
1.244
243         int tnr;
244
ragge
1.263
245         if (p->n_op != ADDROF || p->n_left->n_op != TEMP)
ragge
1.244
246                 return;
247         tnr = regno(p->n_left);
ragge
1.289
248         if (aof[tnr][0])
ragge
1.244
249                 return/* already gotten stack address */
250         if (stkarg(tnr, &aof[tnr]))
251                 return/* argument was on stack */
ragge
1.289
252         aof[tnr][0] = FPREG;
253         aof[tnr][1] = freetemp(szty(p->n_left->n_type));
ragge
1.244
254 }
255
256 /*
ragge
1.89
257  * Check if a node has side effects.
258  */
259 static int
260 isuseless(NODE *n)
261 {
262         switch (n->n_op) {
ragge
1.216
263         case XASM:
ragge
1.89
264         case FUNARG:
265         case UCALL:
266         case UFORTCALL:
267         case FORCE:
268         case ASSIGN:
269         case CALL:
270         case FORTCALL:
271         case CBRANCH:
272         case RETURN:
273         case GOTO:
274         case STCALL:
275         case USTCALL:
276         case STASG:
277         case STARG:
278                 return 0;
279         default:
280                 return 1;
281         }
282 }
283
ragge
1.130
284 /*
285  * Delete statements with no meaning (like a+b; or 513.4;)
286  */
ragge
1.238
287 NODE *
ragge
1.89
288 deluseless(NODE *p)
289 {
290         struct interpass *ip;
291         NODE *l, *r;
292
293         if (optype(p->n_op) == LTYPE) {
294                 nfree(p);
295                 return NULL;
296         }
297         if (isuseless(p) == 0)
298                 return p;
299
300         if (optype(p->n_op) == UTYPE) {
301                 l = p->n_left;
302                 nfree(p);
303                 return deluseless(l);
304         }
305
306         /* Be sure that both leaves may be valid */
307         l = deluseless(p->n_left);
308         r = deluseless(p->n_right);
309         nfree(p);
310         if (l && r) {
ragge
1.201
311                 ip = ipnode(l);
312                 DLIST_INSERT_AFTER(&prepoleipqelem);
ragge
1.89
313                 return r;
314         } else if (l)
315                 return l;
316         else if (r)
317                 return r;
318         return NULL;
319 }
320
ragge
1.293
321 #ifdef PASS2
ragge
1.296
322
323 #define SKIPWS(p) while (*p == ' ') p++
ragge
1.293
324 #define SZIBUF  256
ragge
1.296
325 static int inpline;
326 static char inpbuf[SZIBUF];
ragge
1.293
327 static char *
328 rdline(void)
329 {
330         int l;
331
ragge
1.296
332         if (fgets(inpbufsizeof(inpbuf), stdin) == NULL)
ragge
1.293
333                 return NULL;
ragge
1.296
334         inpline++;
335         l = strlen(inpbuf);
336         if (inpbuf[0] < 33 || inpbuf[1] != ' ' || inpbuf[l-1] != '\n')
337                 comperr("sync error in-line %d string '%s'"inplineinpbuf);
338         inpbuf[l-1] = 0;
339         return inpbuf;
ragge
1.293
340 }
341
342 /*
343  * Read an int and traverse over it. count up s.
344  */
345 static int
346 rdint(char **s)
347 {
348         char *p = *s;
349         int rv;
350
ragge
1.296
351         SKIPWS(p);
ragge
1.293
352         rv = atoi(p);
353         if (*p == '-' || *p == '+'p++;
354         while (*p >= '0' && *p <= '9'p++;
355         *s = p;
356         return rv;
357 }
358
ragge
1.296
359 static struct attr *
360 rdattr(char **p)
361 {
362         struct attr *ap, *app = NULL;
363         int iasz;
364
365         (*p)++; /* skip + */
366 onemore:
367         a = rdint(p);
368         sz = rdint(p);
369         ap = attr_new(asz);
370         for (i = 0i < szi++)
371                 ap->iarg(i) = rdint(p);
372         ap->next = app;
373         app = ap;
374         SKIPWS((*p));
375         if (**p != 0)
376                 goto onemore;
377
378         return app;
379 }
380
381 /*
382  * Read in an indentifier and save on tmp heap.  Return saved string.
383  */
384 static char *
385 rdstr(char **p)
386 {
387         char *t, *s = *p;
388         int sz;
389
390         SKIPWS(s);
391         *p = s;
392         for (sz = 0; *s && *s != ' 's++, sz++)
393                 ;
394         t = tmpalloc(sz+1);
395         memcpy(t, *psz);
396         t[sz] = 0;
397         *p = s;
398         return t;
399 }
400
ragge
1.293
401 /*
402  * Read and check node structs from pass1.
403  */
404 static NODE *
405 rdnode(char *s)
406 {
407         NODE *p = talloc();
408         int ty;
409
410         if (s[0] != '"')
411                 comperr("rdnode sync error");
412         s++; s++;
ragge
1.297
413         p->n_regw = NULL;
414         p->n_ap = NULL;
415         p->n_su = p->n_lval = p->n_rval = 0;
ragge
1.293
416         p->n_op = rdint(&s);
417         p->n_type = rdint(&s);
418         p->n_qual = rdint(&s);
ragge
1.294
419         p->n_name = "";
ragge
1.296
420         SKIPWS(s);
ragge
1.293
421         ty = optype(p->n_op);
ragge
1.296
422         if (p->n_op == XASM) {
423                 int i = strlen(s);
424                 p->n_name = tmpalloc(i+1);
425                 memcpy(p->n_namesi);
426                 p->n_name[i] = 0;
427                 s += i;
428         }
429         if (ty == UTYPE) {
430                 p->n_rval = rdint(&s);
431         } else if (ty == LTYPE) {
ragge
1.293
432                 p->n_lval = strtoll(s, &s10);
433                 if (p->n_op == NAME || p->n_op == ICON) {
ragge
1.296
434                         SKIPWS(s);
435                         if (*s && *s != '+')
436                                 p->n_name = rdstr(&s);
ragge
1.293
437                 } else
ragge
1.296
438                         p->n_rval = rdint(&s);
ragge
1.293
439         }
ragge
1.296
440         SKIPWS(s);
441         if (p->n_op == XARG) {
442                 int i = strlen(s);
443                 p->n_name = tmpalloc(i+1);
444                 memcpy(p->n_namesi);
445                 p->n_name[i] = 0;
446                 s += i;
447         }
448         if (*s == '+')
449                 p->n_ap = rdattr(&s);
450         SKIPWS(s);
451         if (*s)
452                 comperr("in-line %d failed read, buf '%s'"inplineinpbuf);
453         if (ty != LTYPE)
454                 p->n_left = rdnode(rdline());
455         if (ty == BITYPE)
456                 p->n_right = rdnode(rdline());
ragge
1.293
457         return p;
458 }
459
460 /*
461  * Read everything from pass1.
462  */
463 void
464 mainp2()
465 {
466         static int foo[] = { 0 };
467         struct interpass_prolog *ipp;
468         struct interpass *ip;
469         char nam[SZIBUF], *p, *b;
470         extern char *ftitle;
471
472         while ((p = rdline()) != NULL) {
473                 b = p++;
474                 p++;
475
476                 switch (*b) {
477                 case '*'/* pass thru line */
478                         printf("%s\n"p);
479                         break;
480                 case '&'/* current filename */
481                         free(ftitle);
482                         ftitle = xstrdup(p);
483                         break;
484                 case '#':
485                         lineno = atoi(p);
486                         break;
487                 case '"':
488                         ip = malloc(sizeof(struct interpass));
489                         ip->type = IP_NODE;
490                         ip->ip_node = rdnode(b);
491                         pass2_compile(ip);
492                         break;
493                 case '^':
494                         ip = malloc(sizeof(struct interpass));
495                         ip->type = IP_DEFLAB;
496                         ip->ip_lbl = atoi(p);
497                         pass2_compile(ip);
498                         break;
499                 case '!'/* prolog */
500                         ipp = malloc(sizeof(struct interpass_prolog));
501                         ip = (void *)ipp;
502                         ip->type = IP_PROLOG;
503                         sscanf(p"%d %d %d %d %d %s", &ipp->ipp_type,
504                             &ipp->ipp_vis, &ip->ip_lbl, &ipp->ip_tmpnum,
505                             &ipp->ip_lblnumnam);
506                         ipp->ipp_name = xstrdup(nam);
507                         memset(ipp->ipp_regs, -1sizeof(ipp->ipp_regs));
508                         ipp->ipp_autos = -1;
509                         ipp->ip_labels = foo;
ragge
1.297
510                         crslab2 = ipp->ip_lblnum;
511 #ifdef TARGET_IPP_MEMBERS
512                         if (*(p = rdline()) != '(')
513                                 comperr("target member error");
514                         p += 2;
515                         target_members_read_prolog(ipp);
516                         SKIPWS(p);
517                         if (*p)
518                                 comperr("bad prolog '%s' '%s'"pinpbuf);
519 #endif
ragge
1.293
520                         pass2_compile((struct interpass *)ipp);
521                         break;
522
523                 case '%'/* epilog */
524                         ipp = malloc(sizeof(struct interpass_prolog));
525                         ip = (void *)ipp;
526                         ip->type = IP_EPILOG;
ragge
1.296
527                         ipp->ipp_autos = rdint(&p);
528                         ip->ip_lbl = rdint(&p);
529                         ipp->ip_tmpnum = rdint(&p);
530                         ipp->ip_lblnum = rdint(&p);
531                         ipp->ipp_name = rdstr(&p);
ragge
1.293
532                         memset(ipp->ipp_regs0sizeof(ipp->ipp_regs));
ragge
1.296
533                         SKIPWS(p);
534                         if (*p == '+') {
535                                 int numi;
536                                 p++;
537                                 num = rdint(&p) + 1;
538                                 ipp->ip_labels = tmpalloc(sizeof(int)*num);
539                                 for (i = 0i < numi++)
540                                         ipp->ip_labels[i] = rdint(&p);
541                                 ipp->ip_labels[num] = 0;
542                         } else
543                                 ipp->ip_labels = foo;
544                         SKIPWS(p);
545                         if (*p)
546                                 comperr("bad epilog '%s' '%s'"pinpbuf);
ragge
1.297
547 #ifdef TARGET_IPP_MEMBERS
548                         if (*(p = rdline()) != ')')
549                                 comperr("target epi member error");
550                         p += 2;
551                         target_members_read_epilog(ipp);
552                         SKIPWS(p);
553                         if (*p)
554                                 comperr("bad epilog2 '%s' '%s'"pinpbuf);
555 #endif
ragge
1.293
556                         pass2_compile((struct interpass *)ipp);
557                         break;
558
559                 default:
560                         comperr("bad string %s"b);
561                 }
562         }
563 }
564
565
566 #endif
567
ragge
1.172
568 /*
569  * Receives interpass structs from pass1.
570  */
571 void
572 pass2_compile(struct interpass *ip)
573 {
ragge
1.260
574         void deljumps(struct p2env *);
ragge
1.244
575         struct p2env *p2e = &p2env;
ragge
1.289
576         int (*addrp)[2];
ragge
1.244
577
ragge
1.172
578         if (ip->type == IP_PROLOG) {
ragge
1.244
579                 memset(p2e0sizeof(struct p2env));
580                 p2e->ipp = (struct interpass_prolog *)ip;
ragge
1.296
581                 crslab2 = p2e->ipp->ip_lblnum;
ragge
1.244
582                 DLIST_INIT(&p2e->ipoleqelem);
ragge
1.172
583         }
ragge
1.244
584         DLIST_INSERT_BEFORE(&p2e->ipoleipqelem);
ragge
1.172
585         if (ip->type != IP_EPILOG)
586                 return;
587
588 #ifdef PCC_DEBUG
589         if (e2debug) {
590                 printf("Entering pass2\n");
ragge
1.244
591                 printip(&p2e->ipole);
ragge
1.172
592         }
593 #endif
ragge
1.174
594
ragge
1.271
595         afree();
ragge
1.244
596         p2e->epp = (struct interpass_prolog *)DLIST_PREV(&p2e->ipoleqelem);
597         p2maxautooff = p2autooff = p2e->epp->ipp_autos;
ragge
1.174
598
ragge
1.241
599 #ifdef PCC_DEBUG
ragge
1.244
600         sanitychecks(p2e);
ragge
1.241
601 #endif
ragge
1.244
602         myreader(&p2e->ipole); /* local massage of input */
ragge
1.174
603
ragge
1.244
604         /*
605          * Do initial modification of the trees.  Two loops;
606          * - first, search for ADDROF of TEMPs, these must be
607          *   converterd to OREGs on stack.
608          * - second, do the actual conversions, in case of not xtemps
609          *   convert all temporaries to stack references.
610          */
ragge
1.295
611
ragge
1.244
612         if (p2e->epp->ip_tmpnum != p2e->ipp->ip_tmpnum) {
ragge
1.295
613                 addrp = xcalloc(sizeof(*addrp),
ragge
1.244
614                     (p2e->epp->ip_tmpnum - p2e->ipp->ip_tmpnum));
615                 addrp -= p2e->ipp->ip_tmpnum;
616         } else
617                 addrp = NULL;
618         if (xtemps) {
619                 DLIST_FOREACH(ip, &p2e->ipoleqelem) {
620                         if (ip->type == IP_NODE)
621                                 walkf(ip->ip_nodefindaofaddrp);
622                 }
623         }
ragge
1.246
624         DLIST_FOREACH(ip, &p2e->ipoleqelem)
ragge
1.244
625                 if (ip->type == IP_NODE)
626                         walkf(ip->ip_nodedeltempaddrp);
ragge
1.295
627         if (addrp)
628                 free(addrp + p2e->ipp->ip_tmpnum);
ragge
1.244
629
630 #ifdef PCC_DEBUG
631         if (e2debug) {
632                 printf("Efter ADDROF/TEMP\n");
633                 printip(&p2e->ipole);
634         }
635 #endif
636
ragge
1.201
637         DLIST_INIT(&prepoleqelem);
ragge
1.244
638         DLIST_FOREACH(ip, &p2e->ipoleqelem) {
ragge
1.172
639                 if (ip->type != IP_NODE)
640                         continue;
641                 canon(ip->ip_node);
ragge
1.201
642                 if ((ip->ip_node = deluseless(ip->ip_node)) == NULL) {
ragge
1.172
643                         DLIST_REMOVE(ipqelem);
ragge
1.201
644                 } else while (!DLIST_ISEMPTY(&prepoleqelem)) {
gmcgarry
1.224
645                         struct interpass *tipp;
ragge
1.201
646
gmcgarry
1.224
647                         tipp = DLIST_NEXT(&prepoleqelem);
648                         DLIST_REMOVE(tippqelem);
649                         DLIST_INSERT_BEFORE(iptippqelem);
ragge
1.201
650                 }
ragge
1.172
651         }
652
ragge
1.244
653         fixxasm(p2e); /* setup for extended asm */
ragge
1.216
654
ragge
1.244
655         optimize(p2e);
656         ngenregs(p2e);
ragge
1.172
657
ragge
1.280
658         if (xtemps && xdeljumps)
ragge
1.260
659                 deljumps(p2e);
660
ragge
1.244
661         DLIST_FOREACH(ip, &p2e->ipoleqelem)
ragge
1.172
662                 emit(ip);
663 }
664
ragge
1.124
665 void
ragge
1.125
666 emit(struct interpass *ip)
ragge
1.124
667 {
gmcgarry
1.208
668         NODE *p, *r;
669         struct optab *op;
ragge
1.149
670         int o;
ragge
1.124
671
ragge
1.125
672         switch (ip->type) {
673         case IP_NODE:
674                 p = ip->ip_node;
ragge
1.124
675
ragge
1.149
676                 nodepole = p;
ragge
1.180
677                 canon(p); /* may convert stuff after genregs */
ragge
1.287
678 #ifdef PCC_DEBUG
ragge
1.240
679                 if (c2debug > 1) {
680                         printf("emit IP_NODE:\n");
681                         fwalk(pe2print0);
682                 }
ragge
1.287
683 #endif
ragge
1.124
684                 switch (p->n_op) {
685                 case CBRANCH:
686                         /* Only emit branch insn if RESCC */
gmcgarry
1.208
687                         /* careful when an OPLOG has been elided */
688                         if (p->n_left->n_su == 0 && p->n_left->n_left != NULL) {
689                                 op = &table[TBLIDX(p->n_left->n_left->n_su)];
690                                 r = p->n_left;
691                         } else {
692                                 op = &table[TBLIDX(p->n_left->n_su)];
693                                 r = p;
694                         }
695                         if (op->rewrite & RESCC) {
ragge
1.124
696                                 o = p->n_left->n_op;
gmcgarry
1.208
697                                 gencode(rFORCC);
ragge
1.124
698                                 cbgen(op->n_right->n_lval);
gmcgarry
1.208
699                         } else {
700                                 gencode(rFORCC);
701                         }
ragge
1.124
702                         break;
703                 case FORCE:
ragge
1.151
704                         gencode(p->n_leftINREGS);
ragge
1.124
705                         break;
ragge
1.216
706                 case XASM:
707                         genxasm(p);
708                         break;
ragge
1.124
709                 default:
710                         if (p->n_op != REG || p->n_type != VOID/* XXX */
711                                 gencode(pFOREFF); /* Emit instructions */
712                 }
713
ragge
1.125
714                 tfree(p);
715                 break;
ragge
1.124
716         case IP_PROLOG:
717                 prologue((struct interpass_prolog *)ip);
718                 break;
719         case IP_EPILOG:
720                 eoftn((struct interpass_prolog *)ip);
ragge
1.174
721                 p2maxautooff = p2autooff = AUTOINIT/SZCHAR;
ragge
1.124
722                 break;
723         case IP_DEFLAB:
724                 deflab(ip->ip_lbl);
725                 break;
726         case IP_ASM:
gmcgarry
1.229
727                 printf("%s"ip->ip_asm);
ragge
1.124
728                 break;
729         default:
ragge
1.216
730                 cerror("emit %d"ip->type);
ragge
1.124
731         }
ragge
1.123
732 }
ragge
1.124
733
ragge
1.30
734 #ifdef PCC_DEBUG
ragge
1.1
735 char *cnames[] = {
736         "SANY",
737         "SAREG",
738         "SBREG",
ragge
1.153
739         "SCREG",
740         "SDREG",
ragge
1.1
741         "SCC",
742         "SNAME",
743         "SCON",
744         "SFLD",
745         "SOREG",
746         "STARNM",
747         "STARREG",
748         "INTEMP",
749         "FORARG",
750         "SWADD",
751         0,
ragge
1.72
752 };
ragge
1.1
753
ragge
1.2
754 /*
755  * print a nice-looking description of cookie
756  */
ragge
1.70
757 char *
ragge
1.2
758 prcook(int cookie)
759 {
ragge
1.70
760         static char buf[50];
ragge
1.1
761         int iflag;
762
ragge
1.70
763         if (cookie & SPECIAL) {
764                 switch (cookie) {
765                 case SZERO:
766                         return "SZERO";
767                 case SONE:
768                         return "SONE";
769                 case SMONE:
770                         return "SMONE";
771                 default:
ragge
1.200
772                         snprintf(bufsizeof(buf), "SPECIAL+%d"cookie & ~SPECIAL);
ragge
1.70
773                         return buf;
ragge
1.1
774                 }
ragge
1.70
775         }
ragge
1.1
776
777         flag = 0;
ragge
1.70
778         buf[0] = 0;
779         for (i = 0cnames[i]; ++i) {
780                 if (cookie & (1<<i)) {
781                         if (flag)
ragge
1.200
782                                 strlcat(buf"|"sizeof(buf));
ragge
1.1
783                         ++flag;
ragge
1.200
784                         strlcat(bufcnames[i], sizeof(buf));
ragge
1.1
785                 }
ragge
1.70
786         }
787         return buf;
788 }
ragge
1.30
789 #endif
ragge
1.1
790
ragge
1.151
791 int
ragge
1.69
792 geninsn(NODE *pint cookie)
793 {
ragge
1.71
794         NODE *p1, *p2;
ragge
1.236
795         int qorv = 0;
ragge
1.69
796
797 #ifdef PCC_DEBUG
plunky
1.278
798         if (o2debug) {
ragge
1.70
799                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
800                 fwalk(pe2print0);
801         }
802 #endif
803
ragge
1.236
804         q = cookie & QUIET;
805         cookie &= ~QUIET/* XXX - should not be necessary */
806
ragge
1.69
807 again:  switch (o = p->n_op) {
ragge
1.71
808         case EQ:
809         case NE:
810         case LE:
811         case LT:
812         case GE:
813         case GT:
814         case ULE:
815         case ULT:
816         case UGE:
817         case UGT:
gmcgarry
1.208
818                 p1 = p->n_left;
819                 p2 = p->n_right;
ragge
1.265
820                 if (p2->n_op == ICON && p2->n_lval == 0 && *p2->n_name == 0 &&
ragge
1.256
821                     (dope[p1->n_op] & (FLOFLG|DIVFLG|SIMPFLG|SHFFLG))) {
ragge
1.236
822 #ifdef mach_pdp11 /* XXX all targets? */
823                         if ((rv = geninsn(p1FORCC|QUIET)) != FFAIL)
824                                 break;
825 #else
826                         if (findops(p1FORCC) > 0)
gmcgarry
1.208
827                                 break;
ragge
1.236
828 #endif
gmcgarry
1.208
829                 }
ragge
1.159
830                 rv = relops(p);
831                 break;
ragge
1.71
832
ragge
1.69
833         case PLUS:
834         case MINUS:
835         case MUL:
836         case DIV:
837         case MOD:
838         case AND:
839         case OR:
840         case ER:
841         case LS:
842         case RS:
ragge
1.151
843                 rv = findops(pcookie);
844                 break;
ragge
1.77
845
ragge
1.69
846         case ASSIGN:
ragge
1.236
847 #ifdef FINDMOPS
848                 if ((rv = findmops(pcookie)) != FFAIL)
849                         break;
850                 /* FALLTHROUGH */
851 #endif
ragge
1.174
852         case STASG:
ragge
1.151
853                 rv = findasg(pcookie);
854                 break;
ragge
1.159
855
ragge
1.178
856         case UMUL/* May turn into an OREG */
ragge
1.179
857                 rv = findumul(pcookie);
858                 break;
859
ragge
1.69
860         case REG:
ragge
1.144
861         case TEMP:
ragge
1.72
862         case NAME:
ragge
1.71
863         case ICON:
ragge
1.213
864         case FCON:
ragge
1.69
865         case OREG:
ragge
1.152
866                 rv = findleaf(pcookie);
867                 break;
ragge
1.69
868
ragge
1.172
869         case STCALL:
870         case CALL:
871                 /* CALL arguments are handled special */
872                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
ragge
1.239
873                         (void)geninsn(p1->n_rightFOREFF);
874                 (void)geninsn(p1FOREFF);
ragge
1.172
875                 /* FALLTHROUGH */
ragge
1.206
876         case FLD:
ragge
1.86
877         case COMPL:
ragge
1.85
878         case UMINUS:
ragge
1.71
879         case PCONV:
880         case SCONV:
ragge
1.198
881 /*      case INIT: */
ragge
1.70
882         case GOTO:
883         case FUNARG:
ragge
1.172
884         case STARG:
ragge
1.72
885         case UCALL:
ragge
1.103
886         case USTCALL:
ragge
1.207
887         case ADDROF:
ragge
1.155
888                 rv = finduni(pcookie);
889                 break;
ragge
1.69
890
ragge
1.71
891         case CBRANCH:
892                 p1 = p->n_left;
893                 p2 = p->n_right;
gmcgarry
1.251
894                 p1->n_label = (int)p2->n_lval;
ragge
1.239
895                 (void)geninsn(p1FORCC);
ragge
1.187
896                 p->n_su = 0;
ragge
1.71
897                 break;
898
ragge
1.187
899         case FORCE/* XXX needed? */
ragge
1.239
900                 (void)geninsn(p->n_leftINREGS);
ragge
1.187
901                 p->n_su = 0/* su calculations traverse left */
ragge
1.71
902                 break;
903
ragge
1.216
904         case XASM:
905                 for (p1 = p->n_leftp1->n_op == CMp1 = p1->n_left)
ragge
1.239
906                         (void)geninsn(p1->n_rightFOREFF);
907                 (void)geninsn(p1FOREFF);
ragge
1.216
908                 break;  /* all stuff already done? */
909
910         case XARG:
911                 /* generate code for correct class here */
912                 break;
913
ragge
1.69
914         default:
ragge
1.174
915                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
916         }
ragge
1.236
917         if (rv == FFAIL && !q)
ragge
1.160
918                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
919         if (rv == FRETRY)
920                 goto again;
ragge