Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030912151401

Diff

Diff from 1.68 to:

Annotations

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

Annotated File View

ragge
1.68
1 /*      $Id: reader.c,v 1.68 2003/09/12 15:14:01 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.65
62 int findops(NODE *p);
63 int relops(NODE *p);
64 int asgops(NODE *pint);
65
66 #define LREG    001
67 #define RREG    002
68 #define LOREG   004
69 #define ROREG   010
70 #define LTEMP   020
71 #define RTEMP   040
ragge
1.37
72
ragge
1.46
73 #define DELAYS 20
74 NODE *deltrees[DELAYS];
75 int deli;
ragge
1.26
76
77 #ifdef PCC_DEBUG
78 static void
79 cktree(NODE *p)
80 {
81         if (p->n_op > MAXOP)
82                 cerror("op %d slipped through"p->n_op);
ragge
1.35
83         if (p->n_op == CBRANCH && !logop(p->n_left->n_op))
84                 cerror("not logop branch");
ragge
1.47
85         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
86                 cerror("asgop %d slipped through"p->n_op);
ragge
1.26
87 }
88 #endif
ragge
1.8
89
ragge
1.17
90 static void
ragge
1.2
91 p2compile(NODE *p)
92 {
ragge
1.46
93         int i;
94
ragge
1.15
95 #if !defined(MULTIPASS)
96         extern char *ftitle;
97 #endif
ragge
1.1
98
ragge
1.14
99         if (lflag)
100                 lineid(linenoftitle);
101
ragge
1.1
102         /* generate code for the tree p */
ragge
1.26
103 #ifdef PCC_DEBUG
104         walkf(pcktree);
105         if (e2debug)
106                 fwalk(pe2print0);
107 #endif
ragge
1.25
108
ragge
1.1
109 # ifdef MYREADER
110         MYREADER(p);  /* do your own laundering of the input */
111 # endif
112         nrecur = 0;
ragge
1.46
113         deli = 0;
114         delay(p);
ragge
1.25
115         codgen(pFOREFF);
ragge
1.46
116         for (i = 0i < deli; ++i)
117                 codgen(deltrees[i], FOREFF);  /* do the rest */
ragge
1.1
118         reclaimpRNULL0 );
119         allchk();
ragge
1.46
120 }
121
122 /* look for delayable ++ and -- operators */
123 void
124 delay(NODE *p)
125 {
126         int ty = optype(p->n_op);
127
128         switch (p->n_op) {
129         case CALL:
ragge
1.68
130         case UCALL:
ragge
1.46
131         case STCALL:
ragge
1.68
132         case USTCALL:
ragge
1.46
133         case FORTCALL:
ragge
1.68
134         case UFORTCALL:
ragge
1.46
135         case CBRANCH:
136                 /* for the moment, don7t delay past a conditional context, or
137                  * inside of a call */
138                 return;
139
ragge
1.67
140         case UMUL:
ragge
1.46
141                 /* if *p++, do not rewrite */
142                 ifautoincrp ) ) return;
143                 break;
144
145         case INCR:
146         case DECR:
147                 ifdeltestp ) ){
148                         ifdeli < DELAYS ){
149                                 register NODE *q;
150                                 deltrees[deli++] = tcopy(p);
151                                 q = p->n_left;
ragge
1.58
152                                 nfree(p->n_right); /* zap constant */
ragge
1.46
153                                 *p = *q;
ragge
1.58
154                                 nfree(q);
ragge
1.46
155                                 return;
156                                 }
157                         }
158
159                 }
160
161         if (ty == BITYPE)
162                 delay(p->n_right);
163         if (ty != LTYPE)
164                 delay(p->n_left);
ragge
1.2
165 }
ragge
1.1
166
ragge
1.17
167 static void newblock(int myregint aoff);
168 static void epilogue(int regsint autosint retlab);
169
ragge
1.2
170 void
ragge
1.17
171 pass2_compile(struct interpass *ip)
172 {
ragge
1.37
173         if (Oflag) {
174                 if (ip->type == IP_PROLOG)
175                         saving++;
176                 if (saving)
177                         return saveip(ip);
178         }
ragge
1.17
179         switch (ip->type) {
180         case IP_NODE:
181                 p2compile(ip->ip_node);
ragge
1.21
182                 tfree(ip->ip_node);
ragge
1.17
183                 break;
184         case IP_PROLOG:
185                 prologue(ip->ip_regsip->ip_auto);
186                 break;
187         case IP_NEWBLK:
188                 newblock(ip->ip_regsip->ip_auto);
189                 break;
190         case IP_EPILOG:
191                 epilogue(ip->ip_regsip->ip_autoip->ip_retl);
ragge
1.18
192                 break;
193         case IP_LOCCTR:
194                 setlocc(ip->ip_locc);
195                 break;
196         case IP_DEFLAB:
197                 deflab(ip->ip_lbl);
198                 break;
199         case IP_DEFNAM:
200                 defname(ip->ip_nameip->ip_vis);
ragge
1.39
201                 break;
202         case IP_ASM:
203                 printf("%s\n"ip->ip_asm);
ragge
1.18
204                 break;
ragge
1.17
205         default:
206                 cerror("pass2_compile %d"ip->type);
207         }
208 }
209
210 static void
ragge
1.16
211 newblock(int myregint aoff)
ragge
1.2
212 {
ragge
1.1
213         setregs();
ragge
1.2
214 }
ragge
1.1
215
ragge
1.17
216 static void
ragge
1.16
217 epilogue(int regsint autosint retlab)
ragge
1.2
218 {
ragge
1.23
219         templst = NULL;
ragge
1.16
220         eoftn(regsautosretlab);
ragge
1.2
221 }
ragge
1.1
222
ragge
1.2
223 /*
224  * generate the code for p;
225  * order may call codgen recursively
226  * cookie is used to describe the context
227  */
228 void
229 codgen(NODE *pint cookie)
230 {
ragge
1.1
231
ragge
1.8
232         for (;;) {
ragge
1.1
233                 canon(p);  /* creats OREG from * if possible and does sucomp */
234                 stotree = NIL;
ragge
1.30
235 #ifdef PCC_DEBUG
ragge
1.8
236                 if (e2debug) {
237                         printf("store called on:\n");
238                         fwalk(pe2print0);
239                 }
ragge
1.30
240 #endif
ragge
1.1
241                 store(p);
242                 ifstotree==NIL ) break;
243
244                 /* because it's minimal, can do w.o. stores */
245
246                 orderstotreestocook );
ragge
1.2
247         }
ragge
1.1
248         orderpcookie );
ragge
1.2
249 }
ragge
1.1
250
ragge
1.30
251 #ifdef PCC_DEBUG
ragge
1.1
252 char *cnames[] = {
253         "SANY",
254         "SAREG",
255         "STAREG",
256         "SBREG",
257         "STBREG",
258         "SCC",
259         "SNAME",
260         "SCON",
261         "SFLD",
262         "SOREG",
263         "STARNM",
264         "STARREG",
265         "INTEMP",
266         "FORARG",
267         "SWADD",
268         0,
269         };
270
ragge
1.2
271 /*
272  * print a nice-looking description of cookie
273  */
274 void
275 prcook(int cookie)
276 {
ragge
1.1
277         int iflag;
278
279         ifcookie & SPECIAL ){
280                 ifcookie == SZERO ) printf"SZERO" );
281                 else ifcookie == SONE ) printf"SONE" );
282                 else ifcookie == SMONE ) printf"SMONE" );
283                 else printf"SPECIAL+%d"cookie & ~SPECIAL );
284                 return;
285                 }
286
287         flag = 0;
288         fori=0cnames[i]; ++i ){
289                 ifcookie & (1<<i) ){
290                         ifflag ) printf"|" );
291                         ++flag;
292                         printfcnames[i] );
293                         }
294                 }
295
ragge
1.2
296 }
ragge
1.30
297 #endif
ragge
1.1
298
299 int odebug = 0;
300
ragge
1.2
301 void
302 order(NODE *pint cook)
303 {
ragge
1.60
304         struct optab *q;
ragge
1.57
305         int otymrv;
ragge
1.1
306         int cookie;
ragge
1.2
307         NODE *p1, *p2;
ragge
1.1
308
ragge
1.8
309         /*
310          * by this time, p should be able to be generated without stores;
311          * the only question is how
312          */
ragge
1.1
313         again:
314
315         cookie = cook;
316         rcount();
317         canon(p);
ragge
1.13
318         rallo(pp->n_rall);
ragge
1.1
319
ragge
1.30
320 #ifdef PCC_DEBUG
ragge
1.8
321         if (odebug) {
322                 printf("order(%p, "p);
323                 prcook(cookie);
324                 printf(")\n");
325                 fwalk(pe2print0);
326         }
ragge
1.30
327 #endif
ragge
1.1
328
ragge
1.13
329         o = p->n_op;
ragge
1.1
330         ty = optype(o);
331
332         /* first of all, for most ops, see if it is in the table */
333
334         /* look for ops */
335
ragge
1.13
336         switch (m = p->n_op) {
ragge
1.1
337
ragge
1.65
338 #if 0
ragge
1.63
339         case ASSIGN:
340                 /*
341                  * For ASSIGN the left node must be directly addressable,
342                  * the right can be put into a register.
343                  * XXX - Will not try to match any smart instructions yet.
344                  */
ragge
1.64
345 //printf("foo\n");
346 //fwalk(p, e2print, 0);
ragge
1.63
347                 if (!canaddr(p->n_left)) {
ragge
1.67
348                         if (p->n_left->n_op == UMUL) {
ragge
1.63
349                                 offstar(p->n_left->n_left);
350                                 goto again;
351                         }
352                         cerror("bad assign lvalue");
353                 }
ragge
1.64
354 //printf("foo1\n");
355 //fwalk(p, e2print, 0);
ragge
1.63
356                 if (!canaddr(p->n_right)) {
ragge
1.67
357                         if (p->n_right->n_op == UMUL) {
ragge
1.63
358                                 offstar(p->n_right->n_left);
359                                 goto again;
360                         }
361                         order(p->n_rightINTAREG|INTBREG);
362                 }
ragge
1.64
363 //printf("foo2\n");
364 //fwalk(p, e2print, 0);
ragge
1.63
365                 rv = asgops(pcook);
ragge
1.64
366 //printf("foo6 : %x\n", rv);
ragge
1.63
367                 if (rv < 0)
368                         goto nomat;
ragge
1.65
369                 if (rv & RREG)
ragge
1.63
370                         order(p->n_rightINTAREG|INTBREG);
371                 q = &table[rv >> 2];
ragge
1.64
372 //printf("foo7\n");
ragge
1.63
373                 if (!allo(pq))
374                         cerror("assign allo failed");
ragge
1.64
375 //printf("foo3\n");
ragge
1.63
376                 expand(pcookq->cstring);
377                 reclaim(pq->rewritecook);
ragge
1.64
378 //printf("foo4\n");
379 //fwalk(p, e2print, 0);
ragge
1.63
380                 goto cleanup;
ragge
1.65
381 #endif
382
ragge
1.48
383         case PLUS:
ragge
1.50
384         case MINUS:
ragge
1.51
385         case AND:
386         case OR:
387         case ER:
ragge
1.52
388         case DIV:
ragge
1.53
389         case MOD:
390         case MUL:
ragge
1.55
391         case LS:
392         case RS:
ragge
1.48
393
ragge
1.60
394                 /*
395                  * Be sure that both sides are addressable.
396                  */
ragge
1.50
397 //printf("newstyle node %p\n", p);
ragge
1.60
398                 if (!canaddr(p->n_left)) {
ragge
1.67
399                         if (p->n_left->n_op == UMUL) {
ragge
1.60
400                                 offstar(p->n_left->n_left);
401                                 goto again;
ragge
1.53
402                         }
ragge
1.60
403                         order(p->n_leftINTAREG|INTBREG);
404                 }
ragge
1.50
405 //printf("newstyle addrl %p\n", p);
ragge
1.60
406                 if (!canaddr(p->n_right)) {
ragge
1.67
407                         if (p->n_right->n_op == UMUL) {
ragge
1.60
408                                 offstar(p->n_right->n_left);
409                                 goto again;
ragge
1.53
410                         }
ragge
1.60
411                         order(p->n_rightINTAREG|INTBREG);
412                 }
ragge
1.50
413 //printf("newstyle addrr %p\n", p);
ragge
1.48
414
ragge
1.60
415                 /*
416                  *
417                  */
418                 m = INTAREG|INTBREG;
419                 rv = findops(p);
420 foo:            if (rv < 0) {
ragge
1.61
421                         if (setbin(p))
ragge
1.60
422                                 goto again;
423                         goto nomat;
424                 }
ragge
1.65
425                 if (rv & LREG) {
ragge
1.67
426                         if (p->n_left->n_op == UMUL) {
ragge
1.65
427                                 offstar(p->n_left->n_left);
428                                 goto again;
429                         }
ragge
1.60
430                         order(p->n_leftINTAREG|INTBREG);
ragge
1.65
431                 }
ragge
1.50
432 //printf("newstyle ltmp %p\n", p);
ragge
1.65
433                 if (rv & RREG) {
ragge
1.67
434                         if (p->n_right->n_op == UMUL) {
ragge
1.65
435                                 offstar(p->n_right->n_left);
436                                 goto again;
437                         }
ragge
1.60
438                         order(p->n_rightINTAREG|INTBREG);
ragge
1.65
439                 }
ragge
1.50
440 //printf("newstyle rtmp %p\n", p);
ragge
1.49
441                 
442
ragge
1.60
443                 q = &table[rv >> 2];
444                 if (!allo(pq)) {
445                         /*
446                          * Ran out of suitable temp regs.
447                          * Force everything onto stack.
448                          * Be careful to avoid loops.
449                          * XXX - this is bad code!
450                          */
ragge
1.65
451                         if ((rv & LREG) == 0 && istnode(p->n_left)) {
ragge
1.60
452                                 order(p->n_leftINTEMP);
453                                 goto again;
ragge
1.65
454                         } else if (!(rv & RREG) &&istnode(p->n_right)) {
ragge
1.60
455                                 order(p->n_rightINTEMP);
456                                 goto again;
ragge
1.54
457                         }
ragge
1.60
458                         cerror("allo failed");
459                 }
460                 expand(pmq->cstring);
461                 reclaim(pq->rewritem);
ragge
1.50
462 //printf("newstyle ute %p\n", p);
ragge
1.49
463                 goto cleanup;
464
ragge
1.57
465                 /*
466                  * For now just be sure that the trees on each side
467                  * are adressable.
468                  */
469         case EQ:
470         case NE:
471         case LE:
472         case LT:
473         case GE:
474         case GT:
475         case ULE:
476         case ULT:
477         case UGE:
478         case UGT:
ragge
1.60
479
ragge
1.57
480                 if (!canaddr(p->n_left)) {
ragge
1.67
481                         if (p->n_left->n_op == UMUL) {
ragge
1.57
482                                 offstar(p->n_left->n_left);
483                                 goto again;
484                         }
ragge
1.60
485                         order(p->n_leftINTAREG|INTBREG|INAREG|INBREG);
ragge
1.57
486                 }
487                 if (!canaddr(p->n_right)) {
ragge
1.67
488                         if (p->n_right->n_op == UMUL) {
ragge
1.57
489                                 offstar(p->n_right->n_left);
490                                 goto again;
491                         }
ragge
1.60
492                         order(p->n_rightINTAREG|INTBREG|INAREG|INBREG);
ragge
1.57
493                 }
494                 rv = relops(p);
495                 m = FORCC;
496                 goto foo;
497
ragge
1.1
498         default:
499                 /* look for op in table */
ragge
1.8
500                 for (;;) {
501                         if ((m = match(pcookie)) == MDONE)
502                                 goto cleanup;
503                         else if (m == MNOPE) {
504                                 if (!(cookie = nextcook(pcookie)))
505                                         goto nomat;
ragge
1.1
506                                 continue;
ragge
1.8
507                         } else
508                                 break;
509                 }
ragge
1.1
510                 break;
511
512         case FORCE:
513         case CBRANCH:
ragge
1.68
514         case UCALL:
ragge
1.1
515         case CALL:
ragge
1.68
516         case USTCALL:
ragge
1.1
517         case STCALL:
ragge
1.68
518         case UFORTCALL:
ragge
1.1
519         case FORTCALL:
520                 /* don't even go near the table... */
521                 ;
522
ragge
1.8
523         }
ragge
1.25
524         /*
ragge
1.8
525          * get here to do rewriting if no match or
526          * fall through from above for hard ops
527          */
ragge
1.1
528
ragge
1.13
529         p1 = p->n_left;
ragge
1.8
530         if (ty == BITYPE)
ragge
1.13
531                 p2 = p->n_right;
ragge
1.8
532         else
533                 p2 = NIL;
ragge
1.1
534         
ragge
1.30
535 #ifdef PCC_DEBUG
ragge
1.8
536         if (odebug) {
537                 printf("order(%p, "p);
538                 prcook(cook);
539                 printf("), cookie ");
540                 prcook(cookie);
541                 printf(", rewrite %s\n"opst[m]);
542         }
ragge
1.30
543 #endif
ragge
1.8
544         switch (m) {
ragge
1.1
545         default:
546                 nomat:
ragge
1.13
547                 cerror"no table entry for op %s"opst[p->n_op] );
ragge
1.1
548
549         case FORCE:
550                 cook = INTAREG|INTBREG;
ragge
1.19
551                 order(p->n_leftcook);
552                 reclaim(pRLEFTcook);
ragge
1.38
553                 return;
ragge
1.1
554
555         case CBRANCH:
ragge
1.36
556                 p1->n_label = p2->n_lval;
ragge
1.42
557                 o = p1->n_op;
ragge
1.36
558                 codgen(p1FORCC);
ragge
1.42
559                 cbgen(op2->n_lval);
ragge
1.36
560                 reclaim(p1RNULL0);
ragge
1.19
561                 nfree(p2);
562                 nfree(p);
ragge
1.1
563                 return;
564
565         case FLD:       /* fields of funny type */
ragge
1.67
566                 if ( p1->n_op == UMUL ){
ragge
1.13
567                         offstarp1->n_left );
ragge
1.1
568                         goto again;
569                         }
570
ragge
1.67
571         case UMINUS:
ragge
1.30
572                 orderp1INBREG|INAREG);
ragge
1.1
573                 goto again;
574
575         case NAME:
576                 /* all leaves end up here ... */
577                 ifo == REG ) goto nomat;
578                 orderpINTAREG|INTBREG );
579                 goto again;
580
581         case INIT:
ragge
1.12
582                 uerror("init: illegal initialization");
ragge
1.1
583                 return;
584
ragge
1.68
585         case UFORTCALL:
ragge
1.13
586                 p->n_right = NIL;
ragge
1.1
587         case FORTCALL:
ragge
1.68
588                 o = p->n_op = UFORTCALL;
ragge
1.1
589                 ifgenfcallpcookie ) ) goto nomat;
590                 goto cleanup;
591
ragge
1.68
592         case UCALL:
ragge
1.13
593                 p->n_right = NIL;
ragge
1.1
594         case CALL:
ragge
1.68
595                 o = p->n_op = UCALL;
ragge
1.1
596                 ifgencallpcookie ) ) goto nomat;
597                 goto cleanup;
598
ragge
1.68
599         case USTCALL:
ragge
1.13
600                 p->n_right = NIL;
ragge
1.1
601         case STCALL:
ragge
1.68
602                 o = p->n_op = USTCALL;
ragge
1.1
603                 ifgenscallpcookie ) ) goto nomat;
604                 goto cleanup;
605
606                 /* if arguments are passed in register, care must be taken that reclaim
ragge
1.2
607                  * not throw away the register which now has the result... */
ragge
1.1
608
ragge
1.67
609         case UMUL:
ragge
1.1
610                 ifcook == FOREFF ){
611                         /* do nothing */
ragge
1.13
612                         orderp->n_leftFOREFF );
ragge
1.19
613                         nfree(p);
ragge
1.1
614                         return;
ragge
1.19
615                 }
ragge
1.30
616                 offstarp->n_left );
617 #if 0
618                 canon(p);
619                 ifcanaddr(p) && cook != INTEMP )
620                         goto cleanup;
ragge
1.1
621 #endif
622                 goto again;
623
624         case INCR:  /* INCR and DECR */
625                 ifsetincr(p) ) goto again;
626
ragge
1.49
627                 /* x++ becomes (x = x + 1) -1; */
ragge
1.1
628
629                 p1 = tcopy(p);
ragge
1.49
630                 if (cook & FOREFF) {
631                         nfree(p->n_right);
632                         p->n_right = p1;
ragge
1.50
633                         p1->n_op = (p->n_op == INCR) ? PLUSMINUS;
ragge
1.49
634                         p->n_op = ASSIGN;
635                 } else {
636                         p2 = talloc();
637                         p2->n_rall = NOPREF;
638                         p2->n_name = "";
639                         p2->n_op = ASSIGN;
640                         p2->n_type = p->n_type;
641                         p2->n_left = p->n_left;
642                         p2->n_right = p1;
643                         p1->n_op = (p->n_op == INCR) ? PLUSMINUS;
644                         p->n_op = (p->n_op == INCR) ? MINUS : PLUS;
ragge
1.50
645                         p->n_left = p2;
ragge
1.49
646                 }
ragge
1.1
647                 goto again;
648
649         case STASG:
650                 ifsetstrp ) ) goto again;
651                 goto nomat;
652
653         case ASSIGN:
ragge
1.8
654                 if (setasg(p))
655                         goto again;
ragge
1.1
656                 goto nomat;
657
658         case BITYPE:
659                 ifsetbinp ) ) goto again;
660                 goto nomat;
661
662                 }
663
664         cleanup:
665
666         /* if it is not yet in the right state, put it there */
667
668         ifcook & FOREFF ){
669                 reclaimpRNULL0 );
670                 return;
671                 }
672
ragge
1.13
673         ifp->n_op==FREE ) return;
ragge
1.1
674
675         iftshapepcook ) ) return;
676
677         if( (m=match(p,cook) ) == MDONE ) return;
678
679         /* we are in bad shape, try one last chance */
ragge
1.8
680         if (lastchance(pcook))
681                 goto again;
ragge
1.1
682
683         goto nomat;
ragge
1.8
684 }
ragge
1.1
685
686 int callflag;
687 int fregs;
688
ragge
1.2
689 void
690 storep ) NODE *p; {
ragge
1.1
691
692         /* find a subtree of p which should be stored */
693
ragge
1.2
694         int oty;
ragge
1.1
695
ragge
1.13
696         o = p->n_op;
ragge
1.1
697         ty = optype(o);
698
699         ifty == LTYPE ) return;
700
701         switcho ){
702
ragge
1.68
703         case UCALL:
704         case UFORTCALL:
705         case USTCALL:
ragge
1.1
706                 ++callflag;
707                 break;
708
ragge
1.67
709         case UMUL:
ragge
1.13
710                 if (asgop(p->n_left->n_op))
ragge
1.67
711                         stoasg(p->n_leftUMUL);
ragge
1.1
712                 break;
713
714         case CALL:
715         case FORTCALL:
716         case STCALL:
ragge
1.13
717                 storep->n_left );
718                 stoargp->n_righto );
ragge
1.1
719                 ++callflag;
720                 return;
721
722                 }
723
ragge
1.11
724         if (ty == UTYPE) {
ragge
1.13
725                 store(p->n_left);
ragge
1.1
726                 return;
ragge
1.11
727         }
ragge
1.1
728
ragge
1.13
729         if (asgop(p->n_right->n_op))
730                 stoasg(p->n_righto);
ragge
1.1
731
ragge
1.13
732         ifp->n_su>fregs ){ /* must store */
ragge
1.1
733                 mkadrsp );  /* set up stotree and stocook to subtree
734                                  that must be stored */
735                 }
736
ragge
1.13
737         storep->n_right );
738         storep->n_left );
ragge
1.1
739         }
740
ragge
1.2
741 /* mark off calls below the current node */
742 void
743 markcall(NODE *p)
744 {
ragge
1.1
745
746         again:
ragge
1.13
747         switchp->n_op ){
ragge
1.1
748
ragge
1.68
749         case UCALL:
750         case USTCALL:
751         case UFORTCALL:
ragge
1.1
752         case CALL:
753         case STCALL:
754         case FORTCALL:
755                 ++callflag;
756                 return;
757
758                 }
759
ragge
1.13
760         switchoptypep->n_op ) ){
ragge
1.1
761
762         case BITYPE:
ragge
1.13
763                 markcallp->n_right );
ragge
1.1
764         case UTYPE:
ragge
1.13
765                 p = p->n_left;
ragge
1.1
766                 /* eliminate recursion (aren't I clever...) */
767                 goto again;
768         case LTYPE:
769                 return;
770                 }
771
ragge
1.2
772 }
ragge
1.1
773
ragge
1.2
774 void
775 stoarg(NODE *pint calltype)
776 {
ragge
1.1
777         /* arrange to store the args */
ragge
1.13
778         ifp->n_op == CM ){
779                 stoargp->n_leftcalltype );
780                 p = p->n_right ;
ragge
1.1
781                 }
782         ifcalltype == CALL ){
783                 STOARG(p);
784                 }
785         else ifcalltype == STCALL ){
786                 STOSTARG(p);
787                 }
788         else {
789                 STOFARG(p);
790                 }
791         callflag = 0;
792         store(p);
ragge
1.30
793 #ifdef NO_NESTCALLS
ragge
1.1
794         ifcallflag ){ /* prevent two calls from being active at once  */
795                 SETSTO(p,INTEMP);
796                 store(p); /* do again to preserve bottom up nature....  */
ragge
1.2
797         }
ragge
1.1
798 #endif
ragge
1.2
799 }
ragge
1.1
800
801 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
802
ragge
1.2
803 void
804 rcount()
805 /* count recursions */
ragge
1.1
806         if( ++nrecur > NRECUR ){
807                 cerror"expression causes compiler loop: try simplifying" );
808         }
ragge
1.2
809 }
ragge
1.1
810
ragge
1.30
811 #ifdef PCC_DEBUG
ragge
1.2
812 int
ragge
1.8
813 e2print(NODE *pint downint *aint *b)
ragge
1.2
814 {
ragge
1.1
815
816         *a = *b = down+1;
817         whiledown >= 2 ){
818                 printf"\t" );
819                 down -= 2;
820                 }
821         ifdown-- ) printf"    " );
822
823
ragge
1.13
824         printf"%p) %s"popst[p->n_op] );
825         switchp->n_op ) { /* special cases */
ragge
1.1
826
827         case REG:
ragge
1.13
828                 printf" %s"rnames[p->n_rval] );
ragge
1.1
829                 break;
830
ragge
1.23
831         case TEMP:
832                 printf(" %d", (int)p->n_lval);
833                 break;
834
ragge
1.1
835         case ICON:
836         case NAME:
837         case OREG:
838                 printf" " );
839                 adrputp );
840                 break;
841
842         case STCALL:
ragge
1.68
843         case USTCALL:
ragge
1.1
844         case STARG:
845         case STASG:
ragge
1.13
846                 printf" size=%d"p->n_stsize );
847                 printf" align=%d"p->n_stalign );
ragge
1.1
848                 break;
849                 }
850
851         printf", " );
ragge
1.33
852         tprintp->n_typep->n_qual);
ragge
1.1
853         printf", " );
ragge
1.13
854         ifp->n_rall == NOPREF ) printf"NOPREF" );
ragge
1.1
855         else {
ragge
1.13
856                 ifp->n_rall & MUSTDO ) printf"MUSTDO " );
ragge
1.1
857                 else printf"PREF " );
ragge
1.13
858                 printf"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
859                 }
ragge
1.13
860         printf", SU= %d\n"p->n_su );
ragge
1.2
861         return 0;
862 }
ragge
1.30
863 #endif
ragge
1.1
864
865 #ifndef FIELDOPS
ragge
1.7
866 /*
867  * do this if there is no special hardware support for fields
868  */
869 static int
870 ffld(NODE *pint downint *down1int *down2 )
871 {
872         /*
873          * look for fields that are not in an lvalue context,
874          * and rewrite them...
875          */
876         NODE *shp;
877         int sovty;
ragge
1.1
878
ragge
1.13
879         *down1 =  asgopp->n_op );
ragge
1.1
880         *down2 = 0;
881
ragge
1.13
882         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
883
ragge
1.7
884                 if( !rewfld(p) ) return 0;
ragge
1.1
885
ragge
1.48
886                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
887                 v = p->n_rval;
ragge
1.1
888                 s = UPKFSZ(v);
889 # ifdef RTOLBYTES
890                 o = UPKFOFF(v);  /* amount to shift */
891 # else
ragge
1.13
892                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
893 #endif
894
895                 /* make & mask part */
896
ragge
1.13
897                 p->n_left->n_type = ty;
ragge
1.1
898
ragge
1.13
899                 p->n_op = AND;
900                 p->n_right = talloc();
901                 p->n_right->n_op = ICON;
902                 p->n_right->n_rall = NOPREF;
903                 p->n_right->n_type = ty;
904                 p->n_right->n_lval = 1;
905                 p->n_right->n_rval = 0;
906                 p->n_right->n_name = "";
907                 p->n_right->n_lval <<= s;
908                 p->n_right->n_lval--;
ragge
1.1
909