Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030730084730

Diff

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