Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20020326184257

Diff

Diff from 1.3 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 # define NOMAIN
10
11 int nrecur;
12 int lflag;
13 #ifdef FORT
14 int Oflag = 0;
15 #endif
16 extern int Wflag;
17 int edebug = 0;
18 int xdebug = 0;
19 int udebug = 0;
20 int vdebug = 0;
21
22 OFFSZ tmpoff;  /* offset for first temporary, in bits for current block */
23 OFFSZ maxoff;  /* maximum temporary offset over all blocks in current ftn, in bits */
24 int maxtreg;
25
26 NODE *stotree;
27 int stocook;
28
29 OFFSZ baseoff = 0;
30 OFFSZ maxtemp = 0;
31
ragge
1.2
32 int
33 p2init(int argcchar *argv[])
34 {
ragge
1.1
35         /* set the values of the pass 2 arguments */
36
ragge
1.2
37         int c;
38         char *cp;
39         int files;
ragge
1.1
40
41         allo0();  /* free all regs */
42         files = 0;
43
44         forc=1c<argc; ++c ){
45                 if( *(cp=argv[c]) == '-' ){
46                         while( *++cp ){
47                                 switch( *cp ){
48
49                                 case 'X':  /* pass1 flags */
50                                         while( *++cp ) { /* VOID */ }
51                                         --cp;
52                                         break;
53
54                                 case 'l':  /* linenos */
55                                         ++lflag;
56                                         break;
57
58                                 case 'e':  /* expressions */
59                                         ++edebug;
60                                         break;
61
62                                 case 'o':  /* orders */
63                                         ++odebug;
64                                         break;
65
66                                 case 'r':  /* register allocation */
67                                         ++rdebug;
68                                         break;
69
70                                 case 'a':  /* rallo */
71                                         ++radebug;
72                                         break;
73
74                                 case 'v':
75                                         ++vdebug;
76                                         break;
77
78                                 case 't':  /* ttype calls */
79                                         ++tdebug;
80                                         break;
81
82                                 case 's':  /* shapes */
83                                         ++sdebug;
84                                         break;
85
86                                 case 'u':  /* Sethi-Ullman testing (machine dependent) */
87                                         ++udebug;
88                                         break;
89
90                                 case 'x':  /* general machine-dependent debugging flag */
91                                         ++xdebug;
92                                         break;
93
94                                 case 'w':
95                                 case 'W':  /* shut up warnings */
96
97                                         ++Wflag;
98                                         break;
99
100 #ifdef FORT
101                                 case 'O':  /* optimizing */
102                                         ++Oflag;
103                                         break;
104 #endif
105
106                                 default:
107                                         cerror"bad option: %c", *cp );
108                                         }
109                                 }
110                         }
111                 else files = 1;  /* assumed to be a filename */
112                 }
113
114         mkdope();
115         setrew();
116         returnfiles );
117
ragge
1.2
118 }
ragge
1.1
119
120 # ifndef NOMAIN
121
122 unsigned int caloff();
123 unsigned int offsz;
124 mainp2argcargv ) char *argv[]; {
125         register files;
126         register temp;
127         register c;
128         register char *cp;
129         register NODE *p;
130
131         offsz = caloff();
132         files = p2initargcargv );
133         tinit();
134
135         reread:
136
137         iffiles ){
138                 whilefiles < argc && argv[files][0] == '-' ) {
139                         ++files;
140                         }
141                 iffiles > argc ) returnnerrors );
142                 freopenargv[files], "r"stdin );
143                 }
144         while( (c=getchar()) > 0 ) switchc ){
145         case ')':
146         default:
147                 /* copy line unchanged */
148                 if ( c != ')' )
149                         PUTCHARc );  /*  initial tab  */
150                 while( (c=getchar()) > 0 ){
151                         PUTCHAR(c);
152                         ifc == '\n' ) break;
153                         }
154                 continue;
155
156         case BBEG:
157                 /* beginning of a block */
158                 temp = rdin(10);  /* ftnno */
159                 tmpoff = baseoff = (unsigned intrdin(10); /* autooff for block gives max offset of autos in block */
160                 maxtreg = rdin(10);
161                 ifgetchar() != '\n' ) cerror"intermediate file format error");
162
163                 iftemp != ftnno ){ /* beginning of function */
164                         maxoff = baseoff;
165                         ftnno = temp;
166                         maxtemp = 0;
167                         }
168                 else {
169                         ifbaseoff > maxoff ) maxoff = baseoff;
170                         /* maxoff at end of ftn is max of autos and temps
171                            over all blocks in the function */
172                         }
173                 setregs();
174                 continue;
175
176         case BEND:  /* end of block */
177                 SETOFFmaxoffALSTACK );
178                 eobl2();
179                 while( (c=getchar()) != '\n' ){
180                         ifc <= 0 ) cerror"intermediate file format eof" );
181                         }
182                 continue;
183
184         case EXPR:
185                 /* compile code for an expression */
186                 lineno = rdin10 );
187                 forcp=filename; (*cp=getchar()) != '\n'; ++cp ) ; /* VOID, reads filename */
188                 *cp = '\0';
189                 iflflag ) lineidlinenofilename );
190
191                 tmpoff = baseoff;  /* expression at top level reuses temps */
192                 p = eread();
193
194 # ifndef BUG4
195                 ifedebug ) fwalkpeprint0 );
196 # endif
197
198 # ifdef MYREADER
199                 MYREADER(p);  /* do your own laundering of the input */
200 # endif
201
202                 nrecur = 0;
203                 delayp );  /* expression statement  throws out results */
204                 reclaimpRNULL0 );
205
206                 allchk();
207                 tcheck();
208                 continue;
209
210                 }
211
212         /* EOF */
213         iffiles ) goto reread;
214         return(nerrors);
215
216         }
217
218 # endif
219
ragge
1.2
220 void
221 p2compile(NODE *p)
222 {
ragge
1.1
223
224         iflflag ) lineidlinenofilename );
225         tmpoff = baseoff;  /* expression at top level reuses temps */
226         /* generate code for the tree p */
227 # ifndef BUG4
228         ifedebug ) fwalkpeprint0 );
229 # endif
230
231 # ifdef MYREADER
232         MYREADER(p);  /* do your own laundering of the input */
233 # endif
234         nrecur = 0;
235         delayp );  /* do the code generation */
236         reclaimpRNULL0 );
237         allchk();
238         /* can't do tcheck here; some stuff (e.g., attributes) may be around from first pass */
239         /* first pass will do it... */
ragge
1.2
240 }
ragge
1.1
241
ragge
1.2
242 void
243 p2bbeg(int aoffint myreg)
244 {
ragge
1.1
245         static int myftn = -1;
246
247         tmpoff = baseoff = (unsigned intaoff;
248         maxtreg = myreg;
249         ifmyftn != ftnno ){ /* beginning of function */
250                 maxoff = baseoff;
251                 myftn = ftnno;
252                 maxtemp = 0;
253                 }
254         else {
255                 ifbaseoff > maxoff ) maxoff = baseoff;
256                 /* maxoff at end of ftn is max of autos and temps over all blocks */
257                 }
258         setregs();
ragge
1.2
259 }
ragge
1.1
260
ragge
1.2
261 void
262 p2bend()
263 {
ragge
1.1
264         SETOFFmaxoffALSTACK );
265         eobl2();
ragge
1.2
266 }
ragge
1.1
267
268 NODE *deltrees[DELAYS];
269 int deli;
270
ragge
1.2
271 /*
272  * look in all legal places for COMOP's and ++ and -- ops to delay
273  * note; don't delay ++ and -- within calls or things like
274  * getchar (in their macro forms) will start behaving strangely
275  */
276 void
277 delay(NODE *p)
278 {
279         int i;
ragge
1.1
280
281         /* look for visible COMOPS, and rewrite repeatedly */
282
ragge
1.2
283         while (delay1(p))
284                 ;
ragge
1.1
285
286         /* look for visible, delayable ++ and -- */
287
288         deli = 0;
289         delay2p );
290         codgenpFOREFF );  /* do what is left */
ragge
1.2
291         fori = 0i<deli; ++i )
292                 codgendeltrees[i], FOREFF );  /* do the rest */
293 }
294
295 /*
296  * look for COMOPS
297  */
298 int
299 delay1(NODE *p)
300 {
301         int oty;
ragge
1.1
302
303         o = p->in.op;
304         ty = optypeo );
305         ifty == LTYPE ) return0 );
306         else ifty == UTYPE ) returndelay1p->in.left ) );
307
308         switcho ){
309
310         case QUEST:
311         case ANDAND:
312         case OROR:
313                 /* don't look on RHS */
314                 returndelay1(p->in.left ) );
315
316         case COMOP:  /* the meat of the routine */
317                 delayp->in.left );  /* completely evaluate the LHS */
318                 /* rewrite the COMOP */
319                 { register NODE *q;
320                         q = p->in.right;
321                         ncopypp->in.right );
322                         q->in.op = FREE;
323                         }
324                 return1 );
ragge
1.2
325         }
ragge
1.1
326
327         returndelay1(p->in.left) || delay1(p->in.right ) );
ragge
1.2
328 }
ragge
1.1
329
ragge
1.2
330 void
331 delay2(NODE *p)
332 {
ragge
1.1
333
334         /* look for delayable ++ and -- operators */
335
ragge
1.2
336         int oty;
ragge
1.1
337         o = p->in.op;
338         ty = optypeo );
339
340         switcho ){
341
342         case NOT:
343         case QUEST:
344         case ANDAND:
345         case OROR:
346         case CALL:
347         case UNARY CALL:
348         case STCALL:
349         case UNARY STCALL:
350         case FORTCALL:
351         case UNARY FORTCALL:
352         case COMOP:
353         case CBRANCH:
354                 /* for the moment, don't delay past a conditional context, or
ragge
1.2
355                  * inside of a call */
ragge
1.1
356                 return;
357
358         case UNARY MUL:
359                 /* if *p++, do not rewrite */
360                 ifautoincrp ) ) return;
361                 break;
362
363         case INCR:
364         case DECR:
365                 ifdeltestp ) ){
366                         ifdeli < DELAYS ){
367                                 register NODE *q;
368                                 deltrees[deli++] = tcopy(p);
369                                 q = p->in.left;
370                                 p->in.right->in.op = FREE;  /* zap constant */
371                                 ncopypq );
372                                 q->in.op = FREE;
373                                 return;
374                                 }
375                         }
376
377                 }
378
379         ifty == BITYPE ) delay2p->in.right );
380         ifty != LTYPE ) delay2p->in.left );
ragge
1.2
381 }
ragge
1.1
382
ragge
1.2
383 /*
384  * generate the code for p;
385  * order may call codgen recursively
386  * cookie is used to describe the context
387  */
388 void
389 codgen(NODE *pint cookie)
390 {
ragge
1.1
391
392         for(;;){
393                 canon(p);  /* creats OREG from * if possible and does sucomp */
394                 stotree = NIL;
395 # ifndef BUG4
396                 ifedebug ){
397                         printf"store called on:\n" );
398                         fwalkpeprint0 );
399                         }
400 # endif
401                 store(p);
402                 ifstotree==NIL ) break;
403
404                 /* because it's minimal, can do w.o. stores */
405
406                 orderstotreestocook );
ragge
1.2
407         }
ragge
1.1
408         orderpcookie );
ragge
1.2
409 }
ragge
1.1
410
411 # ifndef BUG4
412 char *cnames[] = {
413         "SANY",
414         "SAREG",
415         "STAREG",
416         "SBREG",
417         "STBREG",
418         "SCC",
419         "SNAME",
420         "SCON",
421         "SFLD",
422         "SOREG",
423 # ifdef WCARD1
424         "WCARD1",
425 # else
426         "STARNM",
427 # endif
428 # ifdef WCARD2
429         "WCARD2",
430 # else
431         "STARREG",
432 # endif
433         "INTEMP",
434         "FORARG",
435         "SWADD",
436         0,
437         };
438
ragge
1.2
439 /*
440  * print a nice-looking description of cookie
441  */
442 void
443 prcook(int cookie)
444 {
ragge
1.1
445         int iflag;
446
447         ifcookie & SPECIAL ){
448                 ifcookie == SZERO ) printf"SZERO" );
449                 else ifcookie == SONE ) printf"SONE" );
450                 else ifcookie == SMONE ) printf"SMONE" );
451                 else ifcookie == SCCON ) printf"SCCON" );
452                 else ifcookie == SSCON ) printf"SSCON" );
453                 else ifcookie == SSOREG ) printf"SSOREG" );
454                 else printf"SPECIAL+%d"cookie & ~SPECIAL );
455                 return;
456                 }
457
458         flag = 0;
459         fori=0cnames[i]; ++i ){
460                 ifcookie & (1<<i) ){
461                         ifflag ) printf"|" );
462                         ++flag;
463                         printfcnames[i] );
464                         }
465                 }
466
ragge
1.2
467 }
ragge
1.1
468 # endif
469
470 int odebug = 0;
471
ragge
1.2
472 void
473 order(NODE *pint cook)
474 {
475         int otym;
ragge
1.1
476         int m1;
477         int cookie;
ragge
1.2
478         NODE *p1, *p2;
ragge
1.1
479
480         cookie = cook;
481         rcount();
482         canon(p);
483         rallopp->in.rall );
484         goto first;
485         /* by this time, p should be able to be generated without stores;
486            the only question is how */
487
488         again:
489
490         if ( p->in.op == FREE )
491                 return;         /* whole tree was done */
492         cookie = cook;
493         rcount();
494         canon(p);
495         rallopp->in.rall );
496         /* if any rewriting and canonicalization has put
497          * the tree (p) into a shape that cook is happy
498          * with (exclusive of FOREFF, FORREW, and INTEMP)
499          * then we are done.
500          * this allows us to call order with shapes in
501          * addition to cookies and stop short if possible.
502          */
503         iftshape(pcook &(~(FOREFF|FORREW|INTEMP))) )return;
504
505         first:
506 # ifndef BUG4
507         ifodebug ){
ragge
1.2
508                 printf"order( %p, "p );
ragge
1.1
509                 prcookcookie );
510                 printf" )\n" );
511                 fwalkpeprint0 );
512                 }
513 # endif
514
515         o = p->in.op;
516         ty = optype(o);
517
518         /* first of all, for most ops, see if it is in the table */
519
520         /* look for ops */
521
522         switchm = p->in.op ){
523
524         default:
525                 /* look for op in table */
526                 for(;;){
527                         if( (m = matchpcookie ) ) == MDONE ) goto cleanup;
528                         else ifm == MNOPE ){
529                                 if( !(cookie = nextcookpcookie ) ) ) goto nomat;
530                                 continue;
531                                 }
532                         else break;
533                         }
534                 break;
535
536         case COMOP:
537         case FORCE:
538         case CBRANCH:
539         case QUEST:
540         case ANDAND:
541         case OROR:
542         case NOT:
543         case UNARY CALL:
544         case CALL:
545         case UNARY STCALL:
546         case STCALL:
547         case UNARY FORTCALL:
548         case FORTCALL:
549                 /* don't even go near the table... */
550                 ;
551
552                 }
553         /* get here to do rewriting if no match or
554            fall through from above for hard ops */
555
556         p1 = p->in.left;
557         ifty == BITYPE ) p2 = p->in.right;
558         else p2 = NIL;
559         
560 # ifndef BUG4
561         ifodebug ){
ragge
1.2
562                 printf"order( %p, "p );
ragge
1.1
563                 prcookcook );
564                 printf" ), cookie " );
565                 prcookcookie );
566                 printf", rewrite %s\n"opst[m] );
567                 }
568 # endif
569         switchm ){
570         default:
571                 nomat:
572                 cerror"no table entry for op %s"opst[p->in.op] );
573
574         case COMOP:
575                 codgenp1FOREFF );
576                 p2->in.rall = p->in.rall;
577                 codgenp2cookie );
578                 ncopypp2 );
579                 p2->in.op = FREE;
580                 goto cleanup;
581
582         case FORCE:
583                 /* recurse, letting the work be done by rallo */
584                 p = p->in.left;
585                 cook = INTAREG|INTBREG;
586                 goto again;
587
588         case CBRANCH:
589                 o = p2->tn.lval;
590                 cbranchp1, -1o );
591                 p2->in.op = FREE;
592                 p->in.op = FREE;
593                 return;
594
595         case QUEST:
596                 cbranchp1, -1m=getlab() );
597                 p2->in.left->in.rall = p->in.rall;
598                 codgenp2->in.leftINTAREG|INTBREG );
599                 /* force right to compute result into same reg used by left */
600                 p2->in.right->in.rall = p2->in.left->tn.rval|MUSTDO;
601                 reclaimp2->in.leftRNULL0 );
602                 cbgen0m1 = getlab(), 'I' );
603                 deflabm );
604                 codgenp2->in.rightINTAREG|INTBREG );
605                 deflabm1 );
606                 p->in.op = REG;  /* set up node describing result */
607                 p->tn.lval = 0;
608                 p->tn.rval = p2->in.right->tn.rval;
609                 p->in.type = p2->in.right->in.type;
610                 tfreep2->in.right );
611                 p2->in.op = FREE;
612                 goto cleanup;
613
614         case ANDAND:
615         case OROR:
616         case NOT:  /* logical operators */
617                 /* if here, must be a logical operator for 0-1 value */
618                 cbranchp, -1m=getlab() );
619                 p->in.op = CCODES;
620                 p->bn.label = m;
621                 orderpINTAREG );
622                 goto cleanup;
623
624         case FLD:       /* fields of funny type */
625                 if ( p1->in.op == UNARY MUL ){
626                         offstarp1->in.left );
627                         goto again;
628                         }
629
630         case UNARY MINUS:
631                 orderp1INBREG|INAREG|SOREG );
632                 goto again;
633
634         case NAME:
635                 /* all leaves end up here ... */
636                 ifo == REG ) goto nomat;
637                 orderpINTAREG|INTBREG );
638                 goto again;
639
640         case INIT:
641                 uerror"illegal initialization" );
642                 return;
643
644         case UNARY FORTCALL:
645                 p->in.right = NIL;
646         case FORTCALL:
647                 o = p->in.op = UNARY FORTCALL;
648                 ifgenfcallpcookie ) ) goto nomat;
649                 goto cleanup;
650
651         case UNARY CALL:
652                 p->in.right = NIL;
653         case CALL:
654                 o = p->in.op = UNARY CALL;
655                 ifgencallpcookie ) ) goto nomat;
656                 goto cleanup;
657
658         case UNARY STCALL:
659                 p->in.right = NIL;
660         case STCALL:
661                 o = p->in.op = UNARY STCALL;
662                 ifgenscallpcookie ) ) goto nomat;
663                 goto cleanup;
664
665                 /* if arguments are passed in register, care must be taken that reclaim
ragge
1.2
666                  * not throw away the register which now has the result... */
ragge
1.1
667
668         case UNARY MUL:
669                 ifcook == FOREFF ){
670                         /* do nothing */
671                         orderp->in.leftFOREFF );
672                         p->in.op = FREE;
673                         return;
674                         }
675 #ifdef R2REGS
676                 /* try to coax a tree into a doubly indexed OREG */
677                 p1 = p->in.left;
678                 ifp1->in.op == PLUS ) {
679                         ifISPTR(p1->in.left->in.type) &&
680                             offset(p1->in.righttlen(p)) >= 0 ) {
681                                 orderp1->in.leftINAREG|INTAREG );
682                                 goto again;
683                                 }
684                         ifISPTR(p1->in.right->in.type) &&
685                             offset(p1->in.lefttlen(p)) >= 0 ) {
686                                 orderp1->in.rightINAREG|INTAREG );
687                                 goto again;
688                                 }
689                         }
690 #endif
691                 offstarp->in.left );
692                 goto again;
693
694         case INCR:  /* INCR and DECR */
695                 ifsetincr(p) ) goto again;
696
697                 /* x++ becomes (x += 1) -1; */
698
699                 ifcook & FOREFF ){  /* result not needed so inc or dec and be done with it */
700                         /* x++ => x += 1 */
701                         p->in.op = (p->in.op==INCR)?ASG PLUS:ASG MINUS;
702                         goto again;
703                         }
704
705                 p1 = tcopy(p);
706                 reclaimp->in.leftRNULL0 );
707                 p->in.left = p1;
708                 p1->in.op = (p->in.op==INCR)?ASG PLUS:ASG MINUS;
709                 p->in.op = (p->in.op==INCR)?MINUS:PLUS;
710                 goto again;
711
712         case STASG:
713                 ifsetstrp ) ) goto again;
714                 goto nomat;
715
716         case ASG PLUS:  /* and other assignment ops */
717                 ifsetasop(p) ) goto again;
718
719                 /* there are assumed to be no side effects in LHS */
720
721                 p2 = tcopy(p);
722                 p->in.op = ASSIGN;
723                 reclaimp->in.rightRNULL0 );
724                 p->in.right = p2;
725                 canon(p);
726                 rallopp->in.rall );
727
728 # ifndef BUG4
729                 ifodebug ) fwalkpeprint0 );
730 # endif
731
732                 orderp2->in.leftINTBREG|INTAREG );
733                 orderp2INTBREG|INTAREG );
734                 goto again;
735
736         case ASSIGN:
737                 ifsetasgp ) ) goto again;
738                 goto nomat;
739
740
741         case BITYPE:
742                 ifsetbinp ) ) goto again;
743                 /* try to replace binary ops by =ops */
744                 switch(o){
745
746                 case PLUS:
747                 case MINUS:
748                 case MUL:
749                 case DIV:
750                 case MOD:
751                 case AND:
752                 case OR:
753                 case ER:
754                 case LS:
755                 case RS:
756                         p->in.op = ASG o;
757                         goto again;
758                         }
759                 goto nomat;
760
761                 }
762
763         cleanup:
764
765         /* if it is not yet in the right state, put it there */
766
767         ifcook & FOREFF ){
768                 reclaimpRNULL0 );
769                 return;
770                 }
771
772         ifp->in.op==FREE ) return;
773
774         iftshapepcook ) ) return;
775
776         if( (m=match(p,cook) ) == MDONE ) return;
777
778         /* we are in bad shape, try one last chance */
779         iflastchancepcook ) ) goto again;
780
781         goto nomat;
782         }
783
784 int callflag;
785 int fregs;
786
ragge
1.2
787 void
788 storep ) NODE *p; {
ragge
1.1
789
790         /* find a subtree of p which should be stored */
791
ragge
1.2
792         int oty;
ragge
1.1
793
794         o = p->in.op;
795         ty = optype(o);
796
797         ifty == LTYPE ) return;
798
799         switcho ){
800
801         case UNARY CALL:
802         case UNARY FORTCALL:
803         case UNARY STCALL:
804                 ++callflag;
805                 break;
806
807         case UNARY MUL:
808                 ifasgop(p->in.left->in.op) ) stoasgp->in.leftUNARY MUL );
809                 break;
810
811         case CALL:
812         case FORTCALL:
813         case STCALL:
814                 storep->in.left );
815                 stoargp->in.righto );
816                 ++callflag;
817                 return;
818
819         case COMOP:
820                 markcallp->in.right );
821                 ifp->in.right->in.su > fregs ) SETSTOpINTEMP );
822                 storep->in.left );
823                 return;
824
825         case ANDAND:
826         case OROR:
827         case QUEST:
828                 markcallp->in.right );
829                 ifp->in.right->in.su > fregs ) SETSTOpINTEMP );
830         case CBRANCH:   /* to prevent complicated expressions on the LHS from being stored */
831         case NOT:
832                 constorep->in.left );
833                 return;
834
835                 }
836
837         ifty == UTYPE ){
838                 storep->in.left );
839                 return;
840                 }
841
842         ifasgopp->in.right->in.op ) ) stoasgp->in.righto );
843
844         ifp->in.su>fregs ){ /* must store */
845                 mkadrsp );  /* set up stotree and stocook to subtree
846                                  that must be stored */
847                 }
848
849         storep->in.right );
850         storep->in.left );
851         }
852
ragge
1.2
853 /*
854  * store conditional expressions
855  * the point is, avoid storing expressions in conditional
856  * conditional context, since the evaluation order is predetermined
857  */
858 void
859 constore(NODE *p)
860 {
ragge
1.1
861         switchp->in.op ) {
862
863         case ANDAND:
864         case OROR:
865         case QUEST:
866                 markcallp->in.right );
867         case NOT:
868                 constorep->in.left );
869                 return;
870
871                 }
872
873         storep );
ragge
1.2
874 }
ragge
1.1
875
ragge
1.2
876 /* mark off calls below the current node */
877 void
878 markcall(NODE *p)
879 {
ragge
1.1
880
881         again:
882         switchp->in.op ){
883
884         case UNARY CALL:
885         case UNARY STCALL:
886         case UNARY FORTCALL:
887         case CALL:
888         case STCALL:
889         case FORTCALL:
890                 ++callflag;
891                 return;
892
893                 }
894
895         switchoptypep->in.op ) ){
896
897         case BITYPE:
898                 markcallp->in.right );
899         case UTYPE:
900                 p = p->in.left;
901                 /* eliminate recursion (aren't I clever...) */
902                 goto again;
903         case LTYPE:
904                 return;
905                 }
906
ragge
1.2
907 }
ragge
1.1
908
ragge
1.2
909 void
910 stoarg(NODE *pint calltype)
911 {
ragge
1.1
912         /* arrange to store the args */
913         ifp->in.op == CM ){
914                 stoargp->in.leftcalltype );
915                 p = p->in.right ;
916                 }
917         ifcalltype == CALL ){
918                 STOARG(p);
919                 }
920         else ifcalltype == STCALL ){
921                 STOSTARG(p);
922                 }
923         else {
924                 STOFARG(p);
925                 }
926         callflag = 0;
927         store(p);
928 # ifndef NESTCALLS
929         ifcallflag ){ /* prevent two calls from being active at once  */
930                 SETSTO(p,INTEMP);
931                 store(p); /* do again to preserve bottom up nature....  */
ragge
1.2
932         }
ragge
1.1
933 #endif
ragge
1.2
934 }
ragge
1.1
935
936 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
937
ragge
1.2
938 /*
939  * evaluate p for truth value, and branch to true or false
940  * accordingly: label <0 means fall through
941  */
942
943 void
944 cbranch(NODE *pint trueint false)
945 {
946         int olabflabtlab;
ragge
1.1
947
948         lab = -1;
949
950         switcho=p->in.op ){
951
952         case ULE:
953         case ULT:
954         case UGE:
955         case UGT:
956         case EQ:
957         case NE:
958         case LE:
959         case LT:
960         case GE:
961         case GT:
962                 iftrue < 0 ){
963                         o = p->in.op = negrelo-EQ ];
964                         true = false;
965                         false = -1;
966                         }
967 #ifndef NOOPT
968                 ifp->in.right->in.op == ICON && p->in.right->tn.lval == 0 && p->in.right->in.name[0] == '\0' ){
969                         switcho ){
970
971                         case UGT:
972                         case ULE:
973                                 o = p->in.op = (o==UGT)?NE:EQ;
974                         case EQ:
975                         case NE:
976                         case LE:
977                         case LT:
978                         case GE:
979                         case GT:
980                                 iflogop(p->in.left->in.op) ){
981                                         /* strange situation: e.g., (a!=0) == 0 */
982                                         /* must prevent reference to p->in.left->lable, so get 0/1 */
983                                         /* we could optimize, but why bother */
984                                         codgenp->in.leftINAREG|INBREG );
985                                         }
986                                 codgenp->in.leftFORCC );
987                                 cbgenotrue'I' );
988                                 break;
989
990                         case UGE:
991                                 codgen(p->in.leftFORCC);
992                                 cbgen0true'I' );  /* unconditional branch */
993                                 break;
994                         case ULT:
995                                 codgen(p->in.leftFORCC);
996                                 }
997                         }
998                 else
999 #endif
1000                         {
1001                         p->bn.label = true;
1002                         codgenpFORCC );
1003                         }
1004                 iffalse>=0 ) cbgen0false'I' );
1005                 reclaimpRNULL0 );
1006                 return;
1007
1008         case ANDAND:
1009                 lab = false<0 ? getlab() : false ;
1010                 cbranchp->in.left, -1lab );
1011                 cbranchp->in.righttruefalse );
1012                 iffalse < 0 ) deflablab );
1013                 p->in.op = FREE;
1014                 return;
1015
1016         case OROR:
1017                 lab = true<0 ? getlab() : true;
1018                 cbranchp->in.leftlab, -1 );
1019                 cbranchp->in.righttruefalse );
1020                 iftrue < 0 ) deflablab );
1021                 p->in.op = FREE;
1022                 return;
1023
1024         case NOT:
1025                 cbranchp->in.leftfalsetrue );
1026                 p->in.op = FREE;
1027                 break;
1028
1029         case COMOP:
1030                 codgenp->in.leftFOREFF );
1031                 p->in.op = FREE;
1032                 cbranchp->in.righttruefalse );
1033                 return;
1034
1035         case QUEST:
1036                 flab = false<0 ? getlab() : false;
1037                 tlab = true<0 ? getlab() : true;
1038                 cbranchp->in.left, -1lab = getlab() );
1039                 cbranchp->in.right->in.lefttlabflab );
1040                 deflablab );
1041                 cbranchp->in.right->in.righttruefalse );
1042                 iftrue < 0 ) deflabtlab);
1043                 iffalse < 0 ) deflabflab );
1044                 p->in.right->in.op = FREE;
1045                 p->in.op = FREE;
1046                 return;
1047
1048         case ICON:
1049                 ifp->in.type != FLOAT && p->in.type != DOUBLE ){
1050
1051                         ifp->tn.lval || p->in.name[0] ){
1052                                 /* addresses of C objects are never 0 */
1053                                 iftrue>=0 ) cbgen0true'I' );
1054                                 }
1055                         else iffalse>=0 ) cbgen0false'I' );
1056                         p->in.op = FREE;
1057                         return;
1058                         }
1059                 /* fall through to default with other strange constants */
1060
1061         default:
1062                 /* get condition codes */
1063                 codgenpFORCC );
1064                 iftrue >= 0 ) cbgenNEtrue'I' );
1065                 iffalse >= 0 ) cbgentrue >= 0 ? 0 : EQfalse'I' );
1066                 reclaimpRNULL0 );
1067                 return;
1068
1069                 }
1070
1071         }
1072
ragge
1.2
1073 void
1074 rcount()
1075 /* count recursions */
ragge
1.1
1076         if( ++nrecur > NRECUR ){
1077                 cerror"expression causes compiler loop: try simplifying" );
1078         }
ragge
1.2
1079 }
ragge
1.1
1080
1081 # ifndef BUG4
ragge
1.2
1082 int
1083 eprint(NODE *pint downint *aint *b)
1084 {
ragge
1.1
1085
1086         *a = *b = down+1;
1087         whiledown >= 2 ){
1088                 printf"\t" );
1089                 down -= 2;
1090                 }
1091         ifdown-- ) printf"    " );
1092
1093
ragge
1.2
1094         printf"%p) %s"popst[p->in.op] );
ragge
1.1
1095         switchp->in.op ) { /* special cases */
1096
1097         case REG:
1098                 printf" %s"rnames[p->tn.rval] );
1099                 break;
1100
1101         case ICON:
1102         case NAME:
1103         case OREG:
1104                 printf" " );
1105                 adrputp );
1106                 break;
1107
1108         case STCALL:
1109         case UNARY STCALL:
1110         case STARG:
1111         case STASG:
1112                 printf" size=%d"p->stn.stsize );
1113                 printf" align=%d"p->stn.stalign );
1114                 break;
1115                 }
1116
1117         printf", " );
1118         tprintp->in.type );
1119         printf", " );
1120