Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20031112164226

Diff

Diff from 1.70 to:

Annotations

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

Annotated File View

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