Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030809094732

Diff

Diff from 1.42 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/mip/reader.c

Annotated File View

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