Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030910074652

Diff

Diff from 1.64 to:

Annotations

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

Annotated File View

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