Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030902081351

Diff

Diff from 1.53 to:

Annotations

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

Annotated File View

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