Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030729092515

Diff

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