Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030729200301

Diff

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