Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030730094858

Diff

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