Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030821173333

Diff

Diff from 1.46 to:

Annotations

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

Annotated File View

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