Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030908114456

Diff

Diff from 1.59 to:

Annotations

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

Annotated File View

ragge
1.59
1 /*      $Id: reader.c,v 1.59 2003/09/08 11:44:56 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.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:
ragge
1.59
420 if (0) {
ragge
1.57
421                 if (!canaddr(p->n_left)) {
422                         if (p->n_left->n_op == UNARY MUL) {
423                                 offstar(p->n_left->n_left);
424                                 goto again;
425                         }
426                         order(p->n_leftINTAREG|INTBREG);
427                 }
428                 if (!canaddr(p->n_right)) {
429                         if (p->n_right->n_op == UNARY MUL) {
430                                 offstar(p->n_right->n_left);
431                                 goto again;
432                         }
433                         order(p->n_rightINTAREG|INTBREG);
434                 }
435                 rv = relops(p);
436                 m = FORCC;
437                 goto foo;
ragge
1.59
438 }
ragge
1.57
439
ragge
1.1
440         default:
441                 /* look for op in table */
ragge
1.8
442                 for (;;) {
443                         if ((m = match(pcookie)) == MDONE)
444                                 goto cleanup;
445                         else if (m == MNOPE) {
446                                 if (!(cookie = nextcook(pcookie)))
447                                         goto nomat;
ragge
1.1
448                                 continue;
ragge
1.8
449                         } else
450                                 break;
451                 }
ragge
1.1
452                 break;
453
454         case FORCE:
455         case CBRANCH:
456         case UNARY CALL:
457         case CALL:
458         case UNARY STCALL:
459         case STCALL:
460         case UNARY FORTCALL:
461         case FORTCALL:
462                 /* don't even go near the table... */
463                 ;
464
ragge
1.8
465         }
ragge
1.25
466         /*
ragge
1.8
467          * get here to do rewriting if no match or
468          * fall through from above for hard ops
469          */
ragge
1.1
470
ragge
1.13
471         p1 = p->n_left;
ragge
1.8
472         if (ty == BITYPE)
ragge
1.13
473                 p2 = p->n_right;
ragge
1.8
474         else
475                 p2 = NIL;
ragge
1.1
476         
ragge
1.30
477 #ifdef PCC_DEBUG
ragge
1.8
478         if (odebug) {
479                 printf("order(%p, "p);
480                 prcook(cook);
481                 printf("), cookie ");
482                 prcook(cookie);
483                 printf(", rewrite %s\n"opst[m]);
484         }
ragge
1.30
485 #endif
ragge
1.8
486         switch (m) {
ragge
1.1
487         default:
488                 nomat:
ragge
1.13
489                 cerror"no table entry for op %s"opst[p->n_op] );
ragge
1.1
490
491         case FORCE:
492                 cook = INTAREG|INTBREG;
ragge
1.19
493                 order(p->n_leftcook);
494                 reclaim(pRLEFTcook);
ragge
1.38
495                 return;
ragge
1.1
496
497         case CBRANCH:
ragge
1.36
498                 p1->n_label = p2->n_lval;
ragge
1.42
499                 o = p1->n_op;
ragge
1.36
500                 codgen(p1FORCC);
ragge
1.42
501                 cbgen(op2->n_lval);
ragge
1.36
502                 reclaim(p1RNULL0);
ragge
1.19
503                 nfree(p2);
504                 nfree(p);
ragge
1.1
505                 return;
506
507         case FLD:       /* fields of funny type */
ragge
1.13
508                 if ( p1->n_op == UNARY MUL ){
509                         offstarp1->n_left );
ragge
1.1
510                         goto again;
511                         }
512
513         case UNARY MINUS:
ragge
1.30
514                 orderp1INBREG|INAREG);
ragge
1.1
515                 goto again;
516
517         case NAME:
518                 /* all leaves end up here ... */
519                 ifo == REG ) goto nomat;
520                 orderpINTAREG|INTBREG );
521                 goto again;
522
523         case INIT:
ragge
1.12
524                 uerror("init: illegal initialization");
ragge
1.1
525                 return;
526
527         case UNARY FORTCALL:
ragge
1.13
528                 p->n_right = NIL;
ragge
1.1
529         case FORTCALL:
ragge
1.13
530                 o = p->n_op = UNARY FORTCALL;
ragge
1.1
531                 ifgenfcallpcookie ) ) goto nomat;
532                 goto cleanup;
533
534         case UNARY CALL:
ragge
1.13
535                 p->n_right = NIL;
ragge
1.1
536         case CALL:
ragge
1.13
537                 o = p->n_op = UNARY CALL;
ragge
1.1
538                 ifgencallpcookie ) ) goto nomat;
539                 goto cleanup;
540
541         case UNARY STCALL:
ragge
1.13
542                 p->n_right = NIL;
ragge
1.1
543         case STCALL:
ragge
1.13
544                 o = p->n_op = UNARY STCALL;
ragge
1.1
545                 ifgenscallpcookie ) ) goto nomat;
546                 goto cleanup;
547
548                 /* if arguments are passed in register, care must be taken that reclaim
ragge
1.2
549                  * not throw away the register which now has the result... */
ragge
1.1
550
551         case UNARY MUL:
552                 ifcook == FOREFF ){
553                         /* do nothing */
ragge
1.13
554                         orderp->n_leftFOREFF );
ragge
1.19
555                         nfree(p);
ragge
1.1
556                         return;
ragge
1.19
557                 }
ragge
1.30
558                 offstarp->n_left );
559 #if 0
560                 canon(p);
561                 ifcanaddr(p) && cook != INTEMP )
562                         goto cleanup;
ragge
1.1
563 #endif
564                 goto again;
565
566         case INCR:  /* INCR and DECR */
567                 ifsetincr(p) ) goto again;
568
ragge
1.49
569                 /* x++ becomes (x = x + 1) -1; */
ragge
1.1
570
571                 p1 = tcopy(p);
ragge
1.49
572                 if (cook & FOREFF) {
573                         nfree(p->n_right);
574                         p->n_right = p1;
ragge
1.50
575                         p1->n_op = (p->n_op == INCR) ? PLUSMINUS;
ragge
1.49
576                         p->n_op = ASSIGN;
577                 } else {
578                         p2 = talloc();
579                         p2->n_rall = NOPREF;
580                         p2->n_name = "";
581                         p2->n_op = ASSIGN;
582                         p2->n_type = p->n_type;
583                         p2->n_left = p->n_left;
584                         p2->n_right = p1;
585                         p1->n_op = (p->n_op == INCR) ? PLUSMINUS;
586                         p->n_op = (p->n_op == INCR) ? MINUS : PLUS;
ragge
1.50
587                         p->n_left = p2;
ragge
1.49
588                 }
ragge
1.1
589                 goto again;
590
591         case STASG:
592                 ifsetstrp ) ) goto again;
593                 goto nomat;
594
595         case ASSIGN:
ragge
1.8
596                 if (setasg(p))
597                         goto again;
ragge
1.1
598                 goto nomat;
599
600
601         case BITYPE:
602                 ifsetbinp ) ) goto again;
603                 goto nomat;
604
605                 }
606
607         cleanup:
608
609         /* if it is not yet in the right state, put it there */
610
611         ifcook & FOREFF ){
612                 reclaimpRNULL0 );
613                 return;
614                 }
615
ragge
1.13
616         ifp->n_op==FREE ) return;
ragge
1.1
617
618         iftshapepcook ) ) return;
619
620         if( (m=match(p,cook) ) == MDONE ) return;
621
622         /* we are in bad shape, try one last chance */
ragge
1.8
623         if (lastchance(pcook))
624                 goto again;
ragge
1.1
625
626         goto nomat;
ragge
1.8
627 }
ragge
1.1
628
629 int callflag;
630 int fregs;
631
ragge
1.2
632 void
633 storep ) NODE *p; {
ragge
1.1
634
635         /* find a subtree of p which should be stored */
636
ragge
1.2
637         int oty;
ragge
1.1
638
ragge
1.13
639         o = p->n_op;
ragge
1.1
640         ty = optype(o);
641
642         ifty == LTYPE ) return;
643
644         switcho ){
645
646         case UNARY CALL:
647         case UNARY FORTCALL:
648         case UNARY STCALL:
649                 ++callflag;
650                 break;
651
652         case UNARY MUL:
ragge
1.13
653                 if (asgop(p->n_left->n_op))
654                         stoasg(p->n_leftUNARY MUL);
ragge
1.1
655                 break;
656
657         case CALL:
658         case FORTCALL:
659         case STCALL:
ragge
1.13
660                 storep->n_left );
661                 stoargp->n_righto );
ragge
1.1
662                 ++callflag;
663                 return;
664
665         case CBRANCH:   /* to prevent complicated expressions on the LHS from being stored */
ragge
1.13
666                 constorep->n_left );
ragge
1.1
667                 return;
668
669                 }
670
ragge
1.11
671         if (ty == UTYPE) {
ragge
1.13
672                 store(p->n_left);
ragge
1.1
673                 return;
ragge
1.11
674         }
ragge
1.1
675
ragge
1.13
676         if (asgop(p->n_right->n_op))
677                 stoasg(p->n_righto);
ragge
1.1
678
ragge
1.13
679         ifp->n_su>fregs ){ /* must store */
ragge
1.1
680                 mkadrsp );  /* set up stotree and stocook to subtree
681                                  that must be stored */
682                 }
683
ragge
1.13
684         storep->n_right );
685         storep->n_left );
ragge
1.1
686         }
687
ragge
1.2
688 /*
689  * store conditional expressions
690  * the point is, avoid storing expressions in conditional
691  * conditional context, since the evaluation order is predetermined
692  */
693 void
694 constore(NODE *p)
695 {
ragge
1.1
696         storep );
ragge
1.2
697 }
ragge
1.1
698
ragge
1.2
699 /* mark off calls below the current node */
700 void
701 markcall(NODE *p)
702 {
ragge
1.1
703
704         again:
ragge
1.13
705         switchp->n_op ){
ragge
1.1
706
707         case UNARY CALL:
708         case UNARY STCALL:
709         case UNARY FORTCALL:
710         case CALL:
711         case STCALL:
712         case FORTCALL:
713                 ++callflag;
714                 return;
715
716                 }
717
ragge
1.13
718         switchoptypep->n_op ) ){
ragge
1.1
719
720         case BITYPE:
ragge
1.13
721                 markcallp->n_right );
ragge
1.1
722         case UTYPE:
ragge
1.13
723                 p = p->n_left;
ragge
1.1
724                 /* eliminate recursion (aren't I clever...) */
725                 goto again;
726         case LTYPE:
727                 return;
728                 }
729
ragge
1.2
730 }
ragge
1.1
731
ragge
1.2
732 void
733 stoarg(NODE *pint calltype)
734 {
ragge
1.1
735         /* arrange to store the args */
ragge
1.13
736         ifp->n_op == CM ){
737                 stoargp->n_leftcalltype );
738                 p = p->n_right ;
ragge
1.1
739                 }
740         ifcalltype == CALL ){
741                 STOARG(p);
742                 }
743         else ifcalltype == STCALL ){
744                 STOSTARG(p);
745                 }
746         else {
747                 STOFARG(p);
748                 }
749         callflag = 0;
750         store(p);
ragge
1.30
751 #ifdef NO_NESTCALLS
ragge
1.1
752         ifcallflag ){ /* prevent two calls from being active at once  */
753                 SETSTO(p,INTEMP);
754                 store(p); /* do again to preserve bottom up nature....  */
ragge
1.2
755         }
ragge
1.1
756 #endif
ragge
1.2
757 }
ragge
1.1
758
759 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
760
ragge
1.2
761 void
762 rcount()
763 /* count recursions */
ragge
1.1
764         if( ++nrecur > NRECUR ){
765                 cerror"expression causes compiler loop: try simplifying" );
766         }
ragge
1.2
767 }
ragge
1.1
768
ragge
1.30
769 #ifdef PCC_DEBUG
ragge
1.2
770 int
ragge
1.8
771 e2print(NODE *pint downint *aint *b)
ragge
1.2
772 {
ragge
1.1
773
774         *a = *b = down+1;
775         whiledown >= 2 ){
776                 printf"\t" );
777                 down -= 2;
778                 }
779         ifdown-- ) printf"    " );
780
781
ragge
1.13
782         printf"%p) %s"popst[p->n_op] );
783         switchp->n_op ) { /* special cases */
ragge
1.1
784
785         case REG:
ragge
1.13
786                 printf" %s"rnames[p->n_rval] );
ragge
1.1
787                 break;
788
ragge
1.23
789         case TEMP:
790                 printf(" %d", (int)p->n_lval);
791                 break;
792
ragge
1.1
793         case ICON:
794         case NAME:
795         case OREG:
796                 printf" " );
797                 adrputp );
798                 break;
799
800         case STCALL:
801         case UNARY STCALL:
802         case STARG:
803         case STASG:
ragge
1.13
804                 printf" size=%d"p->n_stsize );
805                 printf" align=%d"p->n_stalign );
ragge
1.1
806                 break;
807                 }
808
809         printf", " );
ragge
1.33
810         tprintp->n_typep->n_qual);
ragge
1.1
811         printf", " );
ragge
1.13
812         ifp->n_rall == NOPREF ) printf"NOPREF" );
ragge
1.1
813         else {
ragge
1.13
814                 ifp->n_rall & MUSTDO ) printf"MUSTDO " );
ragge
1.1
815                 else printf"PREF " );
ragge
1.13
816                 printf"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
817                 }
ragge
1.13
818         printf", SU= %d\n"p->n_su );
ragge
1.2
819         return 0;
820 }
ragge
1.30
821 #endif
ragge
1.1
822
823 #ifndef FIELDOPS
ragge
1.7
824 /*
825  * do this if there is no special hardware support for fields
826  */
827 static int
828 ffld(NODE *pint downint *down1int *down2 )
829 {
830         /*
831          * look for fields that are not in an lvalue context,
832          * and rewrite them...
833          */
834         NODE *shp;
835         int sovty;
ragge
1.1
836
ragge
1.13
837         *down1 =  asgopp->n_op );
ragge
1.1
838         *down2 = 0;
839
ragge
1.13
840         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
841
ragge
1.7
842                 if( !rewfld(p) ) return 0;
ragge
1.1
843
ragge
1.48
844                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
845                 v = p->n_rval;
ragge
1.1
846                 s = UPKFSZ(v);
847 # ifdef RTOLBYTES
848                 o = UPKFOFF(v);  /* amount to shift */
849 # else
ragge
1.13
850                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
851 #endif
852
853                 /* make & mask part */
854
ragge
1.13
855                 p->n_left->n_type = ty;
ragge
1.1
856
ragge
1.13
857                 p->n_op = AND;
858                 p->n_right = talloc();
859                 p->n_right->n_op = ICON;
860                 p->n_right->n_rall = NOPREF;
861                 p->n_right->n_type = ty;
862                 p->n_right->n_lval = 1;
863                 p->n_right->n_rval = 0;
864                 p->n_right->n_name = "";
865                 p->n_right->n_lval <<= s;
866                 p->n_right->n_lval--;
ragge
1.1
867
868                 /* now, if a shift is needed, do it */
869
870                 ifo != 0 ){
871                         shp = talloc();
ragge
1.13
872                         shp->n_op = RS;
873                         shp->n_rall = NOPREF;
874                         shp->n_type = ty;
875                         shp->n_left = p->n_left;
876                         shp->n_right = talloc();
877                         shp->n_right->n_op = ICON;
878                         shp->n_right->n_rall = NOPREF;
879                         shp->n_right->n_type = ty;
880                         shp->n_right->n_rval = 0;
881                         shp->n_right->n_lval = o;  /* amount to shift */
882                         shp->n_right->n_name = "";
883                         p->n_left = shp;
ragge
1.1
884                         /* whew! */
885                 }
886         }
ragge
1.7
887         return 0;
888 }
ragge
1.1
889 #endif
890
ragge
1.23
891 /*
892  * change left TEMPs into OREGs
ragge
1.40
893  */
894 void
895 deltemp(NODE *p)
896 {
897         struct templst *w = templst;
898
899         if (p->n_op != TEMP)
900                 return;
901         /*
902          * the size of a TEMP is in multiples of the reg size.
903          */
904         p->n_op = OREG;
905         p->n_rval = FPREG;
906         while (w != NULL) {
907                 if (w->tempnr == p->n_lval)
908                         break;
909                 w = w->next;
910         }
911         if (w == NULL) {
912                 w = tmpalloc(sizeof(struct templst));
913                 w->tempnr = p->n_lval;
914                 w->tempoff = BITOOR(freetemp(szty(p->n_type)));
915                 w->next = templst;
916                 templst = w;
917         }
918         p->n_lval = w->tempoff;
919         p->n_name = "";
920 }
921
922 /*
ragge
1.48
923  * for pointer/integer arithmetic, set pointer at left node
924  */
925 static void
926 setleft(NODE *p)          
927 {        
928         NODE *q;
929
930         /* only additions for now */
931         if (p->n_op != PLUS)
932                 return;
933         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
934                 q = p->n_right;
935                 p->n_right = p->n_left;
936                 p->n_left = q;
937         }
938 }
939
940 /*
ragge
1.23
941  * look for situations where we can turn * into OREG
942  */
ragge
1.2
943 void
944 oreg2(NODE *p)
945 {
ragge
1.1
946
947         NODE *q;
ragge
1.2
948         int r;
949         char *cp;
950         NODE *ql, *qr;