Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030909122053

Diff

Diff from 1.62 to:

Annotations

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

Annotated File View

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