Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030901082854

Diff

Diff from 1.49 to:

Annotations

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

Annotated File View

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