Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050220124042

Diff

Diff from 1.121 to:

Annotations

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

Annotated File View

ragge
1.121
1 /*      $Id: reader.c,v 1.121 2005/02/20 12:40:42 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
63 # include "pass2.h"
64
ragge
1.70
65 #include <string.h>
ragge
1.71
66 #include <stdarg.h>
ragge
1.94
67 #include <stdlib.h>
ragge
1.70
68
ragge
1.1
69 /*      some storage declarations */
70 int nrecur;
71 int lflag;
ragge
1.9
72 int x2debug;
ragge
1.1
73 int udebug = 0;
ragge
1.32
74 int ftnno;
ragge
1.103
75 int thisline;
ragge
1.72
76 int fregs;
ragge
1.1
77
ragge
1.72
78 NODE *nodepole;
ragge
1.91
79 int saving;
ragge
1.23
80
ragge
1.10
81 int e2print(NODE *pint downint *aint *b);
ragge
1.37
82 void saveip(struct interpass *ip);
83 void deljumps(void);
ragge
1.40
84 void deltemp(NODE *p);
ragge
1.97
85 void mkhardops(NODE *p);
ragge
1.37
86 void optdump(struct interpass *ip);
ragge
1.40
87 void cvtemps(struct interpass *epil);
ragge
1.69
88 int findops(NODE *pint);
89 int findasg(NODE *pint);
90 int finduni(NODE *pint);
91 int findleaf(NODE *pint);
ragge
1.65
92 int relops(NODE *p);
93 int asgops(NODE *pint);
ragge
1.72
94 NODE *store(NODE *);
ragge
1.104
95 void rcount(void);
ragge
1.65
96
ragge
1.72
97 static void gencode(NODE *pint cookie);
ragge
1.69
98
99 static char *ltyp[] = { """LREG""LOREG""LTEMP" };
100 static char *rtyp[] = { """RREG""ROREG""RTEMP" };
ragge
1.37
101
ragge
1.121
102 /* used when removing nodes */
103 struct tmpsave {
104         struct tmpsave *next;
105         CONSZ tempaddr;
106         int tempno;
107 } *tmpsave;
108
ragge
1.46
109 #define DELAYS 20
110 NODE *deltrees[DELAYS];
111 int deli;
ragge
1.26
112
113 #ifdef PCC_DEBUG
114 static void
115 cktree(NODE *p)
116 {
117         if (p->n_op > MAXOP)
118                 cerror("op %d slipped through"p->n_op);
ragge
1.35
119         if (p->n_op == CBRANCH && !logop(p->n_left->n_op))
120                 cerror("not logop branch");
ragge
1.47
121         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
122                 cerror("asgop %d slipped through"p->n_op);
ragge
1.117
123         if (p->n_op ==CALL)
ragge
1.78
124                 cerror("non-UCALL node");
ragge
1.26
125 }
126 #endif
ragge
1.8
127
ragge
1.17
128 static void
ragge
1.2
129 p2compile(NODE *p)
130 {
ragge
1.46
131         int i;
132
ragge
1.15
133 #if !defined(MULTIPASS)
134         extern char *ftitle;
135 #endif
ragge
1.1
136
ragge
1.14
137         if (lflag)
138                 lineid(linenoftitle);
139
ragge
1.1
140         /* generate code for the tree p */
ragge
1.26
141 #ifdef PCC_DEBUG
142         walkf(pcktree);
ragge
1.79
143         if (e2debug) {
144                 fprintf(stderr"Entering pass2\n");
ragge
1.26
145                 fwalk(pe2print0);
ragge
1.79
146         }
ragge
1.26
147 #endif
ragge
1.25
148
ragge
1.1
149         nrecur = 0;
ragge
1.46
150         deli = 0;
151         delay(p);
ragge
1.25
152         codgen(pFOREFF);
ragge
1.46
153         for (i = 0i < deli; ++i)
154                 codgen(deltrees[i], FOREFF);  /* do the rest */
ragge
1.75
155         tfree(p);
ragge
1.46
156 }
157
158 /* look for delayable ++ and -- operators */
159 void
160 delay(NODE *p)
161 {
162         int ty = optype(p->n_op);
163
164         switch (p->n_op) {
ragge
1.68
165         case UCALL:
ragge
1.46
166         case STCALL:
ragge
1.68
167         case USTCALL:
ragge
1.46
168         case FORTCALL:
ragge
1.68
169         case UFORTCALL:
ragge
1.46
170         case CBRANCH:
171                 /* for the moment, don7t delay past a conditional context, or
172                  * inside of a call */
173                 return;
174
ragge
1.67
175         case UMUL:
ragge
1.46
176                 /* if *p++, do not rewrite */
177                 ifautoincrp ) ) return;
178                 break;
179
180         case INCR:
181         case DECR:
ragge
1.83
182                 break;
ragge
1.46
183                 ifdeltestp ) ){
184                         ifdeli < DELAYS ){
185                                 register NODE *q;
186                                 deltrees[deli++] = tcopy(p);
187                                 q = p->n_left;
ragge
1.58
188                                 nfree(p->n_right); /* zap constant */
ragge
1.46
189                                 *p = *q;
ragge
1.58
190                                 nfree(q);
ragge
1.46
191                                 return;
192                         }
ragge
1.83
193                 }
ragge
1.46
194
ragge
1.83
195         }
ragge
1.46
196
197         if (ty == BITYPE)
198                 delay(p->n_right);
199         if (ty != LTYPE)
200                 delay(p->n_left);
ragge
1.2
201 }
ragge
1.1
202
ragge
1.89
203 /*
204  * Check if a node has side effects.
205  */
206 static int
207 isuseless(NODE *n)
208 {
209         switch (n->n_op) {
210         case FUNARG:
211         case UCALL:
212         case UFORTCALL:
213         case FORCE:
214         case INIT:
215         case ASSIGN:
216         case INCR:
217         case DECR:
218         case CALL:
219         case FORTCALL:
220         case CBRANCH:
221         case RETURN:
222         case GOTO:
223         case STCALL:
224         case USTCALL:
225         case STASG:
226         case STARG:
227                 return 0;
228         default:
229                 return 1;
230         }
231 }
232
233 static NODE *
234 deluseless(NODE *p)
235 {
236         struct interpass *ip;
237         NODE *l, *r;
238
239         if (optype(p->n_op) == LTYPE) {
240                 nfree(p);
241                 return NULL;
242         }
243         if (isuseless(p) == 0)
244                 return p;
245
246         if (optype(p->n_op) == UTYPE) {
247                 l = p->n_left;
248                 nfree(p);
249                 return deluseless(l);
250         }
251
252         /* Be sure that both leaves may be valid */
253         l = deluseless(p->n_left);
254         r = deluseless(p->n_right);
255         nfree(p);
256         if (l && r) {
257                 /* Put left on queue first */
258                 ip = tmpalloc(sizeof(*ip));
259                 ip->type = IP_NODE;
260                 ip->lineno = 0/* XXX */
261                 ip->ip_node = l;
262                 pass2_compile(ip);
263                 return r;
264         } else if (l)
265                 return l;
266         else if (r)
267                 return r;
268         return NULL;
269 }
270
ragge
1.113
271 #ifdef TAILCALL
272 int earlylabretlab2;
273 char *cftname;
274 #endif
ragge
1.17
275
ragge
1.2
276 void
ragge
1.17
277 pass2_compile(struct interpass *ip)
278 {
pj
1.114
279 #ifdef TAILCALL
ragge
1.113
280         NODE *p;
pj
1.114
281 #endif
ragge
1.113
282
283 #ifdef TAILCALL
284         if (xtailcallflag) {
285                 if (earlylab == -1) {
286                         if (ip->type != IP_DEFLAB)
287                                 comperr("missing deflab");
288                         earlylab = ip->ip_lbl;
289                 } else if (ip->type == IP_PROLOG) {
290                         earlylab = -1;
291                         retlab2 = ip->ip_lbl;
292                         cftname = ((struct interpass_prolog *)ip)->ipp_name;
293                 } else if (ip->type == IP_EPILOG)
294                         earlylab = 0;
295         }
296 #endif
297
ragge
1.89
298         if (ip->type == IP_NODE) {
ragge
1.103
299                 thisline = ip->lineno;
ragge
1.90
300 #ifdef PCC_DEBUG
301                 if (e2debug) {
ragge
1.92
302                         fprintf(stderr"pass2 called on:\n");
ragge
1.90
303                         fwalk(ip->ip_nodee2print0);
304                 }
305 #endif
ragge
1.89
306                 ip->ip_node = deluseless(ip->ip_node);
307                 if (ip->ip_node == NULL)
308                         return;
ragge
1.103
309
ragge
1.105
310 # ifdef MYREADER
311         MYREADER(ip->ip_node);  /* do your own laundering of the input */
312 # endif
ragge
1.113
313
314 #ifdef TAILCALL
315                 /* Check for tail call optimization early */
316                 if (xtailcallflag) {
317                         static struct interpass *ipp;
318                         static int passany;
319
320                         if (passany == 0) {
321                                 p = ip->ip_node;
322                                 if (ipp) {
323                                         if (p->n_op == GOTO &&
324                                             p->n_left->n_lval == retlab2) {
325                                                 passany = 1;
326                                                 mktailopt(ippip);
327                                                 passany = 0;
328                                                 ipp = NULL;
329                                                 return;
330                                         } else {
331                                                 passany = 1;
332                                                 pass2_compile(ipp);
333                                                 passany = 0;
334                                         }
335                                         ipp = NULL;
336                                 } else if (p->n_op == FORCE &&
337                                     callop(p->n_left->n_op)) {
338                                         ipp = ip;
339                                         return;
340                                 }
341                         }
342                 }
343 #endif
344
ragge
1.103
345                 mkhardops(ip->ip_node);
ragge
1.105
346 //printf("gencall...\n");
347 //fwalk(ip->ip_node, e2print, 0);
348                 gencall(ip->ip_nodeNIL);
ragge
1.97
349 #ifdef notyet
350                 optim1(ip->ip_node);
351 #endif
ragge
1.89
352         }
ragge
1.37
353         if (Oflag) {
354                 if (ip->type == IP_PROLOG)
355                         saving++;
356                 if (saving)
357                         return saveip(ip);
358         }
ragge
1.17
359         switch (ip->type) {
360         case IP_NODE:
361                 p2compile(ip->ip_node);
ragge
1.21
362                 tfree(ip->ip_node);
ragge
1.17
363                 break;
364         case IP_PROLOG:
ragge
1.113
365                 prologue((struct interpass_prolog *)ip);
ragge
1.17
366                 break;
367         case IP_EPILOG:
ragge
1.113
368                 eoftn((struct interpass_prolog *)ip);
ragge
1.121
369                 tmpsave = NULL/* Always forget old nodes */
ragge
1.18
370                 break;
371         case IP_DEFLAB:
372                 deflab(ip->ip_lbl);
373                 break;
ragge
1.39
374         case IP_ASM:
ragge
1.106
375                 printf("\t%s\n"ip->ip_asm);
ragge
1.18
376                 break;
ragge
1.17
377         default:
378                 cerror("pass2_compile %d"ip->type);
379         }
380 }
381
ragge
1.2
382 /*
383  * generate the code for p;
ragge
1.72
384  * store may call codgen recursively
ragge
1.2
385  * cookie is used to describe the context
386  */
387 void
388 codgen(NODE *pint cookie)
389 {
ragge
1.71
390         int o;
ragge
1.70
391
ragge
1.104
392         rcount();
ragge
1.71
393         nodepole = p;
ragge
1.69
394         canon(p);  /* creats OREG from * if possible and does sucomp */
395 #ifdef PCC_DEBUG
396         if (e2debug) {
ragge
1.92
397                 fprintf(stderr"geninsn called on:\n");
ragge
1.69
398                 fwalk(pe2print0);
399         }
400 #endif
ragge
1.70
401         do {
402                 geninsn(pcookie); /* Assign instructions for tree */
ragge
1.78
403 #ifdef PCC_DEBUG
404                 if (udebug) {
ragge
1.92
405                         fprintf(stderr"sucomp called on:\n");
ragge
1.78
406                         fwalk(pe2print0);
407                 }
408 #endif
ragge
1.72
409         } while (sucomp(p) < 0);  /* Calculate sub-tree evaluation order */
ragge
1.69
410 #ifdef PCC_DEBUG
411         if (udebug) {
ragge
1.92
412                 fprintf(stderr"genregs called on:\n");
ragge
1.69
413                 fwalk(pe2print0);
414         }
415 #endif
ragge
1.72
416         /*
417          * When here it is known that the tree can be evaluated.
418          * Assign registers for all instructions.
419          */
ragge
1.69
420         genregs(p); /* allocate registers for instructions */
ragge
1.103
421         mygenregs(p);
ragge
1.72
422 #ifdef PCC_DEBUG
423         if (udebug) {
ragge
1.92
424                 fprintf(stderr"gencode called on:\n");
ragge
1.72
425                 fwalk(pe2print0);
426         }
427 #endif
ragge
1.71
428         switch (p->n_op) {
429         case CBRANCH:
ragge
1.97
430                 /* Only emit branch insn if RESCC */
431                 if (table[TBLIDX(p->n_left->n_su)].rewrite & RESCC) {
432                         o = p->n_left->n_op;
433                         gencode(pFORCC);
434                         cbgen(op->n_right->n_lval);
435                 } else
436                         gencode(pFORCC);
ragge
1.71
437                 break;
438         case FORCE:
ragge
1.72
439                 gencode(p->n_leftINTAREG|INTBREG);
ragge
1.71
440                 break;
441         default:
442                 if (p->n_op != REG || p->n_type != VOID/* XXX */
ragge
1.72
443                         gencode(pFOREFF); /* Emit instructions */
ragge
1.71
444         }
ragge
1.2
445 }
ragge
1.1
446
ragge
1.30
447 #ifdef PCC_DEBUG
ragge
1.1
448 char *cnames[] = {
449         "SANY",
450         "SAREG",
451         "STAREG",
452         "SBREG",
453         "STBREG",
454         "SCC",
455         "SNAME",
456         "SCON",
457         "SFLD",
458         "SOREG",
459         "STARNM",
460         "STARREG",
461         "INTEMP",
462         "FORARG",
463         "SWADD",
464         0,
ragge
1.72
465 };
ragge
1.1
466
ragge
1.2
467 /*
468  * print a nice-looking description of cookie
469  */
ragge
1.70
470 char *
ragge
1.2
471 prcook(int cookie)
472 {
ragge
1.70
473         static char buf[50];
ragge
1.1
474         int iflag;
475
ragge
1.70
476         if (cookie & SPECIAL) {
477                 switch (cookie) {
478                 case SZERO:
479                         return "SZERO";
480                 case SONE:
481                         return "SONE";
482                 case SMONE:
483                         return "SMONE";
484                 default:
485                         sprintf(buf"SPECIAL+%d"cookie & ~SPECIAL);
486                         return buf;
ragge
1.1
487                 }
ragge
1.70
488         }
ragge
1.1
489
490         flag = 0;
ragge
1.70
491         buf[0] = 0;
492         for (i = 0cnames[i]; ++i) {
493                 if (cookie & (1<<i)) {
494                         if (flag)
495                                 strcat(buf"|");
ragge
1.1
496                         ++flag;
ragge
1.70
497                         strcat(bufcnames[i]);
ragge
1.1
498                 }
ragge
1.70
499         }
500         return buf;
501 }
ragge
1.1
502
ragge
1.30
503 #endif
ragge
1.1
504
505 int odebug = 0;
506
ragge
1.2
507 void
ragge
1.69
508 geninsn(NODE *pint cookie)
509 {
ragge
1.71
510         NODE *p1, *p2;
ragge
1.69
511         int orv;
512
513 #ifdef PCC_DEBUG
514         if (odebug) {
ragge
1.70
515                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
516                 fwalk(pe2print0);
517         }
518 #endif
519
520 again:  switch (o = p->n_op) {
ragge
1.71
521         case EQ:
522         case NE:
523         case LE:
524         case LT:
525         case GE:
526         case GT:
527         case ULE:
528         case ULT:
529         case UGE:
530         case UGT:
531                 if ((rv = relops(p)) < 0) {
532                         if (setbin(p))
533                                 goto again;
534                         goto failed;
535                 }
536                 goto sw;
537
ragge
1.69
538         case PLUS:
539         case MINUS:
540         case MUL:
541         case DIV:
542         case MOD:
543         case AND:
544         case OR:
545         case ER:
546         case LS:
547         case RS:
548                 if ((rv = findops(pcookie)) < 0) {
549                         if (setbin(p))
550                                 goto again;
551                         goto failed;
552                 }
ragge
1.71
553                 goto sw;
ragge
1.77
554
555         case INCR:
556         case DECR:
557                 if ((rv = findops(pcookie)) < 0) {
558                         if (setbin(p))
559                                 goto again;
ragge
1.96
560                 } else {
561                         /* Do tree rewriting to ensure correct incr */
562                         if ((rv & LMASK) != LREG)
563                                 goto sw;
564                 }
ragge
1.77
565                 /*
566                  * Rewrite x++ to (x = x + 1) -1;
567                  */
568                 p1 = p->n_left;
569                 p->n_op = o == INCR ? MINUS : PLUS;
570                 /* Assign node */
571                 p2 = talloc();
572                 p2->n_type = p->n_type;
573                 p2->n_name = "";
574                 p2->n_op = ASSIGN;
575                 p->n_left = p2;
576                 p->n_left->n_left = p1;
577                 /* incr/decr node */
578                 p2 = talloc();
579                 p2->n_type = p->n_type;
580                 p2->n_name = "";
581                 p2->n_op = o == INCR ? PLUS : MINUS;
582                 p->n_left->n_right = p2;
583                 /* const one node */
584                 p->n_left->n_right->n_right = tcopy(p->n_right);
585                 /* input tree */
586                 p1 = tcopy(p1);
587                 /* idstrip(p1); */
588                 p->n_left->n_right->n_left = p1;
ragge
1.108
589                 canon(p); /* if fields involved */
ragge
1.77
590                 goto again;
ragge
1.71
591
ragge
1.69
592         case ASSIGN:
ragge
1.71
593                 if ((rv = findasg(pcookie)) < 0) {
ragge
1.69
594                         if (setasg(pcookie))
595                                 goto again;
596                         goto failed;
597                 }
598                 /*
599                  * Do subnodes conversions (if needed).
600                  */
ragge
1.71
601 sw:             switch (rv & LMASK) {
ragge
1.69
602                 case LREG:
603                         geninsn(p->n_leftINTAREG|INTBREG);
604                         break;
605                 case LOREG:
ragge
1.102
606                         if (p->n_left->n_op == FLD) {
607                                 offstar(p->n_left->n_left->n_left);
608                                 p->n_left->n_left->n_su = -1;
609                         } else
610                                 offstar(p->n_left->n_left);
ragge
1.69
611                         p->n_left->n_su = -1;
612                         break;
613                 case LTEMP:
614                         geninsn(p->n_leftINTEMP);
615                         break;
616                 }
617
618                 switch (rv & RMASK) {
619                 case RREG:
620                         geninsn(p->n_rightINTAREG|INTBREG);
621                         break;
622                 case ROREG:
623                         offstar(p->n_right->n_left);
624                         p->n_right->n_su = -1;
625                         break;
626                 case RTEMP:
627                         geninsn(p->n_rightINTEMP);
628                         break;
629                 }
630                 p->n_su = rv;
631                 break;
632
633         case REG:
634                 if (istnode(p))
ragge
1.71
635                         comperr("geninsn REG");
ragge
1.69
636                 /* FALLTHROUGH */
ragge
1.72
637         case NAME:
ragge
1.71
638         case ICON:
ragge
1.69
639         case OREG:
ragge
1.83
640 #if 0
ragge
1.69
641                 if ((cookie & (INTAREG|INTBREG)) == 0)
ragge
1.71
642                         comperr("geninsn OREG, node %p"p);
ragge
1.83
643 #endif
ragge
1.69
644                 if ((rv = findleaf(pcookie)) < 0) {
645                         if (setasg(pcookie))
646                                 goto again;
647                         goto failed;
648                 }
649                 p->n_su = rv;
650                 break;
651
ragge
1.82
652         case UMUL:
653                 /*
654                  * If we end up here with an UMUL, try to fold it into
655                  * an OREG anyway.
656                  */
ragge
1.86
657                 if (p->n_type == STRTY) {
658                         /* XXX - what to do here? */
659                         geninsn(p->n_leftcookie);
660                         p->n_su = -1;
661                         break;
662                 }
663 #if 0
ragge
1.82
664                 if ((cookie & INTAREG) == 0)
665                         comperr("bad umul!");
ragge
1.86
666 #endif
ragge
1.84
667                 if (offstar(p->n_left)) {
668                         p->n_op = OREG;
669                         if ((rv = findleaf(pcookie)) < 0)
670                                 comperr("bad findleaf"); /* XXX */
671                         p->n_op = UMUL;
672                         p->n_su = rv | LOREG;
673                         break;
674                 }
ragge
1.109
675                 /* FALLTHROUGH */
ragge
1.82
676
ragge
1.86
677         case COMPL:
ragge
1.85
678         case UMINUS:
ragge
1.71
679         case PCONV:
680         case SCONV:
681         case INIT:
ragge
1.70
682         case GOTO:
683         case FUNARG:
ragge
1.72
684         case UCALL:
ragge
1.103
685         case USTCALL:
ragge
1.69
686                 if ((rv = finduni(pcookie)) < 0) {
687                         if (setuni(pcookie))
688                                 goto again;
689                         goto failed;
690                 }
691                 switch (rv & LMASK) {
692                 case LREG:
ragge
1.109
693                         cookie = INTAREG|INTBREG;
694                         if (rv & LBREG/* XXX - make prettier */
695                                 cookie = INTBREG;
696                         geninsn(p->n_leftcookie);
ragge
1.69
697                         break;
ragge
1.70
698                 case LOREG:
699                         offstar(p->n_left->n_left);
700                         p->n_left->n_su = -1;
701                         break;
702                 case LTEMP:
703                         geninsn(p->n_leftINTEMP);
704                         break;
ragge
1.69
705                 }
706                 p->n_su = rv;
707                 break;
708
ragge
1.71
709         case CBRANCH:
710                 p1 = p->n_left;
711                 p2 = p->n_right;
712                 p1->n_label = p2->n_lval;
713                 o = p1->n_op;
714                 geninsn(p1FORCC);
715                 p->n_su = -1/* su calculations traverse left */
716                 break;
717
718         case FORCE:
719                 geninsn(p->n_leftINTAREG|INTBREG);
720                 p->n_su = -1/* su calculations traverse left */
721                 break;
722
ragge
1.69
723         default:
ragge
1.72
724                 comperr("geninsn: bad op %d, node %p"op);
ragge
1.69
725         }
726         return;
727
728 failed:
ragge
1.84
729         comperr("Cannot generate code, node %p op %s"popst[p->n_op]);
730
ragge
1.69
731 }
732
ragge
1.72
733 /*
734  * Store a given subtree in a temporary location.
735  * Return an OREG node where it is located.
736  */
737 NODE *
738 store(NODE *p)
ragge
1.2
739 {
ragge
1.72
740         NODE *q, *r, *s;
ragge
1.49
741
ragge
1.72
742         q = talloc();
743         r = talloc();
744         s = talloc();
745         q->n_op = OREG;
746         q->n_type = p->n_type;
747         q->n_name = "";
748         q->n_rval = FPREG;
749         q->n_lval = BITOOR(freetemp(szty(p->n_type)));
750         *r = *q;
751         s->n_op = ASSIGN;
752         s->n_type = p->n_type;
753         s->n_name = "";
754         s->n_left = q;
755         s->n_right = p;
756         codgen(sFOREFF);
ragge
1.80
757         tfree(s);
ragge
1.72
758         return r;
ragge
1.8
759 }
ragge
1.1
760
ragge
1.69
761 /*
ragge
1.75
762  * Rewrite node after instruction emit.
763  */
764 static void
765 rewrite(NODE *pint rewrite)
766 {
ragge
1.79
767         NODE *l, *r;
768         int o;
769
ragge
1.75
770         if (p->n_su == -1)
771                 comperr("rewrite");
772
ragge
1.80
773         l = getlr(p'L');
774         r = getlr(p'R');
ragge
1.79
775         o = p->n_op;
ragge
1.75
776         p->n_op = REG;
ragge
1.76
777         p->n_lval = 0;
ragge
1.95
778         p->n_name = "";
ragge
1.79
779         if (rewrite & RLEFT) {
780 #ifdef PCC_DEBUG
781                 if (l->n_op != REG)
782                         comperr("rewrite left");
783 #endif
784                 p->n_rval = l->n_rval;
785         } else if (rewrite & RRIGHT) {
786 #ifdef PCC_DEBUG
787                 if (r->n_op != REG)
788                         comperr("rewrite right");
789 #endif
790                 p->n_rval = r->n_rval;
791         } else if (rewrite & RESC1)
792                 p->n_rval = p->n_rall;
793         else if (rewrite & RESC2)
794                 p->n_rval = p->n_rall + szty(p->n_type);
ragge
1.75
795         else if (rewrite & RESC3)
ragge
1.79
796                 p->n_rval = p->n_rall + 2*szty(p->n_type);
ragge
1.99
797         else if (p->n_su == DORIGHT)
798                 p->n_rval = l->n_rval/* XXX special */
ragge
1.79
799         if (optype(o) != LTYPE)
800                 tfree(l);
801         if (optype(o) == BITYPE)
802                 tfree(r);
ragge
1.75
803 }
804
ragge
1.69
805 void
ragge
1.72
806 gencode(NODE *pint cookie)
ragge
1.69
807 {
808         struct optab *q = &table[TBLIDX(p->n_su)];
809
810         if (p->n_su == -1/* For OREGs and similar */
ragge
1.72
811                 return gencode(p->n_leftcookie);
ragge
1.69
812
813         if (p->n_su & DORIGHT) {
ragge
1.72
814                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
815                 if ((p->n_su & RMASK) == ROREG)
816                         canon(p);
817         }
818         if (p->n_su & LMASK) {
ragge
1.72
819                 gencode(p->n_leftINTAREG|INTBREG);
ragge
1.69
820                 if ((p->n_su & LMASK) == LOREG)
821                         canon(p);
822         }
823         if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
ragge
1.72
824                 gencode(p->n_rightINTAREG|INTBREG);
ragge
1.69
825                 if ((p->n_su & RMASK) == ROREG)
826                         canon(p);
827         }
ragge
1.72
828         expand(pcookieq->cstring);
ragge
1.75
829         rewrite(pq->rewrite);
ragge
1.2
830 }
ragge
1.1
831
832 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
833
ragge
1.2
834 void
835 rcount()
836 /* count recursions */
ragge
1.1
837         if( ++nrecur > NRECUR ){
838                 cerror"expression causes compiler loop: try simplifying" );
839         }
ragge
1.2
840 }
ragge
1.1
841
ragge
1.30
842 #ifdef PCC_DEBUG
ragge
1.87
843 #undef  PRTABLE
ragge
1.2
844 int
ragge
1.8
845 e2print(NODE *pint downint *aint *b)
ragge
1.2
846 {
ragge
1.85
847 #ifdef PRTABLE
848         extern int tablesize;
849 #endif
ragge
1.1
850
851         *a = *b = down+1;
852         whiledown >= 2 ){
ragge
1.71
853                 fprintf(stderr"\t");
ragge
1.1
854                 down -= 2;
855                 }
ragge
1.71
856         ifdown-- ) fprintf(stderr"    " );
ragge
1.1
857
858
ragge
1.71
859         fprintf(stderr"%p) %s"popst[p->n_op] );
ragge
1.13
860         switchp->n_op ) { /* special cases */
ragge
1.1
861
862         case REG:
ragge
1.71
863                 fprintf(stderr" %s"rnames[p->n_rval] );
ragge
1.1
864                 break;
865
ragge
1.121
866         case TEMP:
867                 fprintf(stderr" " CONFMTp->n_lval);
868                 break;
869
ragge
1.1
870         case ICON:
871         case NAME:
872         case OREG:
ragge
1.71
873                 fprintf(stderr" " );
874                 adrput(stderrp );
ragge
1.1
875                 break;
876
877         case STCALL:
ragge
1.68
878         case USTCALL:
ragge
1.1
879         case STARG:
880         case STASG:
ragge
1.71
881                 fprintf(stderr" size=%d"p->n_stsize );
882                 fprintf(stderr" align=%d"p->n_stalign );
ragge
1.1
883                 break;
884                 }
885
ragge
1.71
886         fprintf(stderr", " );
887         tprint(stderrp->n_typep->n_qual);
888         fprintf(stderr", " );
889         ifp->n_rall == NOPREF ) fprintf(stderr"NOPREF" );
ragge
1.1
890         else {
ragge
1.71
891                 ifp->n_rall & MUSTDO ) fprintf(stderr"MUSTDO " );
892                 else fprintf(stderr"PREF " );
893                 fprintf(stderr"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
894                 }
ragge
1.85
895         fprintf(stderr", SU= %d(%s,%s,%s,%s)\n",
896             TBLIDX(p->n_su), 
897 #ifdef PRTABLE
898             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
899             table[TBLIDX(p->n_su)].cstring : "",
900 #else
901             "",
902 #endif
903             ltyp[LMASK&p->n_su],
ragge
1.70
904             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
905         return 0;
906 }
ragge
1.30
907 #endif
ragge
1.1
908
909 #ifndef FIELDOPS
ragge
1.7
910 /*
911  * do this if there is no special hardware support for fields
912  */
913 static int
914 ffld(NODE *pint downint *down1int *down2 )
915 {
916         /*
917          * look for fields that are not in an lvalue context,
918          * and rewrite them...
919          */
920         NODE *shp;
921         int sovty;
ragge
1.1
922
ragge
1.13
923         *down1 =  asgopp->n_op );
ragge
1.1
924         *down2 = 0;
925
ragge
1.13
926         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
927
ragge
1.7
928                 if( !rewfld(p) ) return 0;
ragge
1.1
929
ragge
1.48
930                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
931                 v = p->n_rval;
ragge
1.1
932                 s = UPKFSZ(v);
933 # ifdef RTOLBYTES
934                 o = UPKFOFF(v);  /* amount to shift */
935 # else
ragge
1.13
936                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
937 #endif
938
939                 /* make & mask part */
940
ragge
1.13
941                 p->n_left->n_type = ty;
ragge
1.1
942
ragge
1.13
943                 p->n_op = AND;