Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030805092755

Diff

Diff from 1.41 to:

Annotations

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

Annotated File View

ragge
1.41
1 /*      $Id: reader.c,v 1.41 2003/08/05 09:27:55 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;
335                 codgen(p1FORCC);
336                 reclaim(p1RNULL0);
ragge
1.19
337                 nfree(p2);
338                 nfree(p);
ragge
1.1
339                 return;
340
341         case FLD:       /* fields of funny type */
ragge
1.13
342                 if ( p1->n_op == UNARY MUL ){
343                         offstarp1->n_left );
ragge
1.1
344                         goto again;
345                         }
346
347         case UNARY MINUS:
ragge
1.30
348                 orderp1INBREG|INAREG);
ragge
1.1
349                 goto again;
350
351         case NAME:
352                 /* all leaves end up here ... */
353                 ifo == REG ) goto nomat;
354                 orderpINTAREG|INTBREG );
355                 goto again;
356
357         case INIT:
ragge
1.12
358                 uerror("init: illegal initialization");
ragge
1.1
359                 return;
360
361         case UNARY FORTCALL:
ragge
1.13
362                 p->n_right = NIL;
ragge
1.1
363         case FORTCALL:
ragge
1.13
364                 o = p->n_op = UNARY FORTCALL;
ragge
1.1
365                 ifgenfcallpcookie ) ) goto nomat;
366                 goto cleanup;
367
368         case UNARY CALL:
ragge
1.13
369                 p->n_right = NIL;
ragge
1.1
370         case CALL:
ragge
1.13
371                 o = p->n_op = UNARY CALL;
ragge
1.1
372                 ifgencallpcookie ) ) goto nomat;
373                 goto cleanup;
374
375         case UNARY STCALL:
ragge
1.13
376                 p->n_right = NIL;
ragge
1.1
377         case STCALL:
ragge
1.13
378                 o = p->n_op = UNARY STCALL;
ragge
1.1
379                 ifgenscallpcookie ) ) goto nomat;
380                 goto cleanup;
381
382                 /* if arguments are passed in register, care must be taken that reclaim
ragge
1.2
383                  * not throw away the register which now has the result... */
ragge
1.1
384
385         case UNARY MUL:
386                 ifcook == FOREFF ){
387                         /* do nothing */
ragge
1.13
388                         orderp->n_leftFOREFF );
ragge
1.19
389                         nfree(p);
ragge
1.1
390                         return;
ragge
1.19
391                 }
ragge
1.30
392                 offstarp->n_left );
393 #if 0
394                 canon(p);
395                 ifcanaddr(p) && cook != INTEMP )
396                         goto cleanup;
ragge
1.1
397 #endif
398                 goto again;
399
400         case INCR:  /* INCR and DECR */
401                 ifsetincr(p) ) goto again;
402
403                 /* x++ becomes (x += 1) -1; */
404
405                 ifcook & FOREFF ){  /* result not needed so inc or dec and be done with it */
406                         /* x++ => x += 1 */
ragge
1.13
407                         p->n_op = (p->n_op==INCR)?ASG PLUS:ASG MINUS;
ragge
1.1
408                         goto again;
409                         }
410
411                 p1 = tcopy(p);
ragge
1.13
412                 reclaimp->n_leftRNULL0 );
413                 p->n_left = p1;
414                 p1->n_op = (p->n_op==INCR)?ASG PLUS:ASG MINUS;
415                 p->n_op = (p->n_op==INCR)?MINUS:PLUS;
ragge
1.1
416                 goto again;
417
418         case STASG:
419                 ifsetstrp ) ) goto again;
420                 goto nomat;
421
422         case ASG PLUS:  /* and other assignment ops */
423                 ifsetasop(p) ) goto again;
424
425                 /* there are assumed to be no side effects in LHS */
426
427                 p2 = tcopy(p);
ragge
1.13
428                 p->n_op = ASSIGN;
429                 reclaimp->n_rightRNULL0 );
430                 p->n_right = p2;
ragge
1.1
431                 canon(p);
ragge
1.13
432                 rallopp->n_rall );
ragge
1.1
433
ragge
1.30
434 #ifdef PCC_DEBUG
ragge
1.8
435                 ifodebug ) fwalkpe2print0 );
ragge
1.30
436 #endif
ragge
1.1
437
ragge
1.13
438                 orderp2->n_leftINTBREG|INTAREG );
ragge
1.1
439                 orderp2INTBREG|INTAREG );
440                 goto again;
441
442         case ASSIGN:
ragge
1.8
443                 if (setasg(p))
444                         goto again;
ragge
1.1
445                 goto nomat;
446
447
448         case BITYPE:
449                 ifsetbinp ) ) goto again;
450                 /* try to replace binary ops by =ops */
451                 switch(o){
452
453                 case PLUS:
454                 case MINUS:
455                 case MUL:
456                 case DIV:
457                 case MOD:
458                 case AND:
459                 case OR:
460                 case ER:
461                 case LS:
462                 case RS:
ragge
1.13
463                         p->n_op = ASG o;
ragge
1.1
464                         goto again;
465                         }
466                 goto nomat;
467
468                 }
469
470         cleanup:
471
472         /* if it is not yet in the right state, put it there */
473
474         ifcook & FOREFF ){
475                 reclaimpRNULL0 );
476                 return;
477                 }
478
ragge
1.13
479         ifp->n_op==FREE ) return;
ragge
1.1
480
481         iftshapepcook ) ) return;
482
483         if( (m=match(p,cook) ) == MDONE ) return;
484
485         /* we are in bad shape, try one last chance */
ragge
1.8
486         if (lastchance(pcook))
487                 goto again;
ragge
1.1
488
489         goto nomat;
ragge
1.8
490 }
ragge
1.1
491
492 int callflag;
493 int fregs;
494
ragge
1.2
495 void
496 storep ) NODE *p; {
ragge
1.1
497
498         /* find a subtree of p which should be stored */
499
ragge
1.2
500         int oty;
ragge
1.1
501
ragge
1.13
502         o = p->n_op;
ragge
1.1
503         ty = optype(o);
504
505         ifty == LTYPE ) return;
506
507         switcho ){
508
509         case UNARY CALL:
510         case UNARY FORTCALL:
511         case UNARY STCALL:
512                 ++callflag;
513                 break;
514
515         case UNARY MUL:
ragge
1.13
516                 if (asgop(p->n_left->n_op))
517                         stoasg(p->n_leftUNARY MUL);
ragge
1.1
518                 break;
519
520         case CALL:
521         case FORTCALL:
522         case STCALL:
ragge
1.13
523                 storep->n_left );
524                 stoargp->n_righto );
ragge
1.1
525                 ++callflag;
526                 return;
527
528         case CBRANCH:   /* to prevent complicated expressions on the LHS from being stored */
ragge
1.13
529                 constorep->n_left );
ragge
1.1
530                 return;
531
532                 }
533
ragge
1.11
534         if (ty == UTYPE) {
ragge
1.13
535                 store(p->n_left);
ragge
1.1
536                 return;
ragge
1.11
537         }
ragge
1.1
538
ragge
1.13
539         if (asgop(p->n_right->n_op))
540                 stoasg(p->n_righto);
ragge
1.1
541
ragge
1.13
542         ifp->n_su>fregs ){ /* must store */
ragge
1.1
543                 mkadrsp );  /* set up stotree and stocook to subtree
544                                  that must be stored */
545                 }
546
ragge
1.13
547         storep->n_right );
548         storep->n_left );
ragge
1.1
549         }
550
ragge
1.2
551 /*
552  * store conditional expressions
553  * the point is, avoid storing expressions in conditional
554  * conditional context, since the evaluation order is predetermined
555  */
556 void
557 constore(NODE *p)
558 {
ragge
1.1
559         storep );
ragge
1.2
560 }
ragge
1.1
561
ragge
1.2
562 /* mark off calls below the current node */
563 void
564 markcall(NODE *p)
565 {
ragge
1.1
566
567         again:
ragge
1.13
568         switchp->n_op ){
ragge
1.1
569
570         case UNARY CALL:
571         case UNARY STCALL:
572         case UNARY FORTCALL:
573         case CALL:
574         case STCALL:
575         case FORTCALL:
576                 ++callflag;
577                 return;
578
579                 }
580
ragge
1.13
581         switchoptypep->n_op ) ){
ragge
1.1
582
583         case BITYPE:
ragge
1.13
584                 markcallp->n_right );
ragge
1.1
585         case UTYPE:
ragge
1.13
586                 p = p->n_left;
ragge
1.1
587                 /* eliminate recursion (aren't I clever...) */
588                 goto again;
589         case LTYPE:
590                 return;
591                 }
592
ragge
1.2
593 }
ragge
1.1
594
ragge
1.2
595 void
596 stoarg(NODE *pint calltype)
597 {
ragge
1.1
598         /* arrange to store the args */
ragge
1.13
599         ifp->n_op == CM ){
600                 stoargp->n_leftcalltype );
601                 p = p->n_right ;
ragge
1.1
602                 }
603         ifcalltype == CALL ){
604                 STOARG(p);
605                 }
606         else ifcalltype == STCALL ){
607                 STOSTARG(p);
608                 }
609         else {
610                 STOFARG(p);
611                 }
612         callflag = 0;
613         store(p);
ragge
1.30
614 #ifdef NO_NESTCALLS
ragge
1.1
615         ifcallflag ){ /* prevent two calls from being active at once  */
616                 SETSTO(p,INTEMP);
617                 store(p); /* do again to preserve bottom up nature....  */
ragge
1.2
618         }
ragge
1.1
619 #endif
ragge
1.2
620 }
ragge
1.1
621
622 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
623
ragge
1.2
624 void
625 rcount()
626 /* count recursions */
ragge
1.1
627         if( ++nrecur > NRECUR ){
628                 cerror"expression causes compiler loop: try simplifying" );
629         }
ragge
1.2
630 }
ragge
1.1
631
ragge
1.30
632 #ifdef PCC_DEBUG
ragge
1.2
633 int
ragge
1.8
634 e2print(NODE *pint downint *aint *b)
ragge
1.2
635 {
ragge
1.1
636
637         *a = *b = down+1;
638         whiledown >= 2 ){
639                 printf"\t" );
640                 down -= 2;
641                 }
642         ifdown-- ) printf"    " );
643
644
ragge
1.13
645         printf"%p) %s"popst[p->n_op] );
646         switchp->n_op ) { /* special cases */
ragge
1.1
647
648         case REG:
ragge
1.13
649                 printf" %s"rnames[p->n_rval] );
ragge
1.1
650                 break;
651
ragge
1.23
652         case TEMP:
653                 printf(" %d", (int)p->n_lval);
654                 break;
655
ragge
1.1
656         case ICON:
657         case NAME:
658         case OREG:
659                 printf" " );
660                 adrputp );
661                 break;
662
663         case STCALL:
664         case UNARY STCALL:
665         case STARG:
666         case STASG:
ragge
1.13
667                 printf" size=%d"p->n_stsize );
668                 printf" align=%d"p->n_stalign );
ragge
1.1
669                 break;
670                 }
671
672         printf", " );
ragge
1.33
673         tprintp->n_typep->n_qual);
ragge
1.1
674         printf", " );
ragge
1.13
675         ifp->n_rall == NOPREF ) printf"NOPREF" );
ragge
1.1
676         else {
ragge
1.13
677                 ifp->n_rall & MUSTDO ) printf"MUSTDO " );
ragge
1.1
678                 else printf"PREF " );
ragge
1.13
679                 printf"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
680                 }
ragge
1.13
681         printf", SU= %d\n"p->n_su );
ragge
1.2
682         return 0;
683 }
ragge
1.30
684 #endif
ragge
1.1
685
686 #ifndef FIELDOPS
ragge
1.7
687 /*
688  * do this if there is no special hardware support for fields
689  */
690 static int
691 ffld(NODE *pint downint *down1int *down2 )
692 {
693         /*
694          * look for fields that are not in an lvalue context,
695          * and rewrite them...
696          */
697         NODE *shp;
698         int sovty;
ragge
1.1
699
ragge
1.13
700         *down1 =  asgopp->n_op );
ragge
1.1
701         *down2 = 0;
702
ragge
1.13
703         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
704
ragge
1.7
705                 if( !rewfld(p) ) return 0;
ragge
1.1
706
ragge
1.13
707                 ty = (szty(p->n_type) == 2)? LONGINT;
708                 v = p->n_rval;
ragge
1.1
709                 s = UPKFSZ(v);
710 # ifdef RTOLBYTES
711                 o = UPKFOFF(v);  /* amount to shift */
712 # else
ragge
1.13
713                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
714 #endif
715
716                 /* make & mask part */
717
ragge
1.13
718                 p->n_left->n_type = ty;
ragge
1.1
719
ragge
1.13
720                 p->n_op = AND;
721                 p->n_right = talloc();
722                 p->n_right->n_op = ICON;
723                 p->n_right->n_rall = NOPREF;
724                 p->n_right->n_type = ty;
725                 p->n_right->n_lval = 1;
726                 p->n_right->n_rval = 0;
727                 p->n_right->n_name = "";
728                 p->n_right->n_lval <<= s;
729                 p->n_right->n_lval--;
ragge
1.1
730
731                 /* now, if a shift is needed, do it */
732
733                 ifo != 0 ){
734                         shp = talloc();
ragge
1.13
735                         shp->n_op = RS;
736                         shp->n_rall = NOPREF;
737                         shp->n_type = ty;
738                         shp->n_left = p->n_left;
739                         shp->n_right = talloc();
740                         shp->n_right->n_op = ICON;
741                         shp->n_right->n_rall = NOPREF;
742                         shp->n_right->n_type = ty;
743                         shp->n_right->n_rval = 0;
744                         shp->n_right->n_lval = o;  /* amount to shift */
745                         shp->n_right->n_name = "";
746                         p->n_left = shp;
ragge
1.1
747                         /* whew! */
748                 }
749         }
ragge
1.7
750         return 0;
751 }
ragge
1.1
752 #endif
753
ragge
1.23
754 /*
755  * change left TEMPs into OREGs
ragge
1.40
756  */
757 void
758 deltemp(NODE *p)
759 {
760         struct templst *w = templst;
761
762         if (p->n_op != TEMP)
763                 return;
764         /*
765          * the size of a TEMP is in multiples of the reg size.
766          */
767         p->n_op = OREG;
768         p->n_rval = FPREG;
769         while (w != NULL) {
770                 if (w->tempnr == p->n_lval)
771                         break;
772                 w = w->next;
773         }
774         if (w == NULL) {
775                 w = tmpalloc(sizeof(struct templst));
776                 w->tempnr = p->n_lval;
777                 w->tempoff = BITOOR(freetemp(szty(p->n_type)));
778                 w->next = templst;
779                 templst = w;
780         }
781         p->n_lval = w->tempoff;
782         p->n_name = "";
783 }
784
785 /*
ragge
1.23
786  * look for situations where we can turn * into OREG
787  */
ragge
1.2
788 void
789 oreg2(NODE *p)
790 {
ragge
1.1
791
792         NODE *q;
ragge
1.2
793         int r;
794         char *cp;
795         NODE *ql, *qr;
ragge
1.1
796         CONSZ temp;
ragge
1.23
797
ragge
1.40
798         deltemp(p);
ragge
1.1
799
ragge
1.13
800         if (p->n_op == UNARY MUL) {
801                 q = p->n_left;
802                 if (q->n_op == REG) {
803                         temp = q->n_lval;
804                         r = q->n_rval;
805                         cp = q->n_name;
ragge
1.1
806                         goto ormake;
ragge
1.12
807                 }
ragge
1.1
808
ragge
1.13
809                 if (q->n_op != PLUS && q->n_op != MINUS)
ragge
1.12
810                         return;
ragge
1.13
811                 ql = q->n_left;
812                 qr = q->n_right;
ragge
1.1
813
814 #ifdef R2REGS
815
816                 /* look for doubly indexed expressions */
817
ragge
1.13
818                 ifq->n_op == PLUS) {
ragge
1.7
819                         int i;
ragge
1.1
820                         if( (r=base(ql))>=0 && (i=offset(qrtlen(p)))>=0) {
821                                 makeor2(pqlri);
822                                 return;
ragge
1.12
823                         } else if((r=base(qr))>=0 && (i=offset(qltlen(p)))>=0) {
ragge
1.1
824                                 makeor2(pqrri);
825                                 return;
826                         }
ragge
1.12
827                 }
ragge
1.1
828
829
830 #endif
831
ragge
1.13
832                 if( (q->n_op==PLUS || q->n_op==MINUS) && qr->n_op == ICON &&
833                                 ql->n_op==REG && szty(qr->n_type)==1) {
834                         temp = qr->n_lval;
835                         ifq->n_op == MINUS ) temp = -temp;
836                         r = ql->n_rval;
837                         temp += ql->n_lval;
838                         cp = qr->n_name;
839                         if( *cp && ( q->n_op == MINUS || *ql->n_name ) ) return;
840                         if( !*cp ) cp = ql->n_name;
ragge
1.1
841
842                         ormake:
ragge
1.13
843                         ifnotoffp->n_typertempcp ) ) return;
844                         p->n_op = OREG;
845                         p->n_rval = r;
846                         p->n_lval = temp;
847                         p->n_name = cp;
ragge
1.1
848                         tfree(q);
849                         return;
850                 }
851         }
ragge
1.12
852 }
ragge
1.1
853
ragge
1.2
854 void
ragge
1.1
855 canon(pNODE *p; {
856         /* put p in canonical form */
857
858 #ifndef FIELDOPS
859         fwalkpffld0 ); /* look for field operators */
860 # endif
861         walkfporeg2 );  /* look for and create OREG nodes */
862 #ifdef MYCANON
863         MYCANON(p);  /* your own canonicalization routine(s) */
864 #endif
865         walkfpsucomp );  /* do the Sethi-Ullman computation */
866
ragge
1.2
867 }
ragge
1.1
868
ragge
1.37
869 static SIMPLEQ_HEAD(, interpassipole = SIMPLEQ_HEAD_INITIALIZER(ipole);
870
871 void
872 saveip(struct interpass *ip)
873 {
ragge
1.40
874         struct interpass *prol;
875
ragge
1.37
876         SIMPLEQ_INSERT_TAIL(&ipoleipsqelem);
877
878         if (ip->type != IP_EPILOG)
879                 return;
880         saving = -1;
881
ragge
1.40
882         cvtemps(ip);    /* Convert TEMPs to OREGs */
883         deljumps();     /* Delete redundant jumps and dead code */
884
885         prol = SIMPLEQ_FIRST(&ipole);
886         prol->ip_auto = ip->ip_auto;
887         prol->ip_regs = ip->ip_regs;
888
889 #ifdef MYOPTIM
890         myoptim(prol);
891 #endif
ragge
1.37
892
893         while ((ip = SIMPLEQ_FIRST(&ipole))) {
894                 SIMPLEQ_REMOVE_HEAD(&ipolesqelem);
895                 pass2_compile(ip);
896         }
ragge
1.40
897 }
898
899 /*
900  * Convert TEMPs to OREGs.
901  * XXX - ugly.
902  */
903 void
904 cvtemps(struct interpass *epil)
905 {
906         struct interpass *ip;
907
908         autooff = maxautooff;
909         SIMPLEQ_FOREACH(ip, &ipolesqelem) {
910                 if (ip->type != IP_NODE)
911                         continue;
912                 walkf(ip->ip_nodedeltemp);
913         }
914         epil->ip_auto = maxautooff;
ragge
1.37
915 }
916
917 void
918 deljumps()
919 {
920         struct interpass *ip, *n;
921         int gotone;
922
923 again:  gotone = 0;
924
925         SIMPLEQ_FOREACH(ip, &ipolesqelem) {
926                 if (ip->type == IP_EPILOG)
927                         return;
928                 if (ip->type != IP_NODE)
929                         continue;
930                 if (ip->ip_node->n_op != GOTO)
931                         continue;
932                 n = ip->sqelem.sqe_next;
933                 switch (n->type) {
934                 case IP_NODE:
935                         tfree(n->ip_node);
936                         ip->sqelem.sqe_next = n->sqelem.sqe_next;
937                         break;
938                 case IP_DEFLAB:
939                         if (ip->ip_node->n_left->n_lval != n->ip_lbl)
940                                 continue;
941                         tfree(ip->ip_node);
942                         *ip = *n;
943                         break;
944                 default:
945                         continue;
946                 }
947                 gotone = 1;
948         }
949         if (gotone)
950                 goto again;
951 }
952
953 void
954 optdump(struct interpass *ip)
955 {
956         static char *nm[] = { "node""prolog""newblk""epilog""locctr",
ragge
1.41
957                 "deflab""defnam""asm" };
ragge
1.37
958         printf("type %s\n"nm[ip->type-1]);
959         switch (ip->type) {
960         case IP_NODE:
961                 fwalk(ip->ip_nodee2print0);
962                 break;
963         case IP_DEFLAB:
ragge
1.41
964                 printf("label " LABFMT "\n"ip->ip_lbl);