Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030902142743

Diff

Diff from 1.55 to:

Annotations

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

Annotated File View

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