Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030902123921

Diff

Diff from 1.54 to:

Annotations

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

Annotated File View

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