Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030909093655

Diff

Diff from 1.60 to:

Annotations

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

Annotated File View

ragge
1.60
1 /*      $Id: reader.c,v 1.60 2003/09/09 09:36:55 ragge Exp $    */
ragge
1.31
2 /*
3  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * Redistributions of source code and documentation must retain the above
10  * copyright notice, this list of conditions and the following disclaimer.
11  * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditionsand the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * All advertising materials mentioning features or use of this software
15  * must display the following acknowledgement:
16  *      This product includes software developed or owned by Caldera
17  *      International, Inc.
18  * Neither the name of Caldera International, Inc. nor the names of other
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
23  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
27  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
ragge
1.1
35
36 # include "pass2.h"
ragge
1.49
37 #include "external.h"
ragge
1.1
38
39 /*      some storage declarations */
40 int nrecur;
41 int lflag;
ragge
1.9
42 int x2debug;
ragge
1.1
43 int udebug = 0;
ragge
1.32
44 int ftnno;
ragge
1.1
45
46 NODE *stotree;
47 int stocook;
ragge
1.37
48 static int saving;
ragge
1.1
49
ragge
1.23
50 static struct templst {
51         struct templst *next;
52         int tempnr;
53         int tempoff;
54 } *templst;
55
ragge
1.10
56 int e2print(NODE *pint downint *aint *b);
ragge
1.37
57 void saveip(struct interpass *ip);
58 void deljumps(void);
ragge
1.40
59 void deltemp(NODE *p);
ragge
1.37
60 void optdump(struct interpass *ip);
ragge
1.40
61 void cvtemps(struct interpass *epil);
ragge
1.49
62 static int findops(NODE *p);
ragge
1.57
63 static int relops(NODE *p);
ragge
1.37
64
ragge
1.46
65 #define DELAYS 20
66 NODE *deltrees[DELAYS];
67 int deli;
ragge
1.26
68
69 #ifdef PCC_DEBUG
70 static void
71 cktree(NODE *p)
72 {
73         if (p->n_op > MAXOP)
74                 cerror("op %d slipped through"p->n_op);
ragge
1.35
75         if (p->n_op == CBRANCH && !logop(p->n_left->n_op))
76                 cerror("not logop branch");
ragge
1.47
77         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
78                 cerror("asgop %d slipped through"p->n_op);
ragge
1.26
79 }
80 #endif
ragge
1.8
81
ragge
1.17
82 static void
ragge
1.2
83 p2compile(NODE *p)
84 {
ragge
1.46
85         int i;
86
ragge
1.15
87 #if !defined(MULTIPASS)
88         extern char *ftitle;
89 #endif
ragge
1.1
90
ragge
1.14
91         if (lflag)
92                 lineid(linenoftitle);
93
ragge
1.1
94         /* generate code for the tree p */
ragge
1.26
95 #ifdef PCC_DEBUG
96         walkf(pcktree);
97         if (e2debug)
98                 fwalk(pe2print0);
99 #endif
ragge
1.25
100
ragge
1.1
101 # ifdef MYREADER
102         MYREADER(p);  /* do your own laundering of the input */
103 # endif
104         nrecur = 0;
ragge
1.46
105         deli = 0;
106         delay(p);
ragge
1.25
107         codgen(pFOREFF);
ragge
1.46
108         for (i = 0i < deli; ++i)
109                 codgen(deltrees[i], FOREFF);  /* do the rest */
ragge
1.1
110         reclaimpRNULL0 );
111         allchk();
ragge
1.46
112 }
113
114 /* look for delayable ++ and -- operators */
115 void
116 delay(NODE *p)
117 {
118         int ty = optype(p->n_op);
119
120         switch (p->n_op) {
121         case CALL:
122         case UNARY CALL:
123         case STCALL:
124         case UNARY STCALL:
125         case FORTCALL:
126         case UNARY FORTCALL:
127         case CBRANCH:
128                 /* for the moment, don7t delay past a conditional context, or
129                  * inside of a call */
130                 return;
131
132         case UNARY MUL:
133                 /* if *p++, do not rewrite */
134                 ifautoincrp ) ) return;
135                 break;
136
137         case INCR:
138         case DECR:
139                 ifdeltestp ) ){
140                         ifdeli < DELAYS ){
141                                 register NODE *q;
142                                 deltrees[deli++] = tcopy(p);
143                                 q = p->n_left;
ragge
1.58
144                                 nfree(p->n_right); /* zap constant */
ragge
1.46
145                                 *p = *q;
ragge
1.58
146                                 nfree(q);
ragge
1.46
147                                 return;
148                                 }
149                         }
150
151                 }
152
153         if (ty == BITYPE)
154                 delay(p->n_right);
155         if (ty != LTYPE)
156                 delay(p->n_left);
ragge
1.2
157 }
ragge
1.1
158
ragge
1.17
159 static void newblock(int myregint aoff);
160 static void epilogue(int regsint autosint retlab);
161
ragge
1.2
162 void
ragge
1.17
163 pass2_compile(struct interpass *ip)
164 {
ragge
1.37
165         if (Oflag) {
166                 if (ip->type == IP_PROLOG)
167                         saving++;
168                 if (saving)
169                         return saveip(ip);
170         }
ragge
1.17
171         switch (ip->type) {
172         case IP_NODE:
173                 p2compile(ip->ip_node);
ragge
1.21
174                 tfree(ip->ip_node);
ragge
1.17
175                 break;
176         case IP_PROLOG:
177                 prologue(ip->ip_regsip->ip_auto);
178                 break;
179         case IP_NEWBLK:
180                 newblock(ip->ip_regsip->ip_auto);
181                 break;
182         case IP_EPILOG:
183                 epilogue(ip->ip_regsip->ip_autoip->ip_retl);
ragge
1.18
184                 break;
185         case IP_LOCCTR:
186                 setlocc(ip->ip_locc);
187                 break;
188         case IP_DEFLAB:
189                 deflab(ip->ip_lbl);
190                 break;
191         case IP_DEFNAM:
192                 defname(ip->ip_nameip->ip_vis);
ragge
1.39
193                 break;
194         case IP_ASM:
195                 printf("%s\n"ip->ip_asm);
ragge
1.18
196                 break;
ragge
1.17
197         default:
198                 cerror("pass2_compile %d"ip->type);
199         }
200 }
201
202 static void
ragge
1.16
203 newblock(int myregint aoff)
ragge
1.2
204 {
ragge
1.1
205         setregs();
ragge
1.2
206 }
ragge
1.1
207
ragge
1.17
208 static void
ragge
1.16
209 epilogue(int regsint autosint retlab)
ragge
1.2
210 {
ragge
1.23
211         templst = NULL;
ragge
1.16
212         eoftn(regsautosretlab);
ragge
1.2
213 }
ragge
1.1
214
ragge
1.2
215 /*
216  * generate the code for p;
217  * order may call codgen recursively
218  * cookie is used to describe the context
219  */
220 void
221 codgen(NODE *pint cookie)
222 {
ragge
1.1
223
ragge
1.8
224         for (;;) {
ragge
1.1
225                 canon(p);  /* creats OREG from * if possible and does sucomp */
226                 stotree = NIL;
ragge
1.30
227 #ifdef PCC_DEBUG
ragge
1.8
228                 if (e2debug) {
229                         printf("store called on:\n");
230                         fwalk(pe2print0);
231                 }
ragge
1.30
232 #endif
ragge
1.1
233                 store(p);
234                 ifstotree==NIL ) break;
235
236                 /* because it's minimal, can do w.o. stores */
237
238                 orderstotreestocook );
ragge
1.2
239         }
ragge
1.1
240         orderpcookie );
ragge
1.2
241 }
ragge
1.1
242
ragge
1.30
243 #ifdef PCC_DEBUG
ragge
1.1
244 char *cnames[] = {
245         "SANY",
246         "SAREG",
247         "STAREG",
248         "SBREG",
249         "STBREG",
250         "SCC",
251         "SNAME",
252         "SCON",
253         "SFLD",
254         "SOREG",
255         "STARNM",
256         "STARREG",
257         "INTEMP",
258         "FORARG",
259         "SWADD",
260         0,
261         };
262
ragge
1.2
263 /*
264  * print a nice-looking description of cookie
265  */
266 void
267 prcook(int cookie)
268 {
ragge
1.1
269         int iflag;
270
271         ifcookie & SPECIAL ){
272                 ifcookie == SZERO ) printf"SZERO" );
273                 else ifcookie == SONE ) printf"SONE" );
274                 else ifcookie == SMONE ) printf"SMONE" );
275                 else printf"SPECIAL+%d"cookie & ~SPECIAL );
276                 return;
277                 }
278
279         flag = 0;
280         fori=0cnames[i]; ++i ){
281                 ifcookie & (1<<i) ){
282                         ifflag ) printf"|" );
283                         ++flag;
284                         printfcnames[i] );
285                         }
286                 }
287
ragge
1.2
288 }
ragge
1.30
289 #endif
ragge
1.1
290
291 int odebug = 0;
292
ragge
1.2
293 void
294 order(NODE *pint cook)
295 {
ragge
1.60
296         struct optab *q;
ragge
1.57
297         int otymrv;
ragge
1.1
298         int cookie;
ragge
1.2
299         NODE *p1, *p2;
ragge
1.1
300
ragge
1.8
301         /*
302          * by this time, p should be able to be generated without stores;
303          * the only question is how
304          */
ragge
1.1
305         again:
306
307         cookie = cook;
308         rcount();
309         canon(p);
ragge
1.13
310         rallo(pp->n_rall);
ragge
1.1
311
ragge
1.30
312 #ifdef PCC_DEBUG
ragge
1.8
313         if (odebug) {
314                 printf("order(%p, "p);
315                 prcook(cookie);
316                 printf(")\n");
317                 fwalk(pe2print0);
318         }
ragge
1.30
319 #endif
ragge
1.1
320
ragge
1.13
321         o = p->n_op;
ragge
1.1
322         ty = optype(o);
323
324         /* first of all, for most ops, see if it is in the table */
325
326         /* look for ops */
327
ragge
1.13
328         switch (m = p->n_op) {
ragge
1.1
329
ragge
1.48
330         case PLUS:
ragge
1.50
331         case MINUS:
ragge
1.51
332         case AND:
333         case OR:
334         case ER:
ragge
1.52
335         case DIV:
ragge
1.53
336         case MOD:
337         case MUL:
ragge
1.55
338         case LS:
339         case RS:
ragge
1.48
340
ragge
1.60
341                 /*
342                  * Be sure that both sides are addressable.
343                  */
ragge
1.50
344 //printf("newstyle node %p\n", p);
ragge
1.60
345                 if (!canaddr(p->n_left)) {
346                         if (p->n_left->n_op == UNARY MUL) {
347                                 offstar(p->n_left->n_left);
348                                 goto again;
ragge
1.53
349                         }
ragge
1.60
350                         order(p->n_leftINTAREG|INTBREG);
351                 }
ragge
1.50
352 //printf("newstyle addrl %p\n", p);
ragge
1.60
353                 if (!canaddr(p->n_right)) {
354                         if (p->n_right->n_op == UNARY MUL) {
355                                 offstar(p->n_right->n_left);
356                                 goto again;
ragge
1.53
357                         }
ragge
1.60
358                         order(p->n_rightINTAREG|INTBREG);
359                 }
ragge
1.50
360 //printf("newstyle addrr %p\n", p);
ragge
1.48
361
ragge
1.60
362                 /*
363                  *
364                  */
ragge
1.49
365 #define LTMP    1
366 #define RTMP    2
ragge
1.60
367                 m = INTAREG|INTBREG;
368                 rv = findops(p);
369 foo:            if (rv < 0) {
370                         if (setnbin(p))
371                                 goto again;
372                         goto nomat;
373                 }
374                 if (rv & LTMP)
375                         order(p->n_leftINTAREG|INTBREG);
ragge
1.50
376 //printf("newstyle ltmp %p\n", p);
ragge
1.60
377                 if (rv & RTMP)
378                         order(p->n_rightINTAREG|INTBREG);
ragge
1.50
379 //printf("newstyle rtmp %p\n", p);
ragge
1.49
380                 
381
ragge
1.60
382                 q = &table[rv >> 2];
383                 if (!allo(pq)) {
384                         /*
385                          * Ran out of suitable temp regs.
386                          * Force everything onto stack.
387                          * Be careful to avoid loops.
388                          * XXX - this is bad code!
389                          */
390                         if ((rv & LTMP) == 0 && istnode(p->n_left)) {
391                                 order(p->n_leftINTEMP);
392                                 goto again;
393                         } else if (!(rv & RTMP) &&istnode(p->n_right)) {
394                                 order(p->n_rightINTEMP);
395                                 goto again;
ragge
1.54
396                         }
ragge
1.60
397                         cerror("allo failed");
398                 }
399                 expand(pmq->cstring);
400                 reclaim(pq->rewritem);
ragge
1.50
401 //printf("newstyle ute %p\n", p);
ragge
1.49
402                 goto cleanup;
403
ragge
1.57
404                 /*
405                  * For now just be sure that the trees on each side
406                  * are adressable.
407                  */
408         case EQ:
409         case NE:
410         case LE:
411         case LT:
412         case GE:
413         case GT:
414         case ULE:
415         case ULT:
416         case UGE:
417         case UGT:
ragge
1.60
418
ragge
1.57
419                 if (!canaddr(p->n_left)) {
420                         if (p->n_left->n_op == UNARY MUL) {
421                                 offstar(p->n_left->n_left);
422                                 goto again;
423                         }
ragge
1.60
424                         order(p->n_leftINTAREG|INTBREG|INAREG|INBREG);
ragge
1.57
425                 }
426                 if (!canaddr(p->n_right)) {
427                         if (p->n_right->n_op == UNARY MUL) {
428                                 offstar(p->n_right->n_left);
429                                 goto again;
430                         }
ragge
1.60
431                         order(p->n_rightINTAREG|INTBREG|INAREG|INBREG);
ragge
1.57
432                 }
433                 rv = relops(p);
434                 m = FORCC;
435                 goto foo;
436
ragge
1.1
437         default:
438                 /* look for op in table */
ragge
1.8
439                 for (;;) {
440                         if ((m = match(pcookie)) == MDONE)
441                                 goto cleanup;
442                         else if (m == MNOPE) {
443                                 if (!(cookie = nextcook(pcookie)))
444                                         goto nomat;
ragge
1.1
445                                 continue;
ragge
1.8
446                         } else
447                                 break;
448                 }
ragge
1.1
449                 break;
450
451         case FORCE:
452         case CBRANCH:
453         case UNARY CALL:
454         case CALL:
455         case UNARY STCALL:
456         case STCALL:
457         case UNARY FORTCALL:
458         case FORTCALL:
459                 /* don't even go near the table... */
460                 ;
461
ragge
1.8
462         }
ragge
1.25
463         /*
ragge
1.8
464          * get here to do rewriting if no match or
465          * fall through from above for hard ops
466          */
ragge
1.1
467
ragge
1.13
468         p1 = p->n_left;
ragge
1.8
469         if (ty == BITYPE)
ragge
1.13
470                 p2 = p->n_right;
ragge
1.8
471         else
472                 p2 = NIL;
ragge
1.1
473         
ragge
1.30
474 #ifdef PCC_DEBUG
ragge
1.8
475         if (odebug) {
476                 printf("order(%p, "p);
477                 prcook(cook);
478                 printf("), cookie ");
479                 prcook(cookie);
480                 printf(", rewrite %s\n"opst[m]);
481         }
ragge
1.30
482 #endif
ragge
1.8
483         switch (m) {
ragge
1.1
484         default:
485                 nomat:
ragge
1.13
486                 cerror"no table entry for op %s"opst[p->n_op] );
ragge
1.1
487
488         case FORCE:
489                 cook = INTAREG|INTBREG;
ragge
1.19
490                 order(p->n_leftcook);
491                 reclaim(pRLEFTcook);
ragge
1.38
492                 return;
ragge
1.1
493
494         case CBRANCH:
ragge
1.36
495                 p1->n_label = p2->n_lval;
ragge
1.42
496                 o = p1->n_op;
ragge
1.36
497                 codgen(p1FORCC);
ragge
1.42
498                 cbgen(op2->n_lval);
ragge
1.36
499                 reclaim(p1RNULL0);
ragge
1.19
500                 nfree(p2);
501                 nfree(p);
ragge
1.1
502                 return;
503
504         case FLD:       /* fields of funny type */
ragge
1.13
505                 if ( p1->n_op == UNARY MUL ){
506                         offstarp1->n_left );
ragge
1.1
507                         goto again;
508                         }
509
510         case UNARY MINUS:
ragge
1.30
511                 orderp1INBREG|INAREG);
ragge
1.1
512                 goto again;
513
514         case NAME:
515                 /* all leaves end up here ... */
516                 ifo == REG ) goto nomat;
517                 orderpINTAREG|INTBREG );
518                 goto again;
519
520         case INIT:
ragge
1.12
521                 uerror("init: illegal initialization");
ragge
1.1
522                 return;
523
524         case UNARY FORTCALL:
ragge
1.13
525                 p->n_right = NIL;
ragge
1.1
526         case FORTCALL:
ragge
1.13
527                 o = p->n_op = UNARY FORTCALL;
ragge
1.1
528                 ifgenfcallpcookie ) ) goto nomat;
529                 goto cleanup;
530
531         case UNARY CALL:
ragge
1.13
532                 p->n_right = NIL;
ragge
1.1
533         case CALL:
ragge
1.13
534                 o = p->n_op = UNARY CALL;
ragge
1.1
535                 ifgencallpcookie ) ) goto nomat;
536                 goto cleanup;
537
538         case UNARY STCALL:
ragge
1.13
539                 p->n_right = NIL;
ragge
1.1
540         case STCALL:
ragge
1.13
541                 o = p->n_op = UNARY STCALL;
ragge
1.1
542                 ifgenscallpcookie ) ) goto nomat;
543                 goto cleanup;
544
545                 /* if arguments are passed in register, care must be taken that reclaim
ragge
1.2
546                  * not throw away the register which now has the result... */
ragge
1.1
547
548         case UNARY MUL:
549                 ifcook == FOREFF ){
550                         /* do nothing */
ragge
1.13
551                         orderp->n_leftFOREFF );
ragge
1.19
552                         nfree(p);
ragge
1.1
553                         return;
ragge
1.19
554                 }
ragge
1.30
555                 offstarp->n_left );
556 #if 0
557                 canon(p);
558                 ifcanaddr(p) && cook != INTEMP )
559                         goto cleanup;
ragge
1.1
560 #endif
561                 goto again;
562
563         case INCR:  /* INCR and DECR */
564                 ifsetincr(p) ) goto again;
565
ragge
1.49
566                 /* x++ becomes (x = x + 1) -1; */
ragge
1.1
567
568                 p1 = tcopy(p);
ragge
1.49
569                 if (cook & FOREFF) {
570                         nfree(p->n_right);
571                         p->n_right = p1;
ragge
1.50
572                         p1->n_op = (p->n_op == INCR) ? PLUSMINUS;
ragge
1.49
573                         p->n_op = ASSIGN;
574                 } else {
575                         p2 = talloc();
576                         p2->n_rall = NOPREF;
577                         p2->n_name = "";
578                         p2->n_op = ASSIGN;
579                         p2->n_type = p->n_type;
580                         p2->n_left = p->n_left;
581                         p2->n_right = p1;
582                         p1->n_op = (p->n_op == INCR) ? PLUSMINUS;
583                         p->n_op = (p->n_op == INCR) ? MINUS : PLUS;
ragge
1.50
584                         p->n_left = p2;
ragge
1.49
585                 }
ragge
1.1
586                 goto again;
587
588         case STASG:
589                 ifsetstrp ) ) goto again;
590                 goto nomat;
591
592         case ASSIGN:
ragge
1.8
593                 if (setasg(p))
594                         goto again;
ragge
1.1
595                 goto nomat;
596
597
598         case BITYPE:
599                 ifsetbinp ) ) goto again;
600                 goto nomat;
601
602                 }
603
604         cleanup:
605
606         /* if it is not yet in the right state, put it there */
607
608         ifcook & FOREFF ){
609                 reclaimpRNULL0 );
610                 return;
611                 }
612
ragge
1.13
613         ifp->n_op==FREE ) return;
ragge
1.1
614
615         iftshapepcook ) ) return;
616
617         if( (m=match(p,cook) ) == MDONE ) return;
618
619         /* we are in bad shape, try one last chance */
ragge
1.8
620         if (lastchance(pcook))
621                 goto again;
ragge
1.1
622
623         goto nomat;
ragge
1.8
624 }
ragge
1.1
625
626 int callflag;
627 int fregs;
628
ragge
1.2
629 void
630 storep ) NODE *p; {
ragge
1.1
631
632         /* find a subtree of p which should be stored */
633
ragge
1.2
634         int oty;
ragge
1.1
635
ragge
1.13
636         o = p->n_op;
ragge
1.1
637         ty = optype(o);
638
639         ifty == LTYPE ) return;
640
641         switcho ){
642
643         case UNARY CALL:
644         case UNARY FORTCALL:
645         case UNARY STCALL:
646                 ++callflag;
647                 break;
648
649         case UNARY MUL:
ragge
1.13
650                 if (asgop(p->n_left->n_op))
651                         stoasg(p->n_leftUNARY MUL);
ragge
1.1
652                 break;
653
654         case CALL:
655         case FORTCALL:
656         case STCALL:
ragge
1.13
657                 storep->n_left );
658                 stoargp->n_righto );
ragge
1.1
659                 ++callflag;
660                 return;
661
662         case CBRANCH:   /* to prevent complicated expressions on the LHS from being stored */
ragge
1.13
663                 constorep->n_left );
ragge
1.1
664                 return;
665
666                 }
667
ragge
1.11
668         if (ty == UTYPE) {
ragge
1.13
669                 store(p->n_left);
ragge
1.1
670                 return;
ragge
1.11
671         }
ragge
1.1
672
ragge
1.13
673         if (asgop(p->n_right->n_op))
674                 stoasg(p->n_righto);
ragge
1.1
675
ragge
1.13
676         ifp->n_su>fregs ){ /* must store */
ragge
1.1
677                 mkadrsp );  /* set up stotree and stocook to subtree
678                                  that must be stored */
679                 }
680
ragge
1.13
681         storep->n_right );
682         storep->n_left );
ragge
1.1
683         }
684
ragge
1.2
685 /*
686  * store conditional expressions
687  * the point is, avoid storing expressions in conditional
688  * conditional context, since the evaluation order is predetermined
689  */
690 void
691 constore(NODE *p)
692 {
ragge
1.1
693         storep );
ragge
1.2
694 }
ragge
1.1
695
ragge
1.2
696 /* mark off calls below the current node */
697 void
698 markcall(NODE *p)
699 {
ragge
1.1
700
701         again:
ragge
1.13
702         switchp->n_op ){
ragge
1.1
703
704         case UNARY CALL:
705         case UNARY STCALL:
706         case UNARY FORTCALL:
707         case CALL:
708         case STCALL:
709         case FORTCALL:
710                 ++callflag;
711                 return;
712
713                 }
714
ragge
1.13
715         switchoptypep->n_op ) ){
ragge
1.1
716
717         case BITYPE:
ragge
1.13
718                 markcallp->n_right );
ragge
1.1
719         case UTYPE:
ragge
1.13
720                 p = p->n_left;
ragge
1.1
721                 /* eliminate recursion (aren't I clever...) */
722                 goto again;
723         case LTYPE:
724                 return;
725                 }
726
ragge
1.2
727 }
ragge
1.1
728
ragge
1.2
729 void
730 stoarg(NODE *pint calltype)
731 {
ragge
1.1
732         /* arrange to store the args */
ragge
1.13
733         ifp->n_op == CM ){
734                 stoargp->n_leftcalltype );
735                 p = p->n_right ;
ragge
1.1
736                 }
737         ifcalltype == CALL ){
738                 STOARG(p);
739                 }
740         else ifcalltype == STCALL ){
741                 STOSTARG(p);
742                 }
743         else {
744                 STOFARG(p);
745                 }
746         callflag = 0;
747         store(p);
ragge
1.30
748 #ifdef NO_NESTCALLS
ragge
1.1
749         ifcallflag ){ /* prevent two calls from being active at once  */
750                 SETSTO(p,INTEMP);
751                 store(p); /* do again to preserve bottom up nature....  */
ragge
1.2
752         }
ragge
1.1
753 #endif
ragge
1.2
754 }
ragge
1.1
755
756 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
757
ragge
1.2
758 void
759 rcount()
760 /* count recursions */
ragge
1.1
761         if( ++nrecur > NRECUR ){
762                 cerror"expression causes compiler loop: try simplifying" );
763         }
ragge
1.2
764 }
ragge
1.1
765
ragge
1.30
766 #ifdef PCC_DEBUG
ragge
1.2
767 int
ragge
1.8
768 e2print(NODE *pint downint *aint *b)
ragge
1.2
769 {
ragge
1.1
770
771         *a = *b = down+1;
772         whiledown >= 2 ){
773                 printf"\t" );
774                 down -= 2;
775                 }
776         ifdown-- ) printf"    " );
777
778
ragge
1.13
779         printf"%p) %s"popst[p->n_op] );
780         switchp->n_op ) { /* special cases */
ragge
1.1
781
782         case REG:
ragge
1.13
783                 printf" %s"rnames[p->n_rval] );
ragge
1.1
784                 break;
785
ragge
1.23
786         case TEMP:
787                 printf(" %d", (int)p->n_lval);
788                 break;
789
ragge
1.1
790         case ICON:
791         case NAME:
792         case OREG:
793                 printf" " );
794                 adrputp );
795                 break;
796
797         case STCALL:
798         case UNARY STCALL:
799         case STARG:
800         case STASG:
ragge
1.13
801                 printf" size=%d"p->n_stsize );
802                 printf" align=%d"p->n_stalign );
ragge
1.1
803                 break;
804                 }
805
806         printf", " );
ragge
1.33
807         tprintp->n_typep->n_qual);
ragge
1.1
808         printf", " );
ragge
1.13
809         ifp->n_rall == NOPREF ) printf"NOPREF" );
ragge
1.1
810         else {
ragge
1.13
811                 ifp->n_rall & MUSTDO ) printf"MUSTDO " );
ragge
1.1
812                 else printf"PREF " );
ragge
1.13
813                 printf"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
814                 }
ragge
1.13
815         printf", SU= %d\n"p->n_su );
ragge
1.2
816         return 0;
817 }
ragge
1.30
818 #endif
ragge
1.1
819
820 #ifndef FIELDOPS
ragge
1.7
821 /*
822  * do this if there is no special hardware support for fields
823  */
824 static int
825 ffld(NODE *pint downint *down1int *down2 )
826 {
827         /*
828          * look for fields that are not in an lvalue context,
829          * and rewrite them...
830          */
831         NODE *shp;
832         int sovty;
ragge
1.1
833
ragge
1.13
834         *down1 =  asgopp->n_op );
ragge
1.1
835         *down2 = 0;
836
ragge
1.13
837         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
838
ragge
1.7
839                 if( !rewfld(p) ) return 0;
ragge
1.1
840
ragge
1.48
841                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
842                 v = p->n_rval;
ragge
1.1
843                 s = UPKFSZ(v);
844 # ifdef RTOLBYTES
845                 o = UPKFOFF(v);  /* amount to shift */
846 # else
ragge
1.13
847                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
848 #endif
849
850                 /* make & mask part */
851
ragge
1.13
852                 p->n_left->n_type = ty;
ragge
1.1
853
ragge
1.13
854                 p->n_op = AND;
855                 p->n_right = talloc();
856                 p->n_right->n_op = ICON;
857                 p->n_right->n_rall = NOPREF;
858                 p->n_right->n_type = ty;
859                 p->n_right->n_lval = 1;
860                 p->n_right->n_rval = 0;
861                 p->n_right->n_name = "";
862                 p->n_right->n_lval <<= s;
863                 p->n_right->n_lval--;
ragge
1.1
864
865                 /* now, if a shift is needed, do it */
866
867                 ifo != 0 ){
868                         shp = talloc();
ragge
1.13
869                         shp->n_op = RS;
870                         shp->n_rall = NOPREF;
871                         shp->n_type = ty;
872                         shp->n_left = p->n_left;
873                         shp->n_right = talloc();
874                         shp->n_right->n_op = ICON;
875                         shp->n_right->n_rall = NOPREF;
876                         shp->n_right->n_type = ty;
877                         shp->n_right->n_rval = 0;
878                         shp->n_right->n_lval = o;  /* amount to shift */
879                         shp->n_right->n_name = "";
880                         p->n_left = shp;
ragge
1.1
881                         /* whew! */
882                 }
883         }
ragge
1.7
884         return 0;
885 }
ragge
1.1
886 #endif
887
ragge
1.23
888 /*
889  * change left TEMPs into OREGs
ragge
1.40
890  */
891 void
892 deltemp(NODE *p)
893 {
894         struct templst *w = templst;
895
896         if (p->n_op != TEMP)
897                 return;
898         /*
899          * the size of a TEMP is in multiples of the reg size.
900          */
901         p->n_op = OREG;
902         p->n_rval = FPREG;
903         while (w != NULL) {
904                 if (w->tempnr == p->n_lval)
905                         break;
906                 w = w->next;
907         }
908         if (w == NULL) {
909                 w = tmpalloc(sizeof(struct templst));
910                 w->tempnr = p->n_lval;
911                 w->tempoff = BITOOR(freetemp(szty(p->n_type)));
912                 w->next = templst;
913                 templst = w;
914         }
915         p->n_lval = w->tempoff;
916         p->n_name = "";
917 }
918
919 /*
ragge
1.48
920  * for pointer/integer arithmetic, set pointer at left node
921  */
922 static void
923 setleft(NODE *p)          
924 {        
925         NODE *q;
926
927         /* only additions for now */
928         if (p->n_op != PLUS)
929                 return;
930         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
931                 q = p->n_right;
932                 p->n_right = p->n_left;
933                 p->n_left = q;
934         }
935 }
936
937 /*
ragge
1.23
938  * look for situations where we can turn * into OREG
939  */
ragge
1.2
940 void
941 oreg2(NODE *p)
942 {
ragge
1.1
943
944         NODE *q;
ragge
1.2
945         int r;
946         char *cp;
947         NODE *ql, *qr;
ragge
1.1
948         CONSZ temp;
ragge
1.23
949
ragge
1.44