Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030622135631

Diff

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