Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030902143721

Diff

Diff from 1.56 to:

Annotations

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

Annotated File View

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