Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030901140805

Diff

Diff from 1.51 to:

Annotations

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

Annotated File View

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