Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030703135351

Diff

Diff from 1.19 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 */
482                 cbranchp, -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
954         *a = *b = down+1;
955         whiledown >=