Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030703181004

Diff

Diff from 1.20 to:

Annotations

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

Annotated File View

ragge
1.2
1 #if 0
ragge
1.1
2 static char *sccsid ="@(#)reader.c      4.8 (Berkeley) 12/10/87";
ragge
1.2
3 #endif
ragge
1.1
4
5 # include "pass2.h"
6
7 /*      some storage declarations */
8
9 int nrecur;
10 int lflag;
11 #ifdef FORT
12 int Oflag = 0;
13 #endif
14 extern int Wflag;
ragge
1.9
15 int x2debug;
ragge
1.1
16 int udebug = 0;
17 int vdebug = 0;
18
19 OFFSZ tmpoff;  /* offset for first temporary, in bits for current block */
20 OFFSZ maxoff;  /* maximum temporary offset over all blocks in current ftn, in bits */
21 int maxtreg;
22
23 NODE *stotree;
24 int stocook;
25
26 OFFSZ baseoff = 0;
27 OFFSZ maxtemp = 0;
28
ragge
1.10
29 int e2print(NODE *pint downint *aint *b);
ragge
1.8
30
ragge
1.17
31 static void
ragge
1.2
32 p2compile(NODE *p)
33 {
ragge
1.15
34 #if !defined(MULTIPASS)
35         extern char *ftitle;
36 #endif
ragge
1.1
37
ragge
1.14
38         if (lflag)
39                 lineid(linenoftitle);
40
ragge
1.1
41         tmpoff = baseoff;  /* expression at top level reuses temps */
42         /* generate code for the tree p */
43 # ifndef BUG4
ragge
1.8
44         if (e2debugfwalkpe2print0 );
ragge
1.1
45 # endif
46
47 # ifdef MYREADER
48         MYREADER(p);  /* do your own laundering of the input */
49 # endif
50         nrecur = 0;
51         delayp );  /* do the code generation */
52         reclaimpRNULL0 );
53         allchk();
54         /* can't do tcheck here; some stuff (e.g., attributes) may be around from first pass */
55         /* first pass will do it... */
ragge
1.2
56 }
ragge
1.1
57
ragge
1.17
58 static void newblock(int myregint aoff);
59 static void epilogue(int regsint autosint retlab);
60
ragge
1.2
61 void
ragge
1.17
62 pass2_compile(struct interpass *ip)
63 {
64         switch (ip->type) {
65         case IP_NODE:
66                 p2compile(ip->ip_node);
67                 break;
68         case IP_PROLOG:
69                 prologue(ip->ip_regsip->ip_auto);
70                 break;
71         case IP_NEWBLK:
72                 newblock(ip->ip_regsip->ip_auto);
73                 break;
74         case IP_EPILOG:
75                 epilogue(ip->ip_regsip->ip_autoip->ip_retl);
ragge
1.18
76                 break;
77         case IP_LOCCTR:
78                 setlocc(ip->ip_locc);
79                 break;
80         case IP_DEFLAB:
81                 deflab(ip->ip_lbl);
82                 break;
83         case IP_DEFNAM:
84                 defname(ip->ip_nameip->ip_vis);
85                 break;
86         case IP_INIT:
87                 printf("%s"ip->ip_name);
ragge
1.17
88                 break;
89         default:
90                 cerror("pass2_compile %d"ip->type);
91         }
92 }
93
94 static void
ragge
1.16
95 newblock(int myregint aoff)
ragge
1.2
96 {
ragge
1.1
97         static int myftn = -1;
98
99         tmpoff = baseoff = (unsigned intaoff;
100         maxtreg = myreg;
101         ifmyftn != ftnno ){ /* beginning of function */
102                 maxoff = baseoff;
103                 myftn = ftnno;
104                 maxtemp = 0;
105                 }
106         else {
107                 ifbaseoff > maxoff ) maxoff = baseoff;
108                 /* maxoff at end of ftn is max of autos and temps over all blocks */
109                 }
110         setregs();
ragge
1.2
111 }
ragge
1.1
112
ragge
1.17
113 static void
ragge
1.16
114 epilogue(int regsint autosint retlab)
ragge
1.2
115 {
ragge
1.16
116         SETOFF(maxoffALSTACK);
117         eoftn(regsautosretlab);
ragge
1.2
118 }
ragge
1.1
119
120 NODE *deltrees[DELAYS];
121 int deli;
122
ragge
1.2
123 /*
124  * look in all legal places for COMOP's and ++ and -- ops to delay
125  * note; don't delay ++ and -- within calls or things like
126  * getchar (in their macro forms) will start behaving strangely
127  */
128 void
129 delay(NODE *p)
130 {
131         int i;
ragge
1.1
132
133         /* look for visible COMOPS, and rewrite repeatedly */
134
ragge
1.2
135         while (delay1(p))
136                 ;
ragge
1.1
137
138         /* look for visible, delayable ++ and -- */
139
140         deli = 0;
141         delay2p );
142         codgenpFOREFF );  /* do what is left */
ragge
1.2
143         fori = 0i<deli; ++i )
144                 codgendeltrees[i], FOREFF );  /* do the rest */
145 }
146
147 /*
148  * look for COMOPS
149  */
150 int
151 delay1(NODE *p)
152 {
153         int oty;
ragge
1.1
154
ragge
1.13
155         o = p->n_op;
ragge
1.1
156         ty = optypeo );
157         ifty == LTYPE ) return0 );
ragge
1.13
158         else ifty == UTYPE ) returndelay1p->n_left ) );
ragge
1.1
159
160         switcho ){
161
162         case QUEST:
163         case ANDAND:
164         case OROR:
165                 /* don't look on RHS */
ragge
1.13
166                 returndelay1(p->n_left ) );
ragge
1.1
167
168         case COMOP:  /* the meat of the routine */
ragge
1.13
169                 delayp->n_left );  /* completely evaluate the LHS */
ragge
1.1
170                 /* rewrite the COMOP */
171                 { register NODE *q;
ragge
1.13
172                         q = p->n_right;
173                         ncopypp->n_right );
ragge
1.19
174                         nfree(q);
175                 }
ragge
1.1
176                 return1 );
ragge
1.2
177         }
ragge
1.1
178
ragge
1.13
179         returndelay1(p->n_left) || delay1(p->n_right ) );
ragge
1.2
180 }
ragge
1.1
181
ragge
1.2
182 void
183 delay2(NODE *p)
184 {
ragge
1.1
185
186         /* look for delayable ++ and -- operators */
187
ragge
1.2
188         int oty;
ragge
1.13
189         o = p->n_op;
ragge
1.1
190         ty = optypeo );
191
192         switcho ){
193
194         case NOT:
195         case QUEST:
196         case ANDAND:
197         case OROR:
198         case CALL:
199         case UNARY CALL:
200         case STCALL:
201         case UNARY STCALL:
202         case FORTCALL:
203         case UNARY FORTCALL:
204         case COMOP:
205         case CBRANCH:
206                 /* for the moment, don't delay past a conditional context, or
ragge
1.2
207                  * inside of a call */
ragge
1.1
208                 return;
209
210         case UNARY MUL:
211                 /* if *p++, do not rewrite */
212                 ifautoincrp ) ) return;
213                 break;
214
215         case INCR:
216         case DECR:
217                 ifdeltestp ) ){
218                         ifdeli < DELAYS ){
219                                 register NODE *q;
220                                 deltrees[deli++] = tcopy(p);
ragge
1.13
221                                 q = p->n_left;
ragge
1.19
222                                 nfree(p->n_right);  /* zap constant */
ragge
1.1
223                                 ncopypq );
ragge
1.19
224                                 nfree(q);
ragge
1.1
225                                 return;
226                                 }
227                         }
228
229                 }
230
ragge
1.13
231         ifty == BITYPE ) delay2p->n_right );
232         ifty != LTYPE ) delay2p->n_left );
ragge
1.2
233 }
ragge
1.1
234
ragge
1.2
235 /*
236  * generate the code for p;
237  * order may call codgen recursively
238  * cookie is used to describe the context
239  */
240 void
241 codgen(NODE *pint cookie)
242 {
ragge
1.1
243
ragge
1.8
244         for (;;) {
ragge
1.1
245                 canon(p);  /* creats OREG from * if possible and does sucomp */
246                 stotree = NIL;
247 # ifndef BUG4
ragge
1.8
248                 if (e2debug) {
249                         printf("store called on:\n");
250                         fwalk(pe2print0);
251                 }
ragge
1.1
252 # endif
253                 store(p);
254                 ifstotree==NIL ) break;
255
256                 /* because it's minimal, can do w.o. stores */
257
258                 orderstotreestocook );
ragge
1.2
259         }
ragge
1.1
260         orderpcookie );
ragge
1.2
261 }
ragge
1.1
262
263 # ifndef BUG4
264 char *cnames[] = {
265         "SANY",
266         "SAREG",
267         "STAREG",
268         "SBREG",
269         "STBREG",
270         "SCC",
271         "SNAME",
272         "SCON",
273         "SFLD",
274         "SOREG",
275 # ifdef WCARD1
276         "WCARD1",
277 # else
278         "STARNM",
279 # endif
280 # ifdef WCARD2
281         "WCARD2",
282 # else
283         "STARREG",
284 # endif
285         "INTEMP",
286         "FORARG",
287         "SWADD",
288         0,
289         };
290
ragge
1.2
291 /*
292  * print a nice-looking description of cookie
293  */
294 void
295 prcook(int cookie)
296 {
ragge
1.1
297         int iflag;
298
299         ifcookie & SPECIAL ){
300                 ifcookie == SZERO ) printf"SZERO" );
301                 else ifcookie == SONE ) printf"SONE" );
302                 else ifcookie == SMONE ) printf"SMONE" );
303                 else ifcookie == SCCON ) printf"SCCON" );
304                 else ifcookie == SSCON ) printf"SSCON" );
305                 else ifcookie == SSOREG ) printf"SSOREG" );
306                 else printf"SPECIAL+%d"cookie & ~SPECIAL );
307                 return;
308                 }
309
310         flag = 0;
311         fori=0cnames[i]; ++i ){
312                 ifcookie & (1<<i) ){
313                         ifflag ) printf"|" );
314                         ++flag;
315                         printfcnames[i] );
316                         }
317                 }
318
ragge
1.2
319 }
ragge
1.1
320 # endif
321
322 int odebug = 0;
323
ragge
1.2
324 void
325 order(NODE *pint cook)
326 {
327         int otym;
ragge
1.1
328         int m1;
329         int cookie;
ragge
1.2
330         NODE *p1, *p2;
ragge
1.1
331
332         cookie = cook;
333         rcount();
334         canon(p);
ragge
1.13
335         rallo(pp->n_rall);
ragge
1.1
336         goto first;
337
ragge
1.8
338
339         /*
340          * by this time, p should be able to be generated without stores;
341          * the only question is how
342          */
ragge
1.1
343         again:
344
ragge
1.13
345         if (p->n_op == FREE)
ragge
1.19
346                 cerror("order");        /* whole tree was done */
ragge
1.1
347         cookie = cook;
348         rcount();
349         canon(p);
ragge
1.13
350         rallo(pp->n_rall);
ragge
1.8
351         /*
352          * if any rewriting and canonicalization has put
ragge
1.1
353          * the tree (p) into a shape that cook is happy
354          * with (exclusive of FOREFF, FORREW, and INTEMP)
355          * then we are done.
356          * this allows us to call order with shapes in
357          * addition to cookies and stop short if possible.
358          */
ragge
1.8
359         if (tshape(pcook &(~(FOREFF|FORREW|INTEMP))))
360                 return;
ragge
1.1
361
362         first:
363 # ifndef BUG4
ragge
1.8
364         if (odebug) {
365                 printf("order(%p, "p);
366                 prcook(cookie);
367                 printf(")\n");
368                 fwalk(pe2print0);
369         }
ragge
1.1
370 # endif
371
ragge
1.13
372         o = p->n_op;
ragge
1.1
373         ty = optype(o);
374
375         /* first of all, for most ops, see if it is in the table */
376
377         /* look for ops */
378
ragge
1.13
379         switch (m = p->n_op) {
ragge
1.1
380
381         default:
382                 /* look for op in table */
ragge
1.8
383                 for (;;) {
384                         if ((m = match(pcookie)) == MDONE)
385                                 goto cleanup;
386                         else if (m == MNOPE) {
387                                 if (!(cookie = nextcook(pcookie)))
388                                         goto nomat;
ragge
1.1
389                                 continue;
ragge
1.8
390                         } else
391                                 break;
392                 }
ragge
1.1
393                 break;
394
395         case COMOP:
396         case FORCE:
397         case CBRANCH:
398         case QUEST:
399         case ANDAND:
400         case OROR:
401         case NOT:
402         case UNARY CALL:
403         case CALL:
404         case UNARY STCALL:
405         case STCALL:
406         case UNARY FORTCALL:
407         case FORTCALL:
408                 /* don't even go near the table... */
409                 ;
410
ragge
1.8
411         }
ragge
1.12
412 /*
ragge
1.8
413          * get here to do rewriting if no match or
414          * fall through from above for hard ops
415          */
ragge
1.1
416
ragge
1.13
417         p1 = p->n_left;
ragge
1.8
418         if (ty == BITYPE)
ragge
1.13
419                 p2 = p->n_right;
ragge
1.8
420         else
421                 p2 = NIL;
ragge
1.1
422         
423 # ifndef BUG4
ragge
1.8
424         if (odebug) {
425                 printf("order(%p, "p);
426                 prcook(cook);
427                 printf("), cookie ");
428                 prcook(cookie);
429                 printf(", rewrite %s\n"opst[m]);
430         }
ragge
1.1
431 # endif
ragge
1.8
432         switch (m) {
ragge
1.1
433         default:
434                 nomat:
ragge
1.13
435                 cerror"no table entry for op %s"opst[p->n_op] );
ragge
1.1
436
437         case COMOP:
438                 codgenp1FOREFF );
ragge
1.13
439                 p2->n_rall = p->n_rall;
ragge
1.1
440                 codgenp2cookie );
441                 ncopypp2 );
ragge
1.19
442                 nfree(p2);
ragge
1.1
443                 goto cleanup;
444
445         case FORCE:
446                 /* recurse, letting the work be done by rallo */
447                 cook = INTAREG|INTBREG;
ragge
1.19
448                 order(p->n_leftcook);
449                 reclaim(pRLEFTcook);
ragge
1.1
450                 goto again;
451
452         case CBRANCH:
ragge
1.13
453                 o = p2->n_lval;
ragge
1.1
454                 cbranchp1, -1o );
ragge
1.19
455                 nfree(p2);
456                 nfree(p);
ragge
1.1
457                 return;
458
459         case QUEST:
460                 cbranchp1, -1m=getlab() );
ragge
1.13
461                 p2->n_left->n_rall = p->n_rall;
462                 codgenp2->n_leftINTAREG|INTBREG );
ragge
1.1
463                 /* force right to compute result into same reg used by left */
ragge
1.13
464                 p2->n_right->n_rall = p2->n_left->n_rval|MUSTDO;
465                 reclaimp2->n_leftRNULL0 );
ragge
1.1
466                 cbgen0m1 = getlab(), 'I' );
467                 deflabm );
ragge
1.13
468                 codgenp2->n_rightINTAREG|INTBREG );
ragge
1.1
469                 deflabm1 );
ragge
1.13
470                 p->n_op = REG;  /* set up node describing result */
471                 p->n_lval = 0;
472                 p->n_rval = p2->n_right->n_rval;
473                 p->n_type = p2->n_right->n_type;
474                 tfreep2->n_right );
ragge
1.19
475                 nfree(p2);
ragge
1.1
476                 goto cleanup;
477
478         case ANDAND:
479         case OROR:
480         case NOT:  /* logical operators */
481                 /* if here, must be a logical operator for 0-1 value */
ragge
1.20
482                 p1 = talloc();
483                 *p1 = *p;       /* hack to avoid clobber in reclaim() */
484                 cbranchp1, -1m=getlab() );
ragge
1.13
485                 p->n_op = CCODES;
486                 p->n_label = m;
ragge
1.1
487                 orderpINTAREG );
488                 goto cleanup;
489
490         case FLD:       /* fields of funny type */
ragge
1.13
491                 if ( p1->n_op == UNARY MUL ){
492                         offstarp1->n_left );
ragge
1.1
493                         goto again;
494                         }
495
496         case UNARY MINUS:
497                 orderp1INBREG|INAREG|SOREG );
498                 goto again;
499
500         case NAME:
501                 /* all leaves end up here ... */
502                 ifo == REG ) goto nomat;
503                 orderpINTAREG|INTBREG );
504                 goto again;
505
506         case INIT:
ragge
1.12
507                 uerror("init: illegal initialization");
ragge
1.1
508                 return;
509
510         case UNARY FORTCALL:
ragge
1.13
511                 p->n_right = NIL;
ragge
1.1
512         case FORTCALL:
ragge
1.13
513                 o = p->n_op = UNARY FORTCALL;
ragge
1.1
514                 ifgenfcallpcookie ) ) goto nomat;
515                 goto cleanup;
516
517         case UNARY CALL:
ragge
1.13
518                 p->n_right = NIL;
ragge
1.1
519         case CALL:
ragge
1.13
520                 o = p->n_op = UNARY CALL;
ragge
1.1
521                 ifgencallpcookie ) ) goto nomat;
522                 goto cleanup;
523
524         case UNARY STCALL:
ragge
1.13
525                 p->n_right = NIL;
ragge
1.1
526         case STCALL:
ragge
1.13
527                 o = p->n_op = UNARY STCALL;
ragge
1.1
528                 ifgenscallpcookie ) ) goto nomat;
529                 goto cleanup;
530
531                 /* if arguments are passed in register, care must be taken that reclaim
ragge
1.2
532                  * not throw away the register which now has the result... */
ragge
1.1
533
534         case UNARY MUL:
535                 ifcook == FOREFF ){
536                         /* do nothing */
ragge
1.13
537                         orderp->n_leftFOREFF );
ragge
1.19
538                         nfree(p);
ragge
1.1
539                         return;
ragge
1.19
540                 }
ragge
1.1
541 #ifdef R2REGS
542                 /* try to coax a tree into a doubly indexed OREG */
ragge
1.13
543                 p1 = p->n_left;
544                 ifp1->n_op == PLUS ) {
545                         ifISPTR(p1->n_left->n_type) &&
546                             offset(p1->n_righttlen(p)) >= 0 ) {
547                                 orderp1->n_leftINAREG|INTAREG );
ragge
1.1
548                                 goto again;
549                                 }
ragge
1.13
550                         ifISPTR(p1->n_right->n_type) &&
551                             offset(p1->n_lefttlen(p)) >= 0 ) {
552                                 orderp1->n_rightINAREG|INTAREG );
ragge
1.1
553                                 goto again;
554                                 }
555                         }
556 #endif
ragge
1.13
557                 offstarp->n_left );
ragge
1.1
558                 goto again;
559
560         case INCR:  /* INCR and DECR */
561                 ifsetincr(p) ) goto again;
562
563                 /* x++ becomes (x += 1) -1; */
564
565                 ifcook & FOREFF ){  /* result not needed so inc or dec and be done with it */
566                         /* x++ => x += 1 */
ragge
1.13
567                         p->n_op = (p->n_op==INCR)?ASG PLUS:ASG MINUS;
ragge
1.1
568                         goto again;
569                         }
570
571                 p1 = tcopy(p);
ragge
1.13
572                 reclaimp->n_leftRNULL0 );
573                 p->n_left = p1;
574                 p1->n_op = (p->n_op==INCR)?ASG PLUS:ASG MINUS;
575                 p->n_op = (p->n_op==INCR)?MINUS:PLUS;
ragge
1.1
576                 goto again;
577
578         case STASG:
579                 ifsetstrp ) ) goto again;
580                 goto nomat;
581
582         case ASG PLUS:  /* and other assignment ops */
583                 ifsetasop(p) ) goto again;
584
585                 /* there are assumed to be no side effects in LHS */
586
587                 p2 = tcopy(p);
ragge
1.13
588                 p->n_op = ASSIGN;
589                 reclaimp->n_rightRNULL0 );
590                 p->n_right = p2;
ragge
1.1
591                 canon(p);
ragge
1.13
592                 rallopp->n_rall );
ragge
1.1
593
594 # ifndef BUG4
ragge
1.8
595                 ifodebug ) fwalkpe2print0 );
ragge
1.1
596 # endif
597
ragge
1.13
598                 orderp2->n_leftINTBREG|INTAREG );
ragge
1.1
599                 orderp2INTBREG|INTAREG );
600                 goto again;
601
602         case ASSIGN:
ragge
1.8
603                 if (setasg(p))
604                         goto again;
ragge
1.1
605                 goto nomat;
606
607
608         case BITYPE:
609                 ifsetbinp ) ) goto again;
610                 /* try to replace binary ops by =ops */
611                 switch(o){
612
613                 case PLUS:
614                 case MINUS:
615                 case MUL:
616                 case DIV:
617                 case MOD:
618                 case AND:
619                 case OR:
620                 case ER:
621                 case LS:
622                 case RS:
ragge
1.13
623                         p->n_op = ASG o;
ragge
1.1
624                         goto again;
625                         }
626                 goto nomat;
627
628                 }
629
630         cleanup:
631
632         /* if it is not yet in the right state, put it there */
633
634         ifcook & FOREFF ){
635                 reclaimpRNULL0 );
636                 return;
637                 }
638
ragge
1.13
639         ifp->n_op==FREE ) return;
ragge
1.1
640
641         iftshapepcook ) ) return;
642
643         if( (m=match(p,cook) ) == MDONE ) return;
644
645         /* we are in bad shape, try one last chance */
ragge
1.8
646         if (lastchance(pcook))
647                 goto again;
ragge
1.1
648
649         goto nomat;
ragge
1.8
650 }
ragge
1.1
651
652 int callflag;
653 int fregs;
654
ragge
1.2
655 void
656 storep ) NODE *p; {
ragge
1.1
657
658         /* find a subtree of p which should be stored */
659
ragge
1.2
660         int oty;
ragge
1.1
661
ragge
1.13
662         o = p->n_op;
ragge
1.1
663         ty = optype(o);
664
665         ifty == LTYPE ) return;
666
667         switcho ){
668
669         case UNARY CALL:
670         case UNARY FORTCALL:
671         case UNARY STCALL:
672                 ++callflag;
673                 break;
674
675         case UNARY MUL:
ragge
1.13
676                 if (asgop(p->n_left->n_op))
677                         stoasg(p->n_leftUNARY MUL);
ragge
1.1
678                 break;
679
680         case CALL:
681         case FORTCALL:
682         case STCALL:
ragge
1.13
683                 storep->n_left );
684                 stoargp->n_righto );
ragge
1.1
685                 ++callflag;
686                 return;
687
688         case COMOP:
ragge
1.13
689                 markcallp->n_right );
690                 ifp->n_right->n_su > fregs ) SETSTOpINTEMP );
691                 storep->n_left );
ragge
1.1
692                 return;
693
694         case ANDAND:
695         case OROR:
696         case QUEST:
ragge
1.13
697                 markcallp->n_right );
698                 ifp->n_right->n_su > fregs ) SETSTOpINTEMP );
ragge
1.1
699         case CBRANCH:   /* to prevent complicated expressions on the LHS from being stored */
700         case NOT:
ragge
1.13
701                 constorep->n_left );
ragge
1.1
702                 return;
703
704                 }
705
ragge
1.11
706         if (ty == UTYPE) {
ragge
1.13
707                 store(p->n_left);
ragge
1.1
708                 return;
ragge
1.11
709         }
ragge
1.1
710
ragge
1.13
711         if (asgop(p->n_right->n_op))
712                 stoasg(p->n_righto);
ragge
1.1
713
ragge
1.13
714         ifp->n_su>fregs ){ /* must store */
ragge
1.1
715                 mkadrsp );  /* set up stotree and stocook to subtree
716                                  that must be stored */
717                 }
718
ragge
1.13
719         storep->n_right );
720         storep->n_left );
ragge
1.1
721         }
722
ragge
1.2
723 /*
724  * store conditional expressions
725  * the point is, avoid storing expressions in conditional
726  * conditional context, since the evaluation order is predetermined
727  */
728 void
729 constore(NODE *p)
730 {
ragge
1.13
731         switchp->n_op ) {
ragge
1.1
732
733         case ANDAND:
734         case OROR:
735         case QUEST:
ragge
1.13
736                 markcallp->n_right );
ragge
1.1
737         case NOT:
ragge
1.13
738                 constorep->n_left );
ragge
1.1
739                 return;
740
741                 }
742
743         storep );
ragge
1.2
744 }
ragge
1.1
745
ragge
1.2
746 /* mark off calls below the current node */
747 void
748 markcall(NODE *p)
749 {
ragge
1.1
750
751         again:
ragge
1.13
752         switchp->n_op ){
ragge
1.1
753
754         case UNARY CALL:
755         case UNARY STCALL:
756         case UNARY FORTCALL:
757         case CALL:
758         case STCALL:
759         case FORTCALL:
760                 ++callflag;
761                 return;
762
763                 }
764
ragge
1.13
765         switchoptypep->n_op ) ){
ragge
1.1
766
767         case BITYPE:
ragge
1.13
768                 markcallp->n_right );
ragge
1.1
769         case UTYPE:
ragge
1.13
770                 p = p->n_left;
ragge
1.1
771                 /* eliminate recursion (aren't I clever...) */
772                 goto again;
773         case LTYPE:
774                 return;
775                 }
776
ragge
1.2
777 }
ragge
1.1
778
ragge
1.2
779 void
780 stoarg(NODE *pint calltype)
781 {
ragge
1.1
782         /* arrange to store the args */
ragge
1.13
783         ifp->n_op == CM ){
784                 stoargp->n_leftcalltype );
785                 p = p->n_right ;
ragge
1.1
786                 }
787         ifcalltype == CALL ){
788                 STOARG(p);
789                 }
790         else ifcalltype == STCALL ){
791                 STOSTARG(p);
792                 }
793         else {
794                 STOFARG(p);
795                 }
796         callflag = 0;
797         store(p);
798 # ifndef NESTCALLS
799         ifcallflag ){ /* prevent two calls from being active at once  */
800                 SETSTO(p,INTEMP);
801                 store(p); /* do again to preserve bottom up nature....  */
ragge
1.2
802         }
ragge
1.1
803 #endif
ragge
1.2
804 }
ragge
1.1
805
806 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
807
ragge
1.2
808 /*
809  * evaluate p for truth value, and branch to true or false
810  * accordingly: label <0 means fall through
811  */
812
813 void
814 cbranch(NODE *pint trueint false)
815 {
816         int olabflabtlab;
ragge
1.1
817
818         lab = -1;
819
ragge
1.13
820         switcho=p->n_op ){
ragge
1.1
821
822         case ULE:
823         case ULT:
824         case UGE:
825         case UGT:
826         case EQ:
827         case NE:
828         case LE:
829         case LT:
830         case GE:
831         case GT:
832                 iftrue < 0 ){
ragge
1.13
833                         o = p->n_op = negrelo-EQ ];
ragge
1.1
834                         true = false;
835                         false = -1;
836                         }
837 #ifndef NOOPT
ragge
1.13
838                 ifp->n_right->n_op == ICON && p->n_right->n_lval == 0 && p->n_right->n_name[0] == '\0' ){
ragge
1.1
839                         switcho ){
840
841                         case UGT:
842                         case ULE:
ragge
1.13
843                                 o = p->n_op = (o==UGT)?NE:EQ;
ragge
1.1
844                         case EQ:
845                         case NE:
846                         case LE:
847                         case LT:
848                         case GE:
849                         case GT:
ragge
1.13
850                                 iflogop(p->n_left->n_op) ){
ragge
1.1
851                                         /* strange situation: e.g., (a!=0) == 0 */
ragge
1.13
852                                         /* must prevent reference to p->n_left->lable, so get 0/1 */
ragge
1.1
853                                         /* we could optimize, but why bother */
ragge
1.13
854                                         codgenp->n_leftINAREG|INBREG );
ragge
1.1
855                                         }
ragge
1.13
856                                 codgenp->n_leftFORCC );
ragge
1.1
857                                 cbgenotrue'I' );
858                                 break;
859
860                         case UGE:
ragge
1.13
861                                 codgen(p->n_leftFORCC);
ragge
1.1
862                                 cbgen0true'I' );  /* unconditional branch */
863                                 break;
864                         case ULT:
ragge
1.13
865                                 codgen(p->n_leftFORCC);
ragge
1.1
866                                 }
867                         }
868                 else
869 #endif
870                         {
ragge
1.13
871                         p->n_label = true;
ragge
1.1
872                         codgenpFORCC );
873                         }
874                 iffalse>=0 ) cbgen0false'I' );
875                 reclaimpRNULL0 );
876                 return;
877
878         case ANDAND:
879                 lab = false<0 ? getlab() : false ;
ragge
1.13
880                 cbranchp->n_left, -1lab );
881                 cbranchp->n_righttruefalse );
ragge
1.1
882                 iffalse < 0 ) deflablab );
ragge
1.19
883                 nfree(p);
ragge
1.1
884                 return;
885
886         case OROR:
887                 lab = true<0 ? getlab() : true;
ragge
1.13
888                 cbranchp->n_leftlab, -1 );
889                 cbranchp->n_righttruefalse );
ragge
1.1
890                 iftrue < 0 ) deflablab );
ragge
1.19
891                 nfree(p);
ragge
1.1
892                 return;
893
894         case NOT:
ragge
1.13
895                 cbranchp->n_leftfalsetrue );
ragge
1.19
896                 nfree(p);
ragge
1.1
897                 break;
898
899         case COMOP:
ragge
1.13
900                 codgenp->n_leftFOREFF );
ragge
1.19
901                 nfree(p);
ragge
1.13
902                 cbranchp->n_righttruefalse );
ragge
1.1
903                 return;
904
905         case QUEST:
906                 flab = false<0 ? getlab() : false;
907                 tlab = true<0 ? getlab() : true;
ragge
1.13
908                 cbranchp->n_left, -1lab = getlab() );
909                 cbranchp->n_right->n_lefttlabflab );
ragge
1.1
910                 deflablab );
ragge
1.13
911                 cbranchp->n_right->n_righttruefalse );
ragge
1.1
912                 iftrue < 0 ) deflabtlab);
913                 iffalse < 0 ) deflabflab );
ragge
1.19
914                 nfree(p->n_right);
915                 nfree(p);
ragge
1.1
916                 return;
917
918         case ICON:
ragge
1.13
919                 ifp->n_type != FLOAT && p->n_type != DOUBLE ){
ragge
1.1
920
ragge
1.13
921                         ifp->n_lval || p->n_name[0] ){
ragge
1.1
922                                 /* addresses of C objects are never 0 */
923                                 iftrue>=0 ) cbgen0true'I' );
924                                 }
925                         else iffalse>=0 ) cbgen0false'I' );
ragge
1.19
926                         nfree(p);
ragge
1.1
927                         return;
ragge
1.19
928                 }
ragge
1.1
929                 /* fall through to default with other strange constants */
930
931         default:
932                 /* get condition codes */
933                 codgenpFORCC );
934                 iftrue >= 0 ) cbgenNEtrue'I' );
935                 iffalse >= 0 ) cbgentrue >= 0 ? 0 : EQfalse'I' );
936                 reclaimpRNULL0 );
937                 return;
938
939                 }
940
941         }
942
ragge
1.2
943 void
944 rcount()
945 /* count recursions */
ragge
1.1
946         if( ++nrecur > NRECUR ){
947                 cerror"expression causes compiler loop: try simplifying" );
948         }
ragge
1.2
949 }
ragge
1.1
950
951 # ifndef BUG4
ragge
1.2
952 int
ragge
1.8
953 e2print(NODE *pint downint *aint *b)
ragge
1.2
954 {
ragge
1.1