Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030823122546

Diff

Diff from 1.47 to:

Annotations

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

Annotated File View

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