Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20160402094712

Diff

Diff from 1.300 to:

Annotations

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

Annotated File View

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