Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20031113155946

Diff

Diff from 1.71 to:

Annotations

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

Annotated File View

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