Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030730132556

Diff

Diff from 1.31 to:

Annotations

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

Annotated File View

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