Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030707183709

Diff

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