Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20020505174551

Diff

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