Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030912133056

Diff

Diff from 1.65 to:

Annotations

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

Annotated File View

ragge
1.65
1 /*      $Id: reader.c,v 1.65 2003/09/12 13:30:56 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:
130         case UNARY CALL:
131         case STCALL:
132         case UNARY STCALL:
133         case FORTCALL:
134         case UNARY FORTCALL:
135         case CBRANCH:
136                 /* for the moment, don7t delay past a conditional context, or
137                  * inside of a call */
138                 return;
139
140         case UNARY MUL:
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)) {
348                         if (p->n_left->n_op == UNARY MUL) {
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)) {
357                         if (p->n_right->n_op == UNARY MUL) {
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)) {
399                         if (p->n_left->n_op == UNARY MUL) {
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)) {
407                         if (p->n_right->n_op == UNARY MUL) {
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) {
426                         if (p->n_left->n_op == UNARY MUL) {
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) {
434                         if (p->n_right->n_op == UNARY MUL) {
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)) {
481                         if (p->n_left->n_op == UNARY MUL) {
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)) {
488                         if (p->n_right->n_op == UNARY MUL) {
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:
514         case UNARY CALL:
515         case CALL:
516         case UNARY STCALL:
517         case STCALL:
518         case UNARY FORTCALL:
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.13
566                 if ( p1->n_op == UNARY MUL ){
567                         offstarp1->n_left );
ragge
1.1
568                         goto again;
569                         }
570
571         case UNARY MINUS:
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
585         case UNARY FORTCALL:
ragge
1.13
586                 p->n_right = NIL;
ragge
1.1
587         case FORTCALL:
ragge
1.13
588                 o = p->n_op = UNARY FORTCALL;
ragge
1.1
589                 ifgenfcallpcookie ) ) goto nomat;
590                 goto cleanup;
591
592         case UNARY CALL:
ragge
1.13
593                 p->n_right = NIL;
ragge
1.1
594         case CALL:
ragge
1.13
595                 o = p->n_op = UNARY CALL;
ragge
1.1
596                 ifgencallpcookie ) ) goto nomat;
597                 goto cleanup;
598
599         case UNARY STCALL:
ragge
1.13
600                 p->n_right = NIL;
ragge
1.1
601         case STCALL:
ragge
1.13
602                 o = p->n_op = UNARY STCALL;
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
609         case UNARY MUL:
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
703         case UNARY CALL:
704         case UNARY FORTCALL:
705         case UNARY STCALL:
706                 ++callflag;
707                 break;
708
709         case UNARY MUL:
ragge
1.13
710                 if (asgop(p->n_left->n_op))
711                         stoasg(p->n_leftUNARY MUL);
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         case CBRANCH:   /* to prevent complicated expressions on the LHS from being stored */
ragge
1.13
723                 constorep->n_left );
ragge
1.1
724                 return;
725
726                 }
727
ragge
1.11
728         if (ty == UTYPE) {
ragge
1.13
729                 store(p->n_left);
ragge
1.1
730                 return;
ragge
1.11
731         }
ragge
1.1
732
ragge
1.13
733         if (asgop(p->n_right->n_op))
734                 stoasg(p->n_righto);
ragge
1.1
735
ragge
1.13
736         ifp->n_su>fregs ){ /* must store */
ragge
1.1
737                 mkadrsp );  /* set up stotree and stocook to subtree
738                                  that must be stored */
739                 }
740
ragge
1.13
741         storep->n_right );
742         storep->n_left );
ragge
1.1
743         }
744
ragge
1.2
745 /*
746  * store conditional expressions
747  * the point is, avoid storing expressions in conditional
748  * conditional context, since the evaluation order is predetermined
749  */
750 void
751 constore(NODE *p)
752 {
ragge
1.1
753         storep );
ragge
1.2
754 }
ragge
1.1
755
ragge
1.2
756 /* mark off calls below the current node */
757 void
758 markcall(NODE *p)
759 {
ragge
1.1
760
761         again:
ragge
1.13
762         switchp->n_op ){
ragge
1.1
763
764         case UNARY CALL:
765         case UNARY STCALL:
766         case UNARY FORTCALL:
767         case CALL:
768         case STCALL:
769         case FORTCALL:
770                 ++callflag;
771                 return;
772
773                 }
774
ragge
1.13
775         switchoptypep->n_op ) ){
ragge
1.1
776
777         case BITYPE:
ragge
1.13
778                 markcallp->n_right );
ragge
1.1
779         case UTYPE:
ragge
1.13
780                 p = p->n_left;
ragge
1.1
781                 /* eliminate recursion (aren't I clever...) */
782                 goto again;
783         case LTYPE:
784                 return;
785                 }
786
ragge
1.2
787 }
ragge
1.1
788
ragge
1.2
789 void
790 stoarg(NODE *pint calltype)
791 {
ragge
1.1
792         /* arrange to store the args */
ragge
1.13
793         ifp->n_op == CM ){
794                 stoargp->n_leftcalltype );
795                 p = p->n_right ;
ragge
1.1
796                 }
797         ifcalltype == CALL ){
798                 STOARG(p);
799                 }
800         else ifcalltype == STCALL ){
801                 STOSTARG(p);
802                 }
803         else {
804                 STOFARG(p);
805                 }
806         callflag = 0;
807         store(p);
ragge
1.30
808 #ifdef NO_NESTCALLS
ragge
1.1
809         ifcallflag ){ /* prevent two calls from being active at once  */
810                 SETSTO(p,INTEMP);
811                 store(p); /* do again to preserve bottom up nature....  */
ragge
1.2
812         }
ragge
1.1
813 #endif
ragge
1.2
814 }
ragge
1.1
815
816 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
817
ragge
1.2
818 void
819 rcount()
820 /* count recursions */
ragge
1.1
821         if( ++nrecur > NRECUR ){
822                 cerror"expression causes compiler loop: try simplifying" );
823         }
ragge
1.2
824 }
ragge
1.1
825
ragge
1.30
826 #ifdef PCC_DEBUG
ragge
1.2
827 int
ragge
1.8
828 e2print(NODE *pint downint *aint *b)
ragge
1.2
829 {
ragge
1.1
830
831         *a = *b = down+1;
832         whiledown >= 2 ){
833                 printf"\t" );
834                 down -= 2;
835                 }
836         ifdown-- ) printf"    " );
837
838
ragge
1.13
839         printf"%p) %s"popst[p->n_op] );
840         switchp->n_op ) { /* special cases */
ragge
1.1
841
842         case REG:
ragge
1.13
843                 printf" %s"rnames[p->n_rval] );
ragge
1.1
844                 break;
845
ragge
1.23
846         case TEMP:
847                 printf(" %d", (int)p->n_lval);
848                 break;
849
ragge
1.1
850         case ICON:
851         case NAME:
852         case OREG:
853                 printf" " );
854                 adrputp );
855                 break;
856
857         case STCALL:
858         case UNARY STCALL:
859         case STARG:
860         case STASG:
ragge
1.13
861                 printf" size=%d"p->n_stsize );
862                 printf" align=%d"p->n_stalign );
ragge
1.1
863                 break;
864                 }
865
866         printf", " );
ragge
1.33
867         tprintp->n_typep->n_qual);
ragge
1.1
868         printf", " );
ragge
1.13
869         ifp->n_rall == NOPREF ) printf"NOPREF" );
ragge
1.1
870         else {
ragge
1.13
871                 ifp->n_rall & MUSTDO ) printf"MUSTDO " );
ragge
1.1
872                 else printf"PREF " );
ragge
1.13
873                 printf"%s"rnames[p->n_rall&~MUSTDO]);
ragge
1.1
874                 }
ragge
1.13
875         printf", SU= %d\n"p->n_su );
ragge
1.2
876         return 0;
877 }
ragge
1.30
878 #endif
ragge
1.1
879
880 #ifndef FIELDOPS
ragge
1.7
881 /*
882  * do this if there is no special hardware support for fields
883  */
884 static int
885 ffld(NODE *pint downint *down1int *down2 )
886 {
887         /*
888          * look for fields that are not in an lvalue context,
889          * and rewrite them...
890          */
891         NODE *shp;
892         int sovty;
ragge
1.1
893
ragge
1.13
894         *down1 =  asgopp->n_op );
ragge
1.1
895         *down2 = 0;
896
ragge
1.13
897         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
898
ragge
1.7
899                 if( !rewfld(p) ) return 0;
ragge
1.1
900
ragge
1.48
901                 ty = (szty(p->n_type) == 2)? LONGINT/* XXXX */
ragge
1.13
902                 v = p->n_rval;
ragge
1.1
903                 s = UPKFSZ(v);
904 # ifdef RTOLBYTES
905                 o = UPKFOFF(v);  /* amount to shift */
906 # else
ragge
1.13
907                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
908 #endif
909
910                 /* make & mask part */
911
ragge
1.13
912                 p->n_left->n_type = ty;
ragge
1.1
913
ragge
1.13
914                 p->n_op = AND;
915                 p->n_right = talloc();
916                 p->n_right->n_op = ICON;
917                 p->n_right->n_rall = NOPREF;
918                 p->n_right->n_type = ty;
919                 p->n_right->n_lval = 1;
920                 p->n_right->n_rval = 0;
921                 p->n_right->n_name = "";
922                 p->n_right->n_lval <<= s;
923                 p->n_right->n_lval--;
ragge
1.1
924
925                 /* now, if a shift is needed, do it */
926
927                 ifo != 0 ){
928                         shp = talloc();
ragge
1.13
929                         shp->n_op = RS;
930                         shp->n_rall = NOPREF;
931                         shp->n_type = ty;
932                         shp->n_left = p->n_left;
933                         shp->n_right = talloc();
934                         shp->n_right->n_op = ICON;
935                         shp->n_right->n_rall = NOPREF;
936               &nb