Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030623214814

Diff

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