Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030901120803

Diff

Diff from 1.50 to:

Annotations

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

Annotated File View

ragge
1.50
1 /*      $Id: reader.c,v 1.50 2003/09/01 12:08:03 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"
ragge
1.49
37 #include "external.h"
ragge
1.1
38
39 /*      some storage declarations */
40 int nrecur;
41 int lflag;
ragge
1.9
42 int x2debug;
ragge
1.1
43 int udebug = 0;
ragge
1.32
44 int ftnno;
ragge
1.1
45
46 NODE *stotree;
47 int stocook;
ragge
1.37
48 static int saving;
ragge
1.1
49
ragge
1.23
50 static struct templst {
51         struct templst *next;
52         int tempnr;
53         int tempoff;
54 } *templst;
55
ragge
1.10
56 int e2print(NODE *pint downint *aint *b);
ragge
1.37
57 void saveip(struct interpass *ip);
58 void deljumps(void);
ragge
1.40
59 void deltemp(NODE *p);
ragge
1.37
60 void optdump(struct interpass *ip);
ragge
1.40
61 void cvtemps(struct interpass *epil);
ragge
1.49
62 static int findops(NODE *p);
ragge
1.37
63
ragge
1.46
64 #define DELAYS 20
65 NODE *deltrees[DELAYS];
66 int deli;
ragge
1.26
67
68 #ifdef PCC_DEBUG
69 static void
70 cktree(NODE *p)
71 {
72         if (p->n_op > MAXOP)
73                 cerror("op %d slipped through"p->n_op);
ragge
1.35
74         if (p->n_op == CBRANCH && !logop(p->n_left->n_op))
75                 cerror("not logop branch");
ragge
1.47
76         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
77                 cerror("asgop %d slipped through"p->n_op);
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
305         cookie = cook;
306         rcount();
307         canon(p);
ragge
1.13
308         rallo(pp->n_rall);
ragge
1.1
309
ragge
1.30
310 #ifdef PCC_DEBUG
ragge
1.8
311         if (odebug) {
312                 printf("order(%p, "p);
313                 prcook(cookie);
314                 printf(")\n");
315                 fwalk(pe2print0);
316         }
ragge
1.30
317 #endif
ragge
1.1
318
ragge
1.13
319         o = p->n_op;
ragge
1.1
320         ty = optype(o);
321
322         /* first of all, for most ops, see if it is in the table */
323
324         /* look for ops */
325
ragge
1.13
326         switch (m = p->n_op) {
ragge
1.1
327
ragge
1.48
328         case PLUS:
ragge
1.50
329         case MINUS:
ragge
1.49
330                 {
331                         struct optab *q;
332                         int rv;
ragge
1.48
333
ragge
1.49
334                         /*
335                          * Be sure that both sides are addressable.
336                          */
ragge
1.50
337 //printf("newstyle node %p\n", p);
ragge
1.49
338                         if (!canaddr(p->n_left))
339                                 order(p->n_leftINTAREG|INTBREG);
ragge
1.50
340 //printf("newstyle addrl %p\n", p);
ragge
1.49
341                         if (!canaddr(p->n_right))
342                                 order(p->n_rightINTAREG|INTBREG);
ragge
1.50
343 //printf("newstyle addrr %p\n", p);
ragge
1.48
344
ragge
1.49
345                         /*
346                          *
347                          */
348 #define LTMP    1
349 #define RTMP    2
350                         rv = findops(p);
ragge
1.50
351                         if (rv < 0) {
352                                 if (setnbin(p))
353                                         goto again;
ragge
1.49
354                                 goto nomat;
ragge
1.50
355                         }
ragge
1.49
356                         if (rv & LTMP)
357                                 order(p->n_leftINTAREG|INTBREG);
ragge
1.50
358 //printf("newstyle ltmp %p\n", p);
ragge
1.49
359                         if (rv & RTMP)
360                                 order(p->n_rightINTAREG|INTBREG);
ragge
1.50
361 //printf("newstyle rtmp %p\n", p);
ragge
1.49
362                 
363
364                         q = &table[rv >> 2];
365                         if (!allo(pq))
366                                 cerror("allo failed");
367                         expand(pINTAREG|INTBREGq->cstring);
368                         reclaim(pq->rewriteINTAREG|INTBREG);
ragge
1.50
369 //printf("newstyle ute %p\n", p);
ragge
1.48
370                 }
ragge
1.49
371                 goto cleanup;
372
ragge
1.1
373         default:
ragge
1.47
374 #ifdef notyet
375                 if ((cookie & (INTAREG|INTBREG)) && optype(m) == LTYPE) {
376                         /*
377                          * Search for an ASSIGN op instead of OPLTYPE.
378                          */
379                 }
380 #endif
ragge
1.1
381                 /* look for op in table */
ragge
1.8
382                 for (;;) {
383                         if ((m = match(pcookie)) == MDONE)
384                                 goto cleanup;
385                         else if (m == MNOPE) {
386                                 if (!(cookie = nextcook(pcookie)))
387                                         goto nomat;
ragge
1.1
388                                 continue;
ragge
1.8
389                         } else
390                                 break;
391                 }
ragge
1.1
392                 break;
393
394         case FORCE:
395         case CBRANCH:
396         case UNARY CALL:
397         case CALL:
398         case UNARY STCALL:
399         case STCALL:
400         case UNARY FORTCALL:
401         case FORTCALL:
402                 /* don't even go near the table... */
403                 ;
404
ragge
1.8
405         }
ragge
1.25
406         /*
ragge
1.8
407          * get here to do rewriting if no match or
408          * fall through from above for hard ops
409          */
ragge
1.1
410
ragge
1.13
411         p1 = p->n_left;
ragge
1.8
412         if (ty == BITYPE)
ragge
1.13
413                 p2 = p->n_right;
ragge
1.8
414         else
415                 p2 = NIL;
ragge
1.1
416         
ragge
1.30
417 #ifdef PCC_DEBUG
ragge
1.8
418         if (odebug) {
419                 printf("order(%p, "p);
420                 prcook(cook);
421                 printf("), cookie ");
422                 prcook(cookie);
423                 printf(", rewrite %s\n"opst[m]);
424         }
ragge
1.30
425 #endif
ragge
1.8
426         switch (m) {
ragge
1.1
427         default:
428                 nomat:
ragge
1.13
429                 cerror"no table entry for op %s"opst[p->n_op] );
ragge
1.1
430
431         case FORCE:
432                 cook = INTAREG|INTBREG;
ragge
1.19
433                 order(p->n_leftcook);
434                 reclaim(pRLEFTcook);
ragge
1.38
435                 return;
ragge
1.1
436
437         case CBRANCH:
ragge
1.36
438                 p1->n_label = p2->n_lval;
ragge
1.42
439                 o = p1->n_op;
ragge
1.36
440                 codgen(p1FORCC);
ragge
1.42
441                 cbgen(op2->n_lval);
ragge
1.36
442                 reclaim(p1RNULL0);
ragge
1.19
443                 nfree(p2);
444                 nfree(p);
ragge
1.1
445                 return;
446
447         case FLD:       /* fields of funny type */
ragge
1.13
448                 if ( p1->n_op == UNARY MUL ){
449                         offstarp1->n_left );
ragge
1.1
450                         goto again;
451                         }
452
453         case UNARY MINUS:
ragge
1.30
454                 orderp1INBREG|INAREG);
ragge
1.1
455                 goto again;
456
457         case NAME:
458                 /* all leaves end up here ... */
459                 ifo == REG ) goto nomat;
460                 orderpINTAREG|INTBREG );
461                 goto again;
462
463         case INIT:
ragge
1.12
464                 uerror("init: illegal initialization");
ragge
1.1
465                 return;
466
467         case UNARY FORTCALL:
ragge
1.13
468                 p->n_right = NIL;
ragge
1.1
469         case FORTCALL:
ragge
1.13
470                 o = p->n_op = UNARY FORTCALL;
ragge
1.1
471                 ifgenfcallpcookie ) ) goto nomat;
472                 goto cleanup;
473
474         case UNARY CALL:
ragge
1.13
475                 p->n_right = NIL;
ragge
1.1
476         case CALL:
ragge
1.13
477                 o = p->n_op = UNARY CALL;
ragge
1.1
478                 ifgencallpcookie ) ) goto nomat;
479                 goto cleanup;
480
481         case UNARY STCALL:
ragge
1.13
482                 p->n_right = NIL;
ragge
1.1
483         case STCALL:
ragge
1.13
484                 o = p->n_op = UNARY STCALL;
ragge
1.1
485                 ifgenscallpcookie ) ) goto nomat;
486                 goto cleanup;
487
488                 /* if arguments are passed in register, care must be taken that reclaim
ragge
1.2
489                  * not throw away the register which now has the result... */
ragge
1.1
490
491         case UNARY MUL:
492                 ifcook == FOREFF ){
493                         /* do nothing */
ragge
1.13
494                         orderp->n_leftFOREFF );
ragge
1.19
495                         nfree(p);
ragge
1.1
496                         return;
ragge
1.19
497                 }
ragge
1.30
498                 offstarp->n_left );
499 #if 0
500                 canon(p);
501                 ifcanaddr(p) && cook != INTEMP )
502                         goto cleanup;
ragge
1.1
503 #endif
504                 goto again;
505
506         case INCR:  /* INCR and DECR */
507                 ifsetincr(p) ) goto again;
508
ragge
1.49
509                 /* x++ becomes (x = x + 1) -1; */
ragge
1.1
510
511                 p1 = tcopy(p);
ragge
1.49
512                 if (cook & FOREFF) {
513                         nfree(p->n_right);
514                         p->n_right = p1;
ragge
1.50
515                         p1->n_op = (p->n_op == INCR) ? PLUSMINUS;
ragge
1.49
516                         p->n_op = ASSIGN;
517                 } else {
518                         p2 = talloc();
519                         p2->n_rall = NOPREF;
520                         p2->n_name = "";
521                         p2->n_op = ASSIGN;
522                         p2->n_type = p->n_type;
523                         p2->n_left = p->n_left;
524                         p2->n_right = p1;
525                         p1->n_op = (p->n_op == INCR) ? PLUSMINUS;
526                         p->n_op = (p->n_op == INCR) ? MINUS : PLUS;
ragge
1.50
527                         p->n_left = p2;
ragge
1.49
528                 }
ragge
1.1
529                 goto again;
530
531         case STASG:
532                 ifsetstrp ) ) goto again;
533                 goto nomat;
534
535         case ASG PLUS:  /* and other assignment ops */
536                 ifsetasop(p) ) goto again;
537
538                 /* there are assumed to be no side effects in LHS */
539
540                 p2 = tcopy(p);
ragge
1.13
541                 p->n_op = ASSIGN;
542                 reclaimp->n_rightRNULL0 );
543                 p->n_right = p2;
ragge
1.1
544                 canon(p);
ragge
1.13
545                 rallopp->n_rall );
ragge
1.1
546
ragge
1.30
547 #ifdef PCC_DEBUG
ragge
1.8
548                 ifodebug ) fwalkpe2print0 );
ragge
1.30
549 #endif
ragge
1.1
550
ragge
1.13
551                 orderp2->n_leftINTBREG|INTAREG );
ragge
1.1
552                 orderp2INTBREG|INTAREG );
553                 goto again;
554
555         case ASSIGN:
ragge
1.8
556                 if (setasg(p))
557                         goto again;
ragge
1.1
558                 goto nomat;
559
560
561         case BITYPE:
562                 ifsetbinp ) ) goto again;
563                 /* try to replace binary ops by =ops */
564                 switch(o){
ragge
1.50
565 #if 0
ragge
1.1
566                 case PLUS:
567                 case MINUS:
ragge
1.50
568 #endif
ragge
1.1
569                 case MUL:
570                 case DIV:
571                 case MOD:
572                 case AND:
573                 case OR:
574                 case ER:
575                 case LS:
576                 case RS:
ragge
1.43
577                         if (!istnode(p->n_left))
578                                 order(p->n_leftINTAREG|INTBREG);
ragge
1.13
579                         p->n_op = ASG o;
ragge
1.1
580                         goto again;
581                         }
582                 goto nomat;
583
584                 }
585
586         cleanup:
587
588         /* if it is not yet in the right state, put it there */
589
590         ifcook & FOREFF ){
591                 reclaimpRNULL0 );
592                 return;
593                 }
594
ragge
1.13
595         ifp->n_op==FREE ) return;
ragge
1.1
596
597         iftshapepcook ) ) return;
598
599         if( (m=match(p,cook) ) == MDONE ) return;
600
601         /* we are in bad shape, try one last chance */
ragge
1.8
602         if (lastchance(pcook))
603                 goto again;
ragge
1.1
604
605         goto nomat;
ragge
1.8
606 }
ragge
1.1
607
608 int callflag;
609 int fregs;
610
ragge
1.2
611 void
612 storep ) NODE *p; {
ragge
1.1
613
614         /* find a subtree of p which should be stored */
615
ragge
1.2
616         int oty;
ragge
1.1
617
ragge
1.13
618         o = p->n_op;
ragge
1.1
619         ty = optype(o);
620
621         ifty == LTYPE ) return;
622
623         switcho ){
624
625         case UNARY CALL:
626         case UNARY FORTCALL:
627         case UNARY STCALL:
628                 ++callflag;
629                 break;
630
631         case UNARY MUL:
ragge
1.13
632                 if (asgop(p->n_left->n_op))
633                         stoasg(p->n_leftUNARY MUL);
ragge
1.1
634                 break;
635
636         case CALL:
637         case FORTCALL:
638         case STCALL:
ragge
1.13
639                 storep->n_left );
640                 stoargp->n_righto );
ragge
1.1
641                 ++callflag;
642                 return;
643
644         case CBRANCH:   /* to prevent complicated expressions on the LHS from being stored */
ragge
1.13
645                 constorep->n_left );
ragge
1.1
646                 return;
647
648                 }
649
ragge
1.11
650         if (ty == UTYPE) {
ragge
1.13
651                 store(p->n_left);
ragge
1.1
652                 return;
ragge
1.11
653         }
ragge
1.1
654
ragge
1.13
655         if (asgop(p->n_right->n_op))
656                 stoasg(p->n_righto);
ragge
1.1
657
ragge
1.13
658         ifp->n_su>fregs ){ /* must store */
ragge
1.1
659                 mkadrsp );  /* set up stotree and stocook to subtree
660                                  that must be stored */
661                 }
662
ragge
1.13
663         storep->n_right );
664         storep->n_left );
ragge
1.1
665         }
666
ragge
1.2
667 /*
668  * store conditional expressions
669  * the point is, avoid storing expressions in conditional
670  * conditional context, since the evaluation order is predetermined
671  */
672 void
673 constore(NODE *p)
674 {
ragge
1.1
675         storep );
ragge
1.2
676 }
ragge
1.1
677
ragge
1.2
678 /* mark off calls below the current node */
679 void
680 markcall(NODE *p)
681 {
ragge
1.1
682
683         again:
ragge
1.13
684         switchp->n_op ){
ragge
1.1
685
686         case UNARY CALL:
687         case UNARY STCALL:
688         case UNARY FORTCALL:
689         case CALL:
690         case STCALL:
691         case FORTCALL:
692                 ++callflag;
693                 return;
694
695                 }
696
ragge
1.13
697         switchoptypep->n_op ) ){
ragge
1.1
698
699         case BITYPE:
ragge
1.13
700                 markcallp->n_right );
ragge
1.1
701         case UTYPE:
ragge
1.13
702                 p = p->n_left;
ragge
1.1
703                 /* eliminate recursion (aren't I clever...) */
704                 goto again;
705         case LTYPE:
706                 return;
707                 }
708
ragge
1.2
709 }
ragge
1.1
710
ragge
1.2
711 void
712 stoarg(NODE *pint calltype)
713 {
ragge
1.1
714         /* arrange to store the args */
ragge
1.13
715         ifp->n_op == CM ){
716                 stoargp->n_leftcalltype );
717                 p = p->n_right ;
ragge
1.1
718                 }
719         ifcalltype == CALL ){
720                 STOARG(p);
721                 }
722         else ifcalltype == STCALL ){
723                 STOSTARG(p);
724                 }
725         else {
726                 STOFARG(p);
727                 }
728         callflag = 0;
729         store(p);
ragge
1.30
730 #ifdef NO_NESTCALLS
ragge
1.1
731         ifcallflag ){ /* prevent two calls from being active at once  */
732                 SETSTO(p,INTEMP);
733                 store(p); /* do again to preserve bottom up nature....  */
ragge
1.2
734         }
ragge
1.1
735 #endif
ragge
1.2
736 }
ragge
1.1
737
738 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
739
ragge
1.2
740 void
741 rcount()
742 /* count recursions */
ragge
1.1
743         if( ++nrecur > NRECUR ){
744                 cerror"expression causes compiler loop: try simplifying" );
745         }
ragge
1.2
746 }
ragge
1.1
747
ragge
1.30
748 #ifdef PCC_DEBUG
ragge
1.2
749 int
ragge
1.8
750 e2print(NODE *pint downint *aint *b)
ragge
1.2
751 {
ragge
1.1
752
753         *a = *b = down+1;
754         whiledown >= 2 ){
755                 printf"\t" );
756                 down -= 2;
757                 }
758         ifdown-- ) printf"    " );
759
760
ragge
1.13
761         printf"%p) %s"popst[p->n_op] );
762         switchp->n_op ) { /* special cases */
ragge
1.1
763
764         case REG:
ragge
1.13
765                 printf" %s"rnames[p->n_rval] );
ragge
1.1
766                 break;
767
ragge
1.23
768         case TEMP:
769                 printf(" %d", (int)p->n_lval);
770                 break;
771
ragge
1.1
772         case ICON:
773         case NAME:
774         case OREG:
775                 printf" " );
776                 adrputp );
777                 break;
778
779         case STCALL:
780         case UNARY STCALL:
781         case STARG:
782         case STASG:
ragge
1.13
783                 printf" size=%d"p->n_stsize );
784                 printf" align=%d"p->n_stalign );
ragge
1.1
785                 break;
786                 }
787
788         printf", " );
ragge
1.33
789         tprintp->n_typep->n_qual);
ragge
1.1
790         printf", " );
ragge
1.13
791         ifp->n_rall == NOPREF ) printf"NOPREF" );
ragge
1.1
792         else {
ragge
1.13
793                 ifp->n_rall & MUSTDO ) printf"MUSTDO " );
ragge
1.1
794                 else printf"PREF " );
ragge
1.13
795                 printf"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
796                 }
ragge
1.13
797         printf", SU= %d\n"p->n_su );
ragge
1.2
798         return 0;
799 }
ragge
1.30
800 #endif
ragge
1.1
801
802 #ifndef FIELDOPS
ragge
1.7
803 /*
804  * do this if there is no special hardware support for fields
805  */
806 static int
807 ffld(NODE *pint downint *down1int *down2 )
808 {
809         /*
810          * look for fields that are not in an lvalue context,
811          * and rewrite them...
812          */
813         NODE *shp;
814         int sovty;
ragge
1.1
815
ragge
1.13
816         *down1 =  asgopp->n_op );
ragge
1.1
817         *down2 = 0;
818
ragge
1.13
819         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
820
ragge
1.7
821                 if( !rewfld(p) ) return 0;
ragge
1.1
822
ragge
1.48
823                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
824                 v = p->n_rval;
ragge
1.1
825                 s = UPKFSZ(v);
826 # ifdef RTOLBYTES
827                 o = UPKFOFF(v);  /* amount to shift */
828 # else
ragge
1.13
829                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
830 #endif
831
832                 /* make & mask part */
833
ragge
1.13
834                 p->n_left->n_type = ty;
ragge
1.1
835
ragge
1.13
836                 p->n_op = AND;
837                 p->n_right = talloc();
838                 p->n_right->n_op = ICON;
839                 p->n_right->n_rall = NOPREF;
840                 p->n_right->n_type = ty;
841                 p->n_right->n_lval = 1;
842                 p->n_right->n_rval = 0;
843                 p->n_right->n_name = "";
844                 p->n_right->n_lval <<= s;
845                 p->n_right->n_lval--;
ragge
1.1
846
847                 /* now, if a shift is needed, do it */
848
849                 ifo != 0 ){
850                         shp = talloc();
ragge
1.13
851                         shp->n_op = RS;
852                         shp->n_rall = NOPREF;
853                         shp->n_type = ty;
854                         shp->n_left = p->n_left;
855                         shp->n_right = talloc();
856                         shp->n_right->n_op = ICON;
857                         shp->n_right->n_rall = NOPREF;
858                         shp->n_right->n_type = ty;
859                         shp->n_right->n_rval = 0;
860                         shp->n_right->n_lval = o;  /* amount to shift */
861                         shp->n_right->n_name = "";
862                         p->n_left = shp;
ragge
1.1
863                         /* whew! */
864                 }
865         }
ragge
1.7
866         return 0;
867 }
ragge
1.1
868 #endif
869
ragge
1.23
870 /*
871  * change left TEMPs into OREGs
ragge
1.40
872  */
873 void
874 deltemp(NODE *p)
875 {
876         struct templst *w = templst;
877
878         if (p->n_op != TEMP)
879                 return;
880         /*
881          * the size of a TEMP is in multiples of the reg size.
882          */
883         p->n_op = OREG;
884         p->n_rval = FPREG;
885         while (w != NULL) {
886                 if (w->tempnr == p->n_lval)
887                         break;
888                 w = w->next;
889         }
890         if (w == NULL) {
891                 w = tmpalloc(sizeof(struct templst));
892                 w->tempnr = p->n_lval;
893                 w->tempoff = BITOOR(freetemp(szty(p->n_type)));
894                 w->next = templst;
895                 templst = w;
896         }
897         p->n_lval = w->tempoff;
898         p->n_name = "";
899 }
900
901 /*
ragge
1.48
902  * for pointer/integer arithmetic, set pointer at left node
903  */
904 static void
905 setleft(NODE *p)          
906 {        
907         NODE *q;
908
909         /* only additions for now */
910         if (p->n_op != PLUS)
911                 return;
912         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
913                 q = p->n_right;
914                 p->n_right = p->n_left;
915                 p->n_left = q;
916         }
917 }
918
919 /*
ragge
1.23
920  * look for situations where we can turn * into OREG
921  */
ragge
1.2
922 void
923 oreg2(NODE *p)
924 {
ragge
1.1
925
926         NODE *q;
ragge
1.2
927         int r;
928         char *cp;
929         NODE *ql, *qr;
ragge
1.1
930         CONSZ temp;
ragge
1.23
931
ragge
1.44
932         if (Oflag == 0)
933                 deltemp(p);
ragge
1.1
934
ragge
1.13
935         if (p->n_op == UNARY MUL) {
936                 q = p->n_left;
937                 if (q->n_op == REG) {
938                         temp = q->n_lval;
939                         r = q->n_rval;
940                         cp = q->n_name;
ragge
1.1
941                         goto ormake;
ragge
1.12
942                 }
ragge
1.1
943
ragge
1.13
944                 if (q->n_op != PLUS && q->n_op != MINUS)
ragge
1.12
945                         return;
ragge
1.13