Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030816145806

Diff

Diff from 1.45 to:

Annotations

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

Annotated File View

ragge
1.45
1 /*      $Id: reader.c,v 1.45 2003/08/16 14:58:06 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.43
465                         if (!istnode(p->n_left))
466                                 order(p->n_leftINTAREG|INTBREG);
ragge
1.13
467                         p->n_op = ASG o;
ragge
1.1
468                         goto again;
469                         }
470                 goto nomat;
471
472                 }
473
474         cleanup:
475
476         /* if it is not yet in the right state, put it there */
477
478         ifcook & FOREFF ){
479                 reclaimpRNULL0 );
480                 return;
481                 }
482
ragge
1.13
483         ifp->n_op==FREE ) return;
ragge
1.1
484
485         iftshapepcook ) ) return;
486
487         if( (m=match(p,cook) ) == MDONE ) return;
488
489         /* we are in bad shape, try one last chance */
ragge
1.8
490         if (lastchance(pcook))
491                 goto again;
ragge
1.1
492
493         goto nomat;
ragge
1.8
494 }
ragge
1.1
495
496 int callflag;
497 int fregs;
498
ragge
1.2
499 void
500 storep ) NODE *p; {
ragge
1.1
501
502         /* find a subtree of p which should be stored */
503
ragge
1.2
504         int oty;
ragge
1.1
505
ragge
1.13
506         o = p->n_op;
ragge
1.1
507         ty = optype(o);
508
509         ifty == LTYPE ) return;
510
511         switcho ){
512
513         case UNARY CALL:
514         case UNARY FORTCALL:
515         case UNARY STCALL:
516                 ++callflag;
517                 break;
518
519         case UNARY MUL:
ragge
1.13
520                 if (asgop(p->n_left->n_op))
521                         stoasg(p->n_leftUNARY MUL);
ragge
1.1
522                 break;
523
524         case CALL:
525         case FORTCALL:
526         case STCALL:
ragge
1.13
527                 storep->n_left );
528                 stoargp->n_righto );
ragge
1.1
529                 ++callflag;
530                 return;
531
532         case CBRANCH:   /* to prevent complicated expressions on the LHS from being stored */
ragge
1.13
533                 constorep->n_left );
ragge
1.1
534                 return;
535
536                 }
537
ragge
1.11
538         if (ty == UTYPE) {
ragge
1.13
539                 store(p->n_left);
ragge
1.1
540                 return;
ragge
1.11
541         }
ragge
1.1
542
ragge
1.13
543         if (asgop(p->n_right->n_op))
544                 stoasg(p->n_righto);
ragge
1.1
545
ragge
1.13
546         ifp->n_su>fregs ){ /* must store */
ragge
1.1
547                 mkadrsp );  /* set up stotree and stocook to subtree
548                                  that must be stored */
549                 }
550
ragge
1.13
551         storep->n_right );
552         storep->n_left );
ragge
1.1
553         }
554
ragge
1.2
555 /*
556  * store conditional expressions
557  * the point is, avoid storing expressions in conditional
558  * conditional context, since the evaluation order is predetermined
559  */
560 void
561 constore(NODE *p)
562 {
ragge
1.1
563         storep );
ragge
1.2
564 }
ragge
1.1
565
ragge
1.2
566 /* mark off calls below the current node */
567 void
568 markcall(NODE *p)
569 {
ragge
1.1
570
571         again:
ragge
1.13
572         switchp->n_op ){
ragge
1.1
573
574         case UNARY CALL:
575         case UNARY STCALL:
576         case UNARY FORTCALL:
577         case CALL:
578         case STCALL:
579         case FORTCALL:
580                 ++callflag;
581                 return;
582
583                 }
584
ragge
1.13
585         switchoptypep->n_op ) ){
ragge
1.1
586
587         case BITYPE:
ragge
1.13
588                 markcallp->n_right );
ragge
1.1
589         case UTYPE:
ragge
1.13
590                 p = p->n_left;
ragge
1.1
591                 /* eliminate recursion (aren't I clever...) */
592                 goto again;
593         case LTYPE:
594                 return;
595                 }
596
ragge
1.2
597 }
ragge
1.1
598
ragge
1.2
599 void
600 stoarg(NODE *pint calltype)
601 {
ragge
1.1
602         /* arrange to store the args */
ragge
1.13
603         ifp->n_op == CM ){
604                 stoargp->n_leftcalltype );
605                 p = p->n_right ;
ragge
1.1
606                 }
607         ifcalltype == CALL ){
608                 STOARG(p);
609                 }
610         else ifcalltype == STCALL ){
611                 STOSTARG(p);
612                 }
613         else {
614                 STOFARG(p);
615                 }
616         callflag = 0;
617         store(p);
ragge
1.30
618 #ifdef NO_NESTCALLS
ragge
1.1
619         ifcallflag ){ /* prevent two calls from being active at once  */
620                 SETSTO(p,INTEMP);
621                 store(p); /* do again to preserve bottom up nature....  */
ragge
1.2
622         }
ragge
1.1
623 #endif
ragge
1.2
624 }
ragge
1.1
625
626 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
627
ragge
1.2
628 void
629 rcount()
630 /* count recursions */
ragge
1.1
631         if( ++nrecur > NRECUR ){
632                 cerror"expression causes compiler loop: try simplifying" );
633         }
ragge
1.2
634 }
ragge
1.1
635
ragge
1.30
636 #ifdef PCC_DEBUG
ragge
1.2
637 int
ragge
1.8
638 e2print(NODE *pint downint *aint *b)
ragge
1.2
639 {
ragge
1.1
640
641         *a = *b = down+1;
642         whiledown >= 2 ){
643                 printf"\t" );
644                 down -= 2;
645                 }
646         ifdown-- ) printf"    " );
647
648
ragge
1.13
649         printf"%p) %s"popst[p->n_op] );
650         switchp->n_op ) { /* special cases */
ragge
1.1
651
652         case REG:
ragge
1.13
653                 printf" %s"rnames[p->n_rval] );
ragge
1.1
654                 break;
655
ragge
1.23
656         case TEMP:
657                 printf(" %d", (int)p->n_lval);
658                 break;
659
ragge
1.1
660         case ICON:
661         case NAME:
662         case OREG:
663                 printf" " );
664                 adrputp );
665                 break;
666
667         case STCALL:
668         case UNARY STCALL:
669         case STARG:
670         case STASG:
ragge
1.13
671                 printf" size=%d"p->n_stsize );
672                 printf" align=%d"p->n_stalign );
ragge
1.1
673                 break;
674                 }
675
676         printf", " );
ragge
1.33
677         tprintp->n_typep->n_qual);
ragge
1.1
678         printf", " );
ragge
1.13
679         ifp->n_rall == NOPREF ) printf"NOPREF" );
ragge
1.1
680         else {
ragge
1.13
681                 ifp->n_rall & MUSTDO ) printf"MUSTDO " );
ragge
1.1
682                 else printf"PREF " );
ragge
1.13
683                 printf"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
684                 }
ragge
1.13
685         printf", SU= %d\n"p->n_su );
ragge
1.2
686         return 0;
687 }
ragge
1.30
688 #endif
ragge
1.1
689
690 #ifndef FIELDOPS
ragge
1.7
691 /*
692  * do this if there is no special hardware support for fields
693  */
694 static int
695 ffld(NODE *pint downint *down1int *down2 )
696 {
697         /*
698          * look for fields that are not in an lvalue context,
699          * and rewrite them...
700          */
701         NODE *shp;
702         int sovty;
ragge
1.1
703
ragge
1.13
704         *down1 =  asgopp->n_op );
ragge
1.1
705         *down2 = 0;
706
ragge
1.13
707         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
708
ragge
1.7
709                 if( !rewfld(p) ) return 0;
ragge
1.1
710
ragge
1.13
711                 ty = (szty(p->n_type) == 2)? LONGINT;
712                 v = p->n_rval;
ragge
1.1
713                 s = UPKFSZ(v);
714 # ifdef RTOLBYTES
715                 o = UPKFOFF(v);  /* amount to shift */
716 # else
ragge
1.13
717                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
718 #endif
719
720                 /* make & mask part */
721
ragge
1.13
722                 p->n_left->n_type = ty;
ragge
1.1
723
ragge
1.13
724                 p->n_op = AND;
725                 p->n_right = talloc();
726                 p->n_right->n_op = ICON;
727                 p->n_right->n_rall = NOPREF;
728                 p->n_right->n_type = ty;
729                 p->n_right->n_lval = 1;
730                 p->n_right->n_rval = 0;
731                 p->n_right->n_name = "";
732                 p->n_right->n_lval <<= s;
733                 p->n_right->n_lval--;
ragge
1.1
734
735                 /* now, if a shift is needed, do it */
736
737                 ifo != 0 ){
738                         shp = talloc();
ragge
1.13
739                         shp->n_op = RS;
740                         shp->n_rall = NOPREF;
741                         shp->n_type = ty;
742                         shp->n_left = p->n_left;
743                         shp->n_right = talloc();
744                         shp->n_right->n_op = ICON;
745                         shp->n_right->n_rall = NOPREF;
746                         shp->n_right->n_type = ty;
747                         shp->n_right->n_rval = 0;
748                         shp->n_right->n_lval = o;  /* amount to shift */
749                         shp->n_right->n_name = "";
750                         p->n_left = shp;
ragge
1.1
751                         /* whew! */
752                 }
753         }
ragge
1.7
754         return 0;
755 }
ragge
1.1
756 #endif
757
ragge
1.23
758 /*
759  * change left TEMPs into OREGs
ragge
1.40
760  */
761 void
762 deltemp(NODE *p)
763 {
764         struct templst *w = templst;
765
766         if (p->n_op != TEMP)
767                 return;
768         /*
769          * the size of a TEMP is in multiples of the reg size.
770          */
771         p->n_op = OREG;
772         p->n_rval = FPREG;
773         while (w != NULL) {
774                 if (w->tempnr == p->n_lval)
775                         break;
776                 w = w->next;
777         }
778         if (w == NULL) {
779                 w = tmpalloc(sizeof(struct templst));
780                 w->tempnr = p->n_lval;
781                 w->tempoff = BITOOR(freetemp(szty(p->n_type)));
782                 w->next = templst;
783                 templst = w;
784         }
785         p->n_lval = w->tempoff;
786         p->n_name = "";
787 }
788
789 /*
ragge
1.23
790  * look for situations where we can turn * into OREG
791  */
ragge
1.2
792 void
793 oreg2(NODE *p)
794 {
ragge
1.1
795
796         NODE *q;
ragge
1.2
797         int r;
798         char *cp;
799         NODE *ql, *qr;
ragge
1.1
800         CONSZ temp;
ragge
1.23
801
ragge
1.44
802         if (Oflag == 0)
803                 deltemp(p);
ragge
1.1
804
ragge
1.13
805         if (p->n_op == UNARY MUL) {
806                 q = p->n_left;
807                 if (q->n_op == REG) {
808                         temp = q->n_lval;
809                         r = q->n_rval;
810                         cp = q->n_name;
ragge
1.1
811                         goto ormake;
ragge
1.12
812                 }
ragge
1.1
813
ragge
1.13
814                 if (q->n_op != PLUS && q->n_op != MINUS)
ragge
1.12
815                         return;
ragge
1.13
816                 ql = q->n_left;
817                 qr = q->n_right;
ragge
1.1
818
819 #ifdef R2REGS
820
821                 /* look for doubly indexed expressions */
822
ragge
1.13
823                 ifq->n_op == PLUS) {
ragge
1.7
824                         int i;
ragge
1.1
825                         if( (r=base(ql))>=0 && (i=offset(qrtlen(p)))>=0) {
826                                 makeor2(pqlri);
827                                 return;
ragge
1.12
828                         } else if((r=base(qr))>=0 && (i=offset(qltlen(p)))>=0) {
ragge
1.1
829                                 makeor2(pqrri);
830                                 return;
831                         }
ragge
1.12
832                 }
ragge
1.1
833
834
835 #endif
836
ragge
1.13
837                 if( (q->n_op==PLUS || q->n_op==MINUS) && qr->n_op == ICON &&
838                                 ql->n_op==REG && szty(qr->n_type)==1) {
839                         temp = qr->n_lval;
840                         ifq->n_op == MINUS ) temp = -temp;
841                         r = ql->n_rval;
842                         temp += ql->n_lval;
843                         cp = qr->n_name;
844                         if( *cp && ( q->n_op == MINUS || *ql->n_name ) ) return;
845                         if( !*cp ) cp = ql->n_name;
ragge
1.1
846
847                         ormake:
ragge
1.13
848                         ifnotoffp->n_typertempcp ) ) return;
849                         p->n_op = OREG;
850                         p->n_rval = r;
851                         p->n_lval = temp;
852                         p->n_name = cp;
ragge
1.1
853                         tfree(q);
854                         return;
855                 }
856         }
ragge
1.12
857 }
ragge
1.1
858
ragge
1.2
859 void
ragge
1.1
860 canon(pNODE *p; {
861         /* put p in canonical form */
862
863 #ifndef FIELDOPS
864         fwalkpffld0 ); /* look for field operators */
865 # endif
866         walkfporeg2 );  /* look for and create OREG nodes */
867 #ifdef MYCANON
868         MYCANON(p);  /* your own canonicalization routine(s) */
869 #endif
870         walkfpsucomp );  /* do the Sethi-Ullman computation */
871
ragge
1.2
872 }
ragge
1.1
873
ragge
1.37
874 static SIMPLEQ_HEAD(, interpassipole = SIMPLEQ_HEAD_INITIALIZER(ipole);
875
876 void
877 saveip(struct interpass *ip)
878 {
ragge
1.40
879         struct interpass *prol;
880
ragge
1.37
881         SIMPLEQ_INSERT_TAIL(&ipoleipsqelem);
882
883         if (ip->type != IP_EPILOG)
884                 return;
885         saving = -1;
886
ragge
1.40
887         cvtemps(ip);    /* Convert TEMPs to OREGs */
888         deljumps();     /* Delete redundant jumps and dead code */
889
890         prol = SIMPLEQ_FIRST(&ipole);
891         prol->ip_auto = ip->ip_auto;
892         prol->ip_regs = ip->ip_regs;
893
894 #ifdef MYOPTIM
895         myoptim(prol);
896 #endif
ragge
1.37
897
898         while ((ip = SIMPLEQ_FIRST(&ipole))) {
899                 SIMPLEQ_REMOVE_HEAD(&ipolesqelem);
900                 pass2_compile(ip);
901         }
ragge
1.40
902 }
903
904 /*
905  * Convert TEMPs to OREGs.
906  * XXX - ugly.
907  */
908 void
909 cvtemps(struct interpass *epil)
910 {
911         struct interpass *ip;
912
ragge
1.45
913         SETOFF(epil->ip_autoALINT);
ragge
1.44
914         maxautooff = autooff = epil->ip_auto;
ragge
1.40
915         SIMPLEQ_FOREACH(ip, &ipolesqelem) {
916                 if (ip->type != IP_NODE)
917                         continue;
918                 walkf(ip->ip_nodedeltemp);
919         }
920         epil->ip_auto = maxautooff;
ragge
1.37
921 }
922
923 void
924 deljumps()
925 {
926         struct interpass *ip, *n;
927         int gotone;
928
929 again:  gotone = 0;
930
931         SIMPLEQ_FOREACH(ip, &ipolesqelem) {
932                 if (ip->type == IP_EPILOG)
933                         return;
934                 if (ip->type != IP_NODE)
935                         continue;
936                 if (ip->ip_node->n_op != GOTO)
937                         continue;
938                 n = ip->sqelem.sqe_next;
939                 switch (n->type) {
940                 case IP_NODE:
941                         tfree(n->ip_node);
942                         ip->sqelem.sqe_next = n->sqelem.sqe_next;
943                         break;
944                 case IP_DEFLAB:
945                         if (ip->ip_node->n_left->n_lval != n->ip_lbl)
946                                 continue;
947                         tfree(ip->ip_node);
948                         *ip = *n;
949                         break;
950                 default:
951                         continue;
952                 }
953                 gotone = 1;
954         }
955         if (gotone)
956                 goto again;
957 }
958
959 void
960 optdump(struct interpass *ip)
961 {
962         static char *nm[] = { "node""prolog""newblk""epilog""locctr",
ragge
1.41
963                 "deflab""defnam""asm" };