Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030908082733

Diff

Diff from 1.57 to:

Annotations

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

Annotated File View

ragge
1.57
1 /*      $Id: reader.c,v 1.57 2003/09/08 08:27:33 ragge Exp $    */
ragge
1.31
2 /*
3  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * Redistributions of source code and documentation must retain the above
10  * copyright notice, this list of conditions and the following disclaimer.
11  * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditionsand the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * All advertising materials mentioning features or use of this software
15  * must display the following acknowledgement:
16  *      This product includes software developed or owned by Caldera
17  *      International, Inc.
18  * Neither the name of Caldera International, Inc. nor the names of other
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
23  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
27  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
ragge
1.1
35
36 # include "pass2.h"
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;
144                                 p->n_right->n_op = FREE;  /* zap constant */
145                                 *p = *q;
146                                 q->n_op = FREE;
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.57
296         int otymrv;
ragge
1.1
297         int cookie;
ragge
1.2
298         NODE *p1, *p2;
ragge
1.1
299
ragge
1.8
300         /*
301          * by this time, p should be able to be generated without stores;
302          * the only question is how
303          */
ragge
1.1
304         again:
305
306         cookie = cook;
307         rcount();
308         canon(p);
ragge
1.13
309         rallo(pp->n_rall);
ragge
1.1
310
ragge
1.30
311 #ifdef PCC_DEBUG
ragge
1.8
312         if (odebug) {
313                 printf("order(%p, "p);
314                 prcook(cookie);
315                 printf(")\n");
316                 fwalk(pe2print0);
317         }
ragge
1.30
318 #endif
ragge
1.1
319
ragge
1.13
320         o = p->n_op;
ragge
1.1
321         ty = optype(o);
322
323         /* first of all, for most ops, see if it is in the table */
324
325         /* look for ops */
326
ragge
1.13
327         switch (m = p->n_op) {
ragge
1.1
328
ragge
1.48
329         case PLUS:
ragge
1.50
330         case MINUS:
ragge
1.51
331         case AND:
332         case OR:
333         case ER:
ragge
1.52
334         case DIV:
ragge
1.53
335         case MOD:
336         case MUL:
ragge
1.55
337         case LS:
338         case RS:
ragge
1.49
339                 {
340                         struct optab *q;
ragge
1.48
341
ragge
1.49
342                         /*
343                          * Be sure that both sides are addressable.
344                          */
ragge
1.50
345 //printf("newstyle node %p\n", p);
ragge
1.53
346                         if (!canaddr(p->n_left)) {
347                                 if (p->n_left->n_op == UNARY MUL) {
348                                         offstar(p->n_left->n_left);
349                                         goto again;
350                                 }
ragge
1.49
351                                 order(p->n_leftINTAREG|INTBREG);
ragge
1.53
352                         }
ragge
1.50
353 //printf("newstyle addrl %p\n", p);
ragge
1.53
354                         if (!canaddr(p->n_right)) {
355                                 if (p->n_right->n_op == UNARY MUL) {
356                                         offstar(p->n_right->n_left);
357                                         goto again;
358                                 }
ragge
1.49
359                                 order(p->n_rightINTAREG|INTBREG);
ragge
1.53
360                         }
ragge
1.50
361 //printf("newstyle addrr %p\n", p);
ragge
1.48
362
ragge
1.49
363                         /*
364                          *
365                          */
366 #define LTMP    1
367 #define RTMP    2
ragge
1.57
368                         m = INTAREG|INTBREG;
ragge
1.49
369                         rv = findops(p);
ragge
1.57
370 foo:                    if (rv < 0) {
ragge
1.50
371                                 if (setnbin(p))
372                                         goto again;
ragge
1.49
373                                 goto nomat;
ragge
1.50
374                         }
ragge
1.49
375                         if (rv & LTMP)
376                                 order(p->n_leftINTAREG|INTBREG);
ragge
1.50
377 //printf("newstyle ltmp %p\n", p);
ragge
1.49
378                         if (rv & RTMP)
379                                 order(p->n_rightINTAREG|INTBREG);
ragge
1.50
380 //printf("newstyle rtmp %p\n", p);
ragge
1.49
381                 
382
383                         q = &table[rv >> 2];
ragge
1.54
384                         if (!allo(pq)) {
385                                 /*
386                                  * Ran out of suitable temp regs.
387                                  * Force everything onto stack.
388                                  * Be careful to avoid loops.
389                                  * XXX - this is bad code!
390                                  */
391                                 if ((rv & LTMP) == 0 && istnode(p->n_left)) {
392                                         order(p->n_leftINTEMP);
393                                         goto again;
394                                 } else if (!(rv & RTMP) &&istnode(p->n_right)) {
395                                         order(p->n_rightINTEMP);
396                                         goto again;
397                                 }
ragge
1.49
398                                 cerror("allo failed");
ragge
1.54
399                         }
ragge
1.57
400                         expand(pmq->cstring);
401                         reclaim(pq->rewritem);
ragge
1.50
402 //printf("newstyle ute %p\n", p);
ragge
1.48
403                 }
ragge
1.49
404                 goto cleanup;
405
ragge
1.57
406                 /*
407                  * For now just be sure that the trees on each side
408                  * are adressable.
409                  */
410         case EQ:
411         case NE:
412         case LE:
413         case LT:
414         case GE:
415         case GT:
416         case ULE:
417         case ULT:
418         case UGE:
419         case UGT:
420                 if (!canaddr(p->n_left)) {
421                         if (p->n_left->n_op == UNARY MUL) {
422                                 offstar(p->n_left->n_left);
423                                 goto again;
424                         }
425                         order(p->n_leftINTAREG|INTBREG);
426                 }
427                 if (!canaddr(p->n_right)) {
428                         if (p->n_right->n_op == UNARY MUL) {
429                                 offstar(p->n_right->n_left);
430                                 goto again;
431                         }
432                         order(p->n_rightINTAREG|INTBREG);
433                 }
434                 rv = relops(p);
435                 m = FORCC;
436                 goto foo;
437
ragge
1.1
438         default:
439                 /* look for op in table */
ragge
1.8
440                 for (;;) {
441                         if ((m = match(pcookie)) == MDONE)
442                                 goto cleanup;
443                         else if (m == MNOPE) {
444                                 if (!(cookie = nextcook(pcookie)))
445                                         goto nomat;
ragge
1.1
446                                 continue;
ragge
1.8
447                         } else
448                                 break;
449                 }
ragge
1.1
450                 break;
451
452         case FORCE:
453         case CBRANCH:
454         case UNARY CALL:
455         case CALL:
456         case UNARY STCALL:
457         case STCALL:
458         case UNARY FORTCALL:
459         case FORTCALL:
460                 /* don't even go near the table... */
461                 ;
462
ragge
1.8
463         }
ragge
1.25
464         /*
ragge
1.8
465          * get here to do rewriting if no match or
466          * fall through from above for hard ops
467          */
ragge
1.1
468
ragge
1.13
469         p1 = p->n_left;
ragge
1.8
470         if (ty == BITYPE)
ragge
1.13
471                 p2 = p->n_right;
ragge
1.8
472         else
473                 p2 = NIL;
ragge
1.1
474         
ragge
1.30
475 #ifdef PCC_DEBUG
ragge
1.8
476         if (odebug) {
477                 printf("order(%p, "p);
478                 prcook(cook);
479                 printf("), cookie ");
480                 prcook(cookie);
481                 printf(", rewrite %s\n"opst[m]);
482         }
ragge
1.30
483 #endif
ragge
1.8
484         switch (m) {
ragge
1.1
485         default:
486                 nomat:
ragge
1.13
487                 cerror"no table entry for op %s"opst[p->n_op] );
ragge
1.1
488
489         case FORCE:
490                 cook = INTAREG|INTBREG;
ragge
1.19
491                 order(p->n_leftcook);
492                 reclaim(pRLEFTcook);
ragge
1.38
493                 return;
ragge
1.1
494
495         case CBRANCH:
ragge
1.36
496                 p1->n_label = p2->n_lval;
ragge
1.42
497                 o = p1->n_op;
ragge
1.36
498                 codgen(p1FORCC);
ragge
1.42
499                 cbgen(op2->n_lval);
ragge
1.36
500                 reclaim(p1RNULL0);
ragge
1.19
501                 nfree(p2);
502                 nfree(p);
ragge
1.1
503                 return;
504
505         case FLD:       /* fields of funny type */
ragge
1.13
506                 if ( p1->n_op == UNARY MUL ){
507                         offstarp1->n_left );
ragge
1.1
508                         goto again;
509                         }
510
511         case UNARY MINUS:
ragge
1.30
512                 orderp1INBREG|INAREG);
ragge
1.1
513                 goto again;
514
515         case NAME:
516                 /* all leaves end up here ... */
517                 ifo == REG ) goto nomat;
518                 orderpINTAREG|INTBREG );
519                 goto again;
520
521         case INIT:
ragge
1.12
522                 uerror("init: illegal initialization");
ragge
1.1
523                 return;
524
525         case UNARY FORTCALL:
ragge
1.13
526                 p->n_right = NIL;
ragge
1.1
527         case FORTCALL:
ragge
1.13
528                 o = p->n_op = UNARY FORTCALL;
ragge
1.1
529                 ifgenfcallpcookie ) ) goto nomat;
530                 goto cleanup;
531
532         case UNARY CALL:
ragge
1.13
533                 p->n_right = NIL;
ragge
1.1
534         case CALL:
ragge
1.13
535                 o = p->n_op = UNARY CALL;
ragge
1.1
536                 ifgencallpcookie ) ) goto nomat;
537                 goto cleanup;
538
539         case UNARY STCALL:
ragge
1.13
540                 p->n_right = NIL;
ragge
1.1
541         case STCALL:
ragge
1.13
542                 o = p->n_op = UNARY STCALL;
ragge
1.1
543                 ifgenscallpcookie ) ) goto nomat;
544                 goto cleanup;
545
546                 /* if arguments are passed in register, care must be taken that reclaim
ragge
1.2
547                  * not throw away the register which now has the result... */
ragge
1.1
548
549         case UNARY MUL:
550                 ifcook == FOREFF ){
551                         /* do nothing */
ragge
1.13
552                         orderp->n_leftFOREFF );
ragge
1.19
553                         nfree(p);
ragge
1.1
554                         return;
ragge
1.19
555                 }
ragge
1.30
556                 offstarp->n_left );
557 #if 0
558                 canon(p);
559                 ifcanaddr(p) && cook != INTEMP )
560                         goto cleanup;
ragge
1.1
561 #endif
562                 goto again;
563
564         case INCR:  /* INCR and DECR */
565                 ifsetincr(p) ) goto again;
566
ragge
1.49
567                 /* x++ becomes (x = x + 1) -1; */
ragge
1.1
568
569                 p1 = tcopy(p);
ragge
1.49
570                 if (cook & FOREFF) {
571                         nfree(p->n_right);
572                         p->n_right = p1;
ragge
1.50
573                         p1->n_op = (p->n_op == INCR) ? PLUSMINUS;
ragge
1.49
574                         p->n_op = ASSIGN;
575                 } else {
576                         p2 = talloc();
577                         p2->n_rall = NOPREF;
578                         p2->n_name = "";
579                         p2->n_op = ASSIGN;
580                         p2->n_type = p->n_type;
581                         p2->n_left = p->n_left;
582                         p2->n_right = p1;
583                         p1->n_op = (p->n_op == INCR) ? PLUSMINUS;
584                         p->n_op = (p->n_op == INCR) ? MINUS : PLUS;
ragge
1.50
585                         p->n_left = p2;
ragge
1.49
586                 }
ragge
1.1
587                 goto again;
588
589         case STASG:
590                 ifsetstrp ) ) goto again;
591                 goto nomat;
592
593         case ASSIGN:
ragge
1.8
594                 if (setasg(p))
595                         goto again;
ragge
1.1
596                 goto nomat;
597
598
599         case BITYPE:
600                 ifsetbinp ) ) goto again;
601                 goto nomat;
602
603                 }
604
605         cleanup:
606
607         /* if it is not yet in the right state, put it there */
608
609         ifcook & FOREFF ){
610                 reclaimpRNULL0 );
611                 return;
612                 }
613
ragge
1.13
614         ifp->n_op==FREE ) return;
ragge
1.1
615
616         iftshapepcook ) ) return;
617
618         if( (m=match(p,cook) ) == MDONE ) return;
619
620         /* we are in bad shape, try one last chance */
ragge
1.8
621         if (lastchance(pcook))
622                 goto again;
ragge
1.1
623
624         goto nomat;
ragge
1.8
625 }
ragge
1.1
626
627 int callflag;
628 int fregs;
629
ragge
1.2
630 void
631 storep ) NODE *p; {
ragge
1.1
632
633         /* find a subtree of p which should be stored */
634
ragge
1.2
635         int oty;
ragge
1.1
636
ragge
1.13
637         o = p->n_op;
ragge
1.1
638         ty = optype(o);
639
640         ifty == LTYPE ) return;
641
642         switcho ){
643
644         case UNARY CALL:
645         case UNARY FORTCALL:
646         case UNARY STCALL:
647                 ++callflag;
648                 break;
649
650         case UNARY MUL:
ragge
1.13
651                 if (asgop(p->n_left->n_op))
652                         stoasg(p->n_leftUNARY MUL);
ragge
1.1
653                 break;
654
655         case CALL:
656         case FORTCALL:
657         case STCALL:
ragge
1.13
658                 storep->n_left );
659                 stoargp->n_righto );
ragge
1.1
660                 ++callflag;
661                 return;
662
663         case CBRANCH:   /* to prevent complicated expressions on the LHS from being stored */
ragge
1.13
664                 constorep->n_left );
ragge
1.1
665                 return;
666
667                 }
668
ragge
1.11
669         if (ty == UTYPE) {
ragge
1.13
670                 store(p->n_left);
ragge
1.1
671                 return;
ragge
1.11
672         }
ragge
1.1
673
ragge
1.13
674         if (asgop(p->n_right->n_op))
675                 stoasg(p->n_righto);
ragge
1.1
676
ragge
1.13
677         ifp->n_su>fregs ){ /* must store */
ragge
1.1
678                 mkadrsp );  /* set up stotree and stocook to subtree
679                                  that must be stored */
680                 }
681
ragge
1.13
682         storep->n_right );
683         storep->n_left );
ragge
1.1
684         }
685
ragge
1.2
686 /*
687  * store conditional expressions
688  * the point is, avoid storing expressions in conditional
689  * conditional context, since the evaluation order is predetermined
690  */
691 void
692 constore(NODE *p)
693 {
ragge
1.1
694         storep );
ragge
1.2
695 }
ragge
1.1
696
ragge
1.2
697 /* mark off calls below the current node */
698 void
699 markcall(NODE *p)
700 {
ragge
1.1
701
702         again:
ragge
1.13
703         switchp->n_op ){
ragge
1.1
704
705         case UNARY CALL:
706         case UNARY STCALL:
707         case UNARY FORTCALL:
708         case CALL:
709         case STCALL:
710         case FORTCALL:
711                 ++callflag;
712                 return;
713
714                 }
715
ragge
1.13
716         switchoptypep->n_op ) ){
ragge
1.1
717
718         case BITYPE:
ragge
1.13
719                 markcallp->n_right );
ragge
1.1
720         case UTYPE:
ragge
1.13
721                 p = p->n_left;
ragge
1.1
722                 /* eliminate recursion (aren't I clever...) */
723                 goto again;
724         case LTYPE:
725                 return;
726                 }
727
ragge
1.2
728 }
ragge
1.1
729
ragge
1.2
730 void
731 stoarg(NODE *pint calltype)
732 {
ragge
1.1
733         /* arrange to store the args */
ragge
1.13
734         ifp->n_op == CM ){
735                 stoargp->n_leftcalltype );
736                 p = p->n_right ;
ragge
1.1
737                 }
738         ifcalltype == CALL ){
739                 STOARG(p);
740                 }
741         else ifcalltype == STCALL ){
742                 STOSTARG(p);
743                 }
744         else {
745                 STOFARG(p);
746                 }
747         callflag = 0;
748         store(p);
ragge
1.30
749 #ifdef NO_NESTCALLS
ragge
1.1
750         ifcallflag ){ /* prevent two calls from being active at once  */
751                 SETSTO(p,INTEMP);
752                 store(p); /* do again to preserve bottom up nature....  */
ragge
1.2
753         }
ragge
1.1
754 #endif
ragge
1.2
755 }
ragge
1.1
756
757 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
758
ragge
1.2
759 void
760 rcount()
761 /* count recursions */
ragge
1.1
762         if( ++nrecur > NRECUR ){
763                 cerror"expression causes compiler loop: try simplifying" );
764         }
ragge
1.2
765 }
ragge
1.1
766
ragge
1.30
767 #ifdef PCC_DEBUG
ragge
1.2
768 int
ragge
1.8
769 e2print(NODE *pint downint *aint *b)
ragge
1.2
770 {
ragge
1.1
771
772         *a = *b = down+1;
773         whiledown >= 2 ){
774                 printf"\t" );
775                 down -= 2;
776                 }
777         ifdown-- ) printf"    " );
778
779
ragge
1.13
780         printf"%p) %s"popst[p->n_op] );
781         switchp->n_op ) { /* special cases */
ragge
1.1
782
783         case REG:
ragge
1.13
784                 printf" %s"rnames[p->n_rval] );
ragge
1.1
785                 break;
786
ragge
1.23
787         case TEMP:
788                 printf(" %d", (int)p->n_lval);
789                 break;
790
ragge
1.1
791         case ICON:
792         case NAME:
793         case OREG:
794                 printf" " );
795                 adrputp );
796                 break;
797
798         case STCALL:
799         case UNARY STCALL:
800         case STARG:
801         case STASG:
ragge
1.13
802                 printf" size=%d"p->n_stsize );
803                 printf" align=%d"p->n_stalign );
ragge
1.1
804                 break;
805                 }
806
807         printf", " );
ragge
1.33
808         tprintp->n_typep->n_qual);
ragge
1.1
809         printf", " );
ragge
1.13
810         ifp->n_rall == NOPREF ) printf"NOPREF" );
ragge
1.1
811         else {
ragge
1.13
812                 ifp->n_rall & MUSTDO ) printf"MUSTDO " );
ragge
1.1
813                 else printf"PREF " );
ragge
1.13
814                 printf"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
815                 }
ragge
1.13
816         printf", SU= %d\n"p->n_su );
ragge
1.2
817         return 0;
818 }
ragge
1.30
819 #endif
ragge
1.1
820
821 #ifndef FIELDOPS
ragge
1.7
822 /*
823  * do this if there is no special hardware support for fields
824  */
825 static int
826 ffld(NODE *pint downint *down1int *down2 )
827 {
828         /*
829          * look for fields that are not in an lvalue context,
830          * and rewrite them...
831          */
832         NODE *shp;
833         int sovty;
ragge
1.1
834
ragge
1.13
835         *down1 =  asgopp->n_op );
ragge
1.1
836         *down2 = 0;
837
ragge
1.13
838         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
839
ragge
1.7
840                 if( !rewfld(p) ) return 0;
ragge
1.1
841
ragge
1.48
842                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
843                 v = p->n_rval;
ragge
1.1
844                 s = UPKFSZ(v);
845 # ifdef RTOLBYTES
846                 o = UPKFOFF(v);  /* amount to shift */
847 # else
ragge
1.13
848                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
849 #endif
850
851                 /* make & mask part */
852
ragge
1.13
853                 p->n_left->n_type = ty;
ragge
1.1
854
ragge
1.13
855                 p->n_op = AND;
856                 p->n_right = talloc();
857                 p->n_right->n_op = ICON;
858                 p->n_right->n_rall = NOPREF;
859                 p->n_right->n_type = ty;
860                 p->n_right->n_lval = 1;
861                 p->n_right->n_rval = 0;
862                 p->n_right->n_name = "";
863                 p->n_right->n_lval <<= s;
864                 p->n_right->n_lval--;
ragge
1.1
865
866                 /* now, if a shift is needed, do it */
867
868                 ifo != 0 ){
869                         shp = talloc();
ragge
1.13
870                         shp->n_op = RS;
871                         shp->n_rall = NOPREF;
872                         shp->n_type = ty;
873                         shp->n_left = p->n_left;
874                         shp->n_right = talloc();
875                         shp->n_right->n_op = ICON;
876                         shp->n_right->n_rall = NOPREF;
877                         shp->n_right->n_type = ty;
878                         shp->n_right->n_rval = 0;
879                         shp->n_right->n_lval = o;  /* amount to shift */
880                         shp->n_right->n_name = "";
881                         p->n_left = shp;
ragge
1.1
882                         /* whew! */
883                 }
884         }
ragge
1.7
885         return 0;
886 }
ragge
1.1
887 #endif
888
ragge
1.23
889 /*
890  * change left TEMPs into OREGs
ragge
1.40
891  */
892 void
893 deltemp(NODE *p)
894 {
895         struct templst *w = templst;
896
897         if (p->n_op != TEMP)
898                 return;
899         /*
900          * the size of a TEMP is in multiples of the reg size.
901          */
902         p->n_op = OREG;
903         p->n_rval = FPREG;
904         while (w != NULL) {
905                 if (w->tempnr == p->n_lval)
906                         break;
907                 w = w->next;
908         }
909         if (w == NULL) {
910                 w = tmpalloc(sizeof(struct templst));
911                 w->tempnr = p->n_lval;
912                 w->tempoff = BITOOR(freetemp(szty(p->n_type)));
913                 w->next = templst;
914                 templst = w;
915         }
916         p->n_lval = w->tempoff;
917         p->n_name = "";
918 }
919
920 /*
ragge
1.48
921  * for pointer/integer arithmetic, set pointer at left node
922  */
923 static void
924 setleft(NODE *p)          
925 {        
926         NODE *q;
927
928         /* only additions for now */
929         if (p->n_op != PLUS)
930                 return;
931         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
932                 q = p->n_right;
933                 p->n_right = p->n_left;
934                 p->n_left = q;
935         }
936 }
937
938 /*
ragge
1.23
939  * look for situations where we can turn * into OREG
940  */
ragge
1.2
941 void
942 oreg2(NODE *p)
943 {
ragge
1.1
944
945         NODE *q;
ragge
1.2
946         int r;
947         char *cp;
948         NODE *ql, *qr;
ragge
1.1
949         CONSZ temp;
ragge