Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030901145559

Diff

Diff from 1.52 to:

Annotations

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

Annotated File View

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