Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20071023183825

Diff

Diff from 1.206 to:

Annotations

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

Annotated File View

ragge
1.206
1 /*      $Id: reader.c,v 1.206 2007/10/23 18:38:25 ragge Exp $   */
ragge
1.72
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
ragge
1.31
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
ragge
1.1
62
ragge
1.123
63 /*
ragge
1.174
64  * Everything is entered via pass2_compile().  Three functions are 
65  * allowed to recurse into pass2_compile(), so be careful:
66  * - deluseless()
ragge
1.123
67  * - myreader()
ragge
1.174
68  * Especially in myreader note that trees may be rewritten twice if
69  * things are not carefully handled.
ragge
1.123
70  */
71
ragge
1.1
72 # include "pass2.h"
73
ragge
1.70
74 #include <string.h>
ragge
1.71
75 #include <stdarg.h>
ragge
1.94
76 #include <stdlib.h>
ragge
1.70
77
ragge
1.1
78 /*      some storage declarations */
79 int nrecur;
80 int lflag;
ragge
1.9
81 int x2debug;
ragge
1.1
82 int udebug = 0;
ragge
1.103
83 int thisline;
ragge
1.72
84 int fregs;
ragge
1.123
85 int p2autooffp2maxautooff;
ragge
1.1
86
ragge
1.72
87 NODE *nodepole;
ragge
1.197
88 FILE *prfil;
ragge
1.201
89 static struct interpass prepole;
ragge
1.23
90
ragge
1.37
91 void saveip(struct interpass *ip);
92 void deljumps(void);
ragge
1.40
93 void deltemp(NODE *p);
ragge
1.97
94 void mkhardops(NODE *p);
ragge
1.37
95 void optdump(struct interpass *ip);
ragge
1.40
96 void cvtemps(struct interpass *epil);
ragge
1.72
97 NODE *store(NODE *);
ragge
1.104
98 void rcount(void);
ragge
1.124
99 void compile2(struct interpass *ip);
100 void compile3(struct interpass *ip);
101 void compile4(struct interpass *ip);
ragge
1.65
102
ragge
1.72
103 static void gencode(NODE *pint cookie);
ragge
1.69
104
ragge
1.150
105 char *ltyp[] = { """LREG""LOREG""LTEMP" };
106 char *rtyp[] = { """RREG""ROREG""RTEMP" };
ragge
1.37
107
ragge
1.121
108 /* used when removing nodes */
109 struct tmpsave {
110         struct tmpsave *next;
111         CONSZ tempaddr;
112         int tempno;
113 } *tmpsave;
114
ragge
1.26
115 #ifdef PCC_DEBUG
116 static void
117 cktree(NODE *p)
118 {
119         if (p->n_op > MAXOP)
120                 cerror("op %d slipped through"p->n_op);
ragge
1.199
121         if (BTYPE(p->n_type) > MAXTYPES)
122                 cerror("type %x slipped through"p->n_type);
ragge
1.35
123         if (p->n_op == CBRANCH && !logop(p->n_left->n_op))
124                 cerror("not logop branch");
ragge
1.47
125         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
126                 cerror("asgop %d slipped through"p->n_op);
ragge
1.26
127 }
128 #endif
ragge
1.8
129
ragge
1.130
130 /*
ragge
1.89
131  * Check if a node has side effects.
132  */
133 static int
134 isuseless(NODE *n)
135 {
136         switch (n->n_op) {
137         case FUNARG:
138         case UCALL:
139         case UFORTCALL:
140         case FORCE:
ragge
1.198
141 /*      case INIT: */
ragge
1.89
142         case ASSIGN:
143         case CALL:
144         case FORTCALL:
145         case CBRANCH:
146         case RETURN:
147         case GOTO:
148         case STCALL:
149         case USTCALL:
150         case STASG:
151         case STARG:
152                 return 0;
153         default:
154                 return 1;
155         }
156 }
157
ragge
1.130
158 /*
159  * Delete statements with no meaning (like a+b; or 513.4;)
160  */
ragge
1.89
161 static NODE *
162 deluseless(NODE *p)
163 {
164         struct interpass *ip;
165         NODE *l, *r;
166
167         if (optype(p->n_op) == LTYPE) {
168                 nfree(p);
169                 return NULL;
170         }
171         if (isuseless(p) == 0)
172                 return p;
173
174         if (optype(p->n_op) == UTYPE) {
175                 l = p->n_left;
176                 nfree(p);
177                 return deluseless(l);
178         }
179
180         /* Be sure that both leaves may be valid */
181         l = deluseless(p->n_left);
182         r = deluseless(p->n_right);
183         nfree(p);
184         if (l && r) {
ragge
1.201
185                 ip = ipnode(l);
186                 DLIST_INSERT_AFTER(&prepoleipqelem);
ragge
1.89
187                 return r;
188         } else if (l)
189                 return l;
190         else if (r)
191                 return r;
192         return NULL;
193 }
194
ragge
1.172
195 static struct interpass ipole;
ragge
1.174
196 struct interpass_prolog *ipp, *epp;
ragge
1.172
197
198 /*
199  * Receives interpass structs from pass1.
200  */
201 void
202 pass2_compile(struct interpass *ip)
203 {
204         if (ip->type == IP_PROLOG) {
205                 tmpsave = NULL;
ragge
1.174
206                 ipp = (struct interpass_prolog *)ip;
ragge
1.172
207                 DLIST_INIT(&ipoleqelem);
208         }
209         DLIST_INSERT_BEFORE(&ipoleipqelem);
210         if (ip->type != IP_EPILOG)
211                 return;
212
213 #ifdef PCC_DEBUG
214         if (e2debug) {
215                 printf("Entering pass2\n");
216                 printip(&ipole);
217         }
218 #endif
ragge
1.174
219
ragge
1.172
220         epp = (struct interpass_prolog *)DLIST_PREV(&ipoleqelem);
221         p2maxautooff = p2autooff = epp->ipp_autos;
ragge
1.174
222
223         myreader(&ipole); /* local massage of input */
224
ragge
1.172
225         DLIST_FOREACH(ip, &ipoleqelem) {
226                 if (ip->type != IP_NODE)
227                         continue;
228                 if (xtemps == 0)
229                         walkf(ip->ip_nodedeltemp);
230         }
ragge
1.201
231         DLIST_INIT(&prepoleqelem);
ragge
1.172
232         DLIST_FOREACH(ip, &ipoleqelem) {
233                 if (ip->type != IP_NODE)
234                         continue;
235                 canon(ip->ip_node);
236                 walkf(ip->ip_nodecktree);
ragge
1.201
237                 if ((ip->ip_node = deluseless(ip->ip_node)) == NULL) {
ragge
1.172
238                         DLIST_REMOVE(ipqelem);
ragge
1.201
239                 } else while (!DLIST_ISEMPTY(&prepoleqelem)) {
240                         struct interpass *ipp;
241
242                         ipp = DLIST_NEXT(&prepoleqelem);
243                         DLIST_REMOVE(ippqelem);
244                         DLIST_INSERT_BEFORE(ipippqelem);
245                 }
ragge
1.172
246         }
247
248         optimize(&ipole);
249         ngenregs(&ipole);
250
251         DLIST_FOREACH(ip, &ipoleqelem)
252                 emit(ip);
253 }
254
ragge
1.124
255 void
ragge
1.125
256 emit(struct interpass *ip)
ragge
1.124
257 {
258         NODE *p;
ragge
1.149
259         int o;
ragge
1.124
260
ragge
1.125
261         switch (ip->type) {
262         case IP_NODE:
263                 p = ip->ip_node;
ragge
1.124
264
ragge
1.149
265                 nodepole = p;
ragge
1.180
266 //printf("bu:\n");
267 //fwalk(p, e2print, 0);
268                 canon(p); /* may convert stuff after genregs */
269 //fwalk(p, e2print, 0);
ragge
1.124
270                 switch (p->n_op) {
271                 case CBRANCH:
272                         /* Only emit branch insn if RESCC */
273                         if (table[TBLIDX(p->n_left->n_su)].rewrite & RESCC) {
274                                 o = p->n_left->n_op;
275                                 gencode(pFORCC);
276                                 cbgen(op->n_right->n_lval);
277                         } else
278                                 gencode(pFORCC);
279                         break;
280                 case FORCE:
ragge
1.151
281                         gencode(p->n_leftINREGS);
ragge
1.124
282                         break;
283                 default:
284                         if (p->n_op != REG || p->n_type != VOID/* XXX */
285                                 gencode(pFOREFF); /* Emit instructions */
286                 }
287
ragge
1.125
288                 tfree(p);
289                 break;
ragge
1.124
290         case IP_PROLOG:
291                 prologue((struct interpass_prolog *)ip);
292                 break;
293         case IP_EPILOG:
294                 eoftn((struct interpass_prolog *)ip);
295                 tmpsave = NULL/* Always forget old nodes */
ragge
1.174
296                 p2maxautooff = p2autooff = AUTOINIT/SZCHAR;
ragge
1.124
297                 break;
298         case IP_DEFLAB:
299                 deflab(ip->ip_lbl);
300                 break;
301         case IP_ASM:
302                 printf("\t%s\n"ip->ip_asm);
303                 break;
304         default:
305                 cerror("compile4 %d"ip->type);
306         }
ragge
1.123
307 }
ragge
1.124
308
ragge
1.30
309 #ifdef PCC_DEBUG
ragge
1.1
310 char *cnames[] = {
311         "SANY",
312         "SAREG",
313         "SBREG",
ragge
1.153
314         "SCREG",
315         "SDREG",
ragge
1.1
316         "SCC",
317         "SNAME",
318         "SCON",
319         "SFLD",
320         "SOREG",
321         "STARNM",
322         "STARREG",
323         "INTEMP",
324         "FORARG",
325         "SWADD",
326         0,
ragge
1.72
327 };
ragge
1.1
328
ragge
1.2
329 /*
330  * print a nice-looking description of cookie
331  */
ragge
1.70
332 char *
ragge
1.2
333 prcook(int cookie)
334 {
ragge
1.70
335         static char buf[50];
ragge
1.1
336         int iflag;
337
ragge
1.70
338         if (cookie & SPECIAL) {
339                 switch (cookie) {
340                 case SZERO:
341                         return "SZERO";
342                 case SONE:
343                         return "SONE";
344                 case SMONE:
345                         return "SMONE";
346                 default:
ragge
1.200
347                         snprintf(bufsizeof(buf), "SPECIAL+%d"cookie & ~SPECIAL);
ragge
1.70
348                         return buf;
ragge
1.1
349                 }
ragge
1.70
350         }
ragge
1.1
351
352         flag = 0;
ragge
1.70
353         buf[0] = 0;
354         for (i = 0cnames[i]; ++i) {
355                 if (cookie & (1<<i)) {
356                         if (flag)
ragge
1.200
357                                 strlcat(buf"|"sizeof(buf));
ragge
1.1
358                         ++flag;
ragge
1.200
359                         strlcat(bufcnames[i], sizeof(buf));
ragge
1.1
360                 }
ragge
1.70
361         }
362         return buf;
363 }
ragge
1.1
364
ragge
1.30
365 #endif
ragge
1.1
366
367 int odebug = 0;
368
ragge
1.151
369 int
ragge
1.69
370 geninsn(NODE *pint cookie)
371 {
ragge
1.71
372         NODE *p1, *p2;
ragge
1.151
373         int orv = 0;
ragge
1.69
374
375 #ifdef PCC_DEBUG
376         if (odebug) {
ragge
1.70
377                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
378                 fwalk(pe2print0);
379         }
380 #endif
381
382 again:  switch (o = p->n_op) {
ragge
1.71
383         case EQ:
384         case NE:
385         case LE:
386         case LT:
387         case GE:
388         case GT:
389         case ULE:
390         case ULT:
391         case UGE:
392         case UGT:
ragge
1.159
393                 rv = relops(p);
394                 break;
ragge
1.71
395
ragge
1.69
396         case PLUS:
397         case MINUS:
398         case MUL:
399         case DIV:
400         case MOD:
401         case AND:
402         case OR:
403         case ER:
404         case LS:
405         case RS:
ragge
1.151
406                 rv = findops(pcookie);
407                 break;
ragge
1.77
408
ragge
1.69
409         case ASSIGN:
ragge
1.174
410         case STASG:
ragge
1.151
411                 rv = findasg(pcookie);
412                 break;
ragge
1.159
413
ragge
1.178
414         case UMUL/* May turn into an OREG */
ragge
1.179
415                 rv = findumul(pcookie);
416                 break;
417
ragge
1.69
418         case REG:
ragge
1.144
419         case TEMP:
ragge
1.72
420         case NAME:
ragge
1.71
421         case ICON:
ragge
1.69
422         case OREG:
ragge
1.152
423                 rv = findleaf(pcookie);
424                 break;
ragge
1.69
425
ragge
1.172
426         case STCALL:
427         case CALL:
428                 /* CALL arguments are handled special */
429                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
430                         geninsn(p1->n_rightFOREFF);
431                 geninsn(p1FOREFF);
432                 /* FALLTHROUGH */
ragge
1.206
433         case FLD:
ragge
1.86
434         case COMPL:
ragge
1.85
435         case UMINUS:
ragge
1.71
436         case PCONV:
437         case SCONV:
ragge
1.198
438 /*      case INIT: */
ragge
1.70
439         case GOTO:
440         case FUNARG:
ragge
1.172
441         case STARG:
ragge
1.72
442         case UCALL:
ragge
1.103
443         case USTCALL:
ragge
1.155
444                 rv = finduni(pcookie);
445                 break;
ragge
1.69
446
ragge
1.71
447         case CBRANCH:
448                 p1 = p->n_left;
449                 p2 = p->n_right;
450                 p1->n_label = p2->n_lval;
451                 o = p1->n_op;
452                 geninsn(p1FORCC);
ragge
1.187
453                 p->n_su = 0;
ragge
1.71
454                 break;
455
ragge
1.187
456         case FORCE/* XXX needed? */
ragge
1.151
457                 geninsn(p->n_leftINREGS);
ragge
1.187
458                 p->n_su = 0/* su calculations traverse left */
ragge
1.71
459                 break;
460
ragge
1.69
461         default:
ragge
1.174
462                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
463         }
ragge
1.160
464         if (rv == FFAIL)
465                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
466         if (rv == FRETRY)
467                 goto again;
ragge
1.153
468         return rv;
ragge
1.69
469 }
470
ragge
1.72
471 /*
472  * Store a given subtree in a temporary location.
473  * Return an OREG node where it is located.
474  */
475 NODE *
476 store(NODE *p)
ragge
1.2
477 {
ragge
1.130
478         extern struct interpass *storesave;
479         struct interpass *ip;
480         NODE *q, *r;
481         int s;
ragge
1.49
482
ragge
1.130
483         s = BITOOR(freetemp(szty(p->n_type)));
484         q = mklnode(OREGsFPREGp->n_type);
485         r = mklnode(OREGsFPREGp->n_type);
486         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
487
ragge
1.149
488         storesave = ip;
ragge
1.72
489         return r;
ragge
1.8
490 }
ragge
1.1
491
ragge
1.170
492 #ifdef PCC_DEBUG
493 #define CDEBUG(x) if (c2debug) printf x
494 #else
495 #define CDEBUG(x)
496 #endif
497
ragge
1.69
498 /*
ragge
1.188
499  * Do a register-register move if necessary.
500  */
501 static void
502 ckmove(NODE *pNODE *q)
503 {
ragge
1.189
504         if (q->n_op != REG || p->n_reg == -1)
ragge
1.188
505                 return/* no register */
506         if (DECRA(p->n_reg0) == DECRA(q->n_reg0))
507                 return/* no move necessary */
ragge
1.190
508         CDEBUG(("rmove: node %p, %s -> %s\n"prnames[DECRA(q->n_reg0)],
509             rnames[DECRA(p->n_reg0)]));
ragge
1.188
510         rmove(DECRA(q->n_reg0), DECRA(p->n_reg0), p->n_type);
511         q->n_reg = q->n_rval = DECRA(p->n_reg0);
512 }
513
514 /*
515  * Rewrite node to register after instruction emit.
ragge
1.75
516  */
517 static void
ragge
1.160
518 rewrite(NODE *pint rewriteint cookie)
ragge
1.75
519 {
ragge
1.79
520         NODE *l, *r;
521         int o;
522
ragge
1.80
523         l = getlr(p'L');
524         r = getlr(p'R');
ragge
1.79
525         o = p->n_op;
ragge
1.75
526         p->n_op = REG;
ragge
1.76
527         p->n_lval = 0;
ragge
1.95
528         p->n_name = "";
ragge
1.158
529
ragge
1.190
530         if (o == ASSIGN) {
531                 /* special rewrite care */
532                 int reg = DECRA(p->n_reg0);
ragge
1.191
533 #define TL(x) (TBLIDX(x->n_su) || x->n_op == REG)
ragge
1.190
534                 if (p->n_reg == -1)
535                         ;
ragge
1.191
536                 else if (TL(l) && (DECRA(l->n_reg0) == reg))
ragge
1.190
537                         ;
ragge
1.191
538                 else if (TL(r) && (DECRA(r->n_reg0) == reg))
ragge
1.190
539                         ;
ragge
1.191
540                 else if (TL(l))
ragge
1.190
541                         rmove(DECRA(l->n_reg0), regp->n_type);
ragge
1.191
542                 else if (TL(r))
ragge
1.190
543                         rmove(DECRA(r->n_reg0), regp->n_type);
544 #if 0
545                 else
546                         comperr("rewrite");
547 #endif
ragge
1.191
548 #undef TL
ragge
1.190
549         }
ragge
1.79
550         if (optype(o) != LTYPE)
551                 tfree(l);
552         if (optype(o) == BITYPE)
553                 tfree(r);
ragge
1.190
554         if (rewrite == 0)
555                 return;
mickey
1.205
556         CDEBUG(("rewrite: %p, reg %s\n"p,
557             p->n_reg == -1"<none>" : rnames[DECRA(p->n_reg0)]));
ragge
1.187
558         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
559 }
560
ragge
1.69
561 void
ragge
1.72
562 gencode(NODE *pint cookie)
ragge
1.69
563 {
564         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
565         NODE *p1, *l, *r;
ragge
1.190
566         int o = optype(p->n_op);
ragge
1.188
567
568         l = p->n_left;
569         r = p->n_right;
ragge
1.69
570
ragge
1.186
571         if (TBLIDX(p->n_su) == 0) {
572                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
573                         gencode(r0);
ragge
1.185
574                 if (optype(p->n_op) != LTYPE)
ragge
1.188
575                         gencode(l0);
ragge
1.186
576                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
577                         gencode(r0);
ragge
1.185
578                 return;
579         }
ragge
1.69
580
ragge
1.170
581         CDEBUG(("gencode: node %p\n"p));
582
583         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
584                 return/* meaningless move to itself */
ragge
1.175
585
586         if (callop(p->n_op))
587                 lastcall(p); /* last chance before function args */
588         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
589                 /* Print out arguments first */
ragge
1.188
590                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
591                         gencode(p1->n_rightFOREFF);
592                 gencode(p1FOREFF);
ragge
1.190
593                 o = UTYPE/* avoid going down again */
ragge
1.175
594         }
595
ragge
1.190
596         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
597                 gencode(rINREGS);
598                 if (q->rewrite & RRIGHT)
599                         ckmove(pr);
600         }
ragge
1.190
601         if (o != LTYPE) {
ragge
1.188
602                 gencode(lINREGS);
603                 if (q->rewrite & RLEFT)
604                         ckmove(pl);
605         }
ragge
1.190
606         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
607                 gencode(rINREGS);
608                 if (q->rewrite & RRIGHT)
609                         ckmove(pr);
610         }
ragge
1.185
611
ragge
1.188
612         canon(p);
ragge
1.185
613
ragge
1.188
614         if (q->needs & NSPECIAL) {
615                 int rr = rspecial(qNRIGHT);
616                 int lr = rspecial(qNLEFT);
ragge
1.187
617
ragge
1.188
618                 if (rr >= 0) {
619                         if (r->n_op != REG)
620                                 comperr("gencode: rop != REG");
621                         if (rr != r->n_rval)
622                                 rmove(r->n_rvalrrr->n_type);
623                         r->n_rval = r->n_reg = rr;
624                 }
625                 if (lr >= 0) {
626                         if (l->n_op != REG)
ragge
1.192
627                                 comperr("gencode: %p lop != REG"p);
ragge
1.188
628                         if (lr != l->n_rval)
629                                 rmove(l->n_rvallrl->n_type);
630                         l->n_rval = l->n_reg = lr;
631                 }
632                 if (rr >= 0 && lr >= 0 && (l->n_reg == rr || r->n_reg == lr))
633                         comperr("gencode: cross-reg-move");
634         }
ragge
1.161
635
ragge
1.162
636         if (p->n_op == ASSIGN &&
637             p->n_left->n_op == REG && p->n_right->n_op == REG &&
638             p->n_left->n_rval == p->n_right->n_rval){
ragge
1.161
639                 /* do not emit anything */
ragge
1.170
640                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
641                 rewrite(pq->rewritecookie);
642                 return;
643         }
ragge
1.147
644
ragge
1.170
645         CDEBUG(("emitting node %p\n"p));
ragge
1.190
646         if (TBLIDX(p->n_su) == 0)
ragge
1.173
647                 return;
ragge
1.170
648
ragge
1.72
649         expand(pcookieq->cstring);
ragge
1.169
650         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
651             DECRA(p->n_reg0) != RETREG(p->n_type)) {
652                 CDEBUG(("gencode(%p) retreg\n"p));
653                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
654         } else if (q->needs & NSPECIAL) {
ragge
1.158
655                 int rr = rspecial(qNRES);
ragge
1.150
656
ragge
1.188
657                 if (rr >= 0 && DECRA(p->n_reg0) != rr) {
ragge
1.170
658                         CDEBUG(("gencode(%p) nspec retreg\n"p));
659                         rmove(rrDECRA(p->n_reg0), p->n_type);
660                 }
ragge
1.162
661         } else if ((q->rewrite & RESC1) &&
ragge
1.170
662             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
663                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
664                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.190
665         }
666 #if 0
667                 /* XXX - kolla upp det här */
668            else if (p->n_op == ASSIGN) {
ragge
1.176
669                 /* may need move added if RLEFT/RRIGHT */
670                 /* XXX should be handled in sucomp() */
671                 if ((q->rewrite & RLEFT) && (p->n_left->n_op == REG) &&
672                     (p->n_left->n_rval != DECRA(p->n_reg0)) &&
673                     TCLASS(p->n_su)) {
674                         rmove(p->n_left->n_rvalDECRA(p->n_reg0), p->n_type);
675                 } else if ((q->rewrite & RRIGHT) && (p->n_right->n_op == REG) &&
676                     (p->n_right->n_rval != DECRA(p->n_reg0)) &&
677                     TCLASS(p->n_su)) {
678                         rmove(p->n_right->n_rvalDECRA(p->n_reg0), p->n_type);
679                 }
ragge
1.149
680         }
ragge
1.190
681 #endif
ragge
1.160
682         rewrite(pq->rewritecookie);
ragge
1.2
683 }
ragge
1.1
684
685 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
ragge
1.204
686 size_t negrelsize = sizeof negrel / sizeof negrel[0];
ragge
1.1
687
ragge
1.30
688 #ifdef PCC_DEBUG
ragge
1.87
689 #undef  PRTABLE
ragge
1.174
690 void
ragge
1.8
691 e2print(NODE *pint downint *aint *b)
ragge
1.2
692 {
ragge
1.85
693 #ifdef PRTABLE
694         extern int tablesize;
695 #endif
ragge
1.1
696
ragge
1.197
697         prfil = stdout;
ragge
1.1
698         *a = *b = down+1;
699         whiledown >= 2 ){
ragge
1.148
700                 fprintf(prfil"\t");
ragge
1.1
701                 down -= 2;
702                 }
ragge
1.148
703         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
704
705
ragge
1.148
706         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
707         switchp->n_op ) { /* special cases */
ragge
1.1
708
709         case REG:
ragge
1.148
710                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
711                 break;
712
ragge
1.121
713         case TEMP:
ragge
1.148
714                 fprintf(prfil" " CONFMTp->n_lval);
ragge
1.121
715                 break;
716
ragge
1.1
717         case ICON:
718         case NAME:
719         case OREG:
ragge
1.148
720                 fprintf(prfil" " );
721                 adrput(prfilp );
ragge
1.1
722                 break;
723
724         case STCALL:
ragge
1.68
725         case USTCALL:
ragge
1.1
726         case STARG:
727         case STASG:
ragge
1.148
728                 fprintf(prfil" size=%d"p->n_stsize );
729                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
730                 break;
731                 }
732
ragge
1.148
733         fprintf(prfil", " );
734         tprint(prfilp->n_typep->n_qual);
735         fprintf(prfil", " );
ragge
1.156
736         {
737                 int gregn(struct regw *);
ragge
1.189
738                 if (p->n_reg == -1)
739                         fprintf(prfil"REG <undef>");
740                 else if (p->n_reg < 100000/* XXX */
ragge
1.170
741                         fprintf(prfil"REG %s"rnames[DECRA(p->n_reg0)]);
ragge
1.155
742                 else
ragge
1.156
743                         fprintf(prfil"TEMP %d"gregn(p->n_regw));
ragge
1.1
744                 }
ragge
1.151
745         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s)\n",
ragge
1.85
746             TBLIDX(p->n_su), 
ragge
1.151
747             TCLASS(p->n_su)+'@',
ragge
1.85
748 #ifdef PRTABLE
749             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
750             table[TBLIDX(p->n_su)].cstring : "",
751 #else
752             "",
753 #endif
754             ltyp[LMASK&p->n_su],
ragge
1.70
755             rtyp[(p->n_su&RMASK) >> 2], p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
756 }
ragge
1.30
757 #endif
ragge
1.1
758
759 #ifndef FIELDOPS
ragge
1.7
760 /*
761  * do this if there is no special hardware support for fields
762  */
ragge
1.174
763 static void
ragge
1.7
764 ffld(NODE *pint downint *down1int *down2 )
765 {
766         /*
767          * look for fields that are not in an lvalue context,
768          * and rewrite them...
769          */
770         NODE *shp;
771         int sovty;
ragge
1.1
772
ragge
1.13
773         *down1 =  asgopp->n_op );
ragge
1.1
774         *down2 = 0;
775
ragge
1.13
776         if( !down && p->n_op == FLD ){ /* rewrite the node */
ragge
1.1
777
ragge
1.174
778                 if( !rewfld(p) ) return;
ragge
1.1
779
ragge
1.173
780                 ty = p->n_type;
ragge
1.13
781                 v = p->n_rval;
ragge
1.1
782                 s = UPKFSZ(v);
783 # ifdef RTOLBYTES
784                 o = UPKFOFF(v);  /* amount to shift */
785 # else
ragge
1.13
786                 o = szty(p->n_type)*SZINT - s - UPKFOFF(v);  /* amount to shift */
ragge
1.1
787 #endif
788
789                 /* make & mask part */
790
ragge
1.203
791                 if (ISUNSIGNED(ty)) {
ragge
1.1
792
ragge
1.203
793                         p->n_left->n_type = ty;
794                         p->n_op = AND;
795                         p->n_right = mklnode(ICON, ((CONSZ)1 << s)-10ty);
796
797                         /* now, if a shift is needed, do it */
798                         ifo != 0 ){
799                                 shp = mkbinode(RSp->n_left,
800                                     mklnode(ICONo0INT), ty);
801                                 p->n_left = shp;
802                                 /* whew! */
803                         }
804                 } else {
805                         /* must sign-extend, assume RS will do */
806                         /* if not, arch must use rewfld() */
807                         p->n_left->n_type = INT/* Ok? */
808                         p->n_op = RS;
809                         p->n_right = mklnode(ICONSZINT-s0INT);
810                         p->n_left = mkbinode(LSp->n_left
811                             mklnode(ICONSZINT-s-o0INT), INT);
ragge
1.1
812                 }
813         }
ragge
1.7
814 }
ragge
1.1
815 #endif
816
ragge
1.23
817 /*
818  * change left TEMPs into OREGs
ragge
1.40
819  */
820 void
821 deltemp(NODE *p)
822 {
ragge
1.116
823         struct tmpsave *w;
ragge
1.130
824         NODE *l;
ragge
1.40
825
ragge
1.116
826         if (p->n_op == TEMP) {
827                 /* Check if already existing */
828                 for (w = tmpsaveww = w->next)
829                         if (w->tempno == p->n_lval)
830                                 break;
831                 if (w == NULL) {
832                         /* new on stack */
833                         w = tmpalloc(sizeof(struct tmpsave));
834                         w->tempno = p->n_lval;
835                         w->tempaddr = BITOOR(freetemp(szty(p->n_type)));
836                         w->next = tmpsave;
837                         tmpsave = w;
838                 }
839                 p->n_op = OREG;
840                 p->n_rval = FPREG;
841                 p->n_lval = w->tempaddr;
842         } else if (p->n_op == ADDROF) {
ragge
1.90
843                 /* TEMPs are already converted to OREGs */
844                 if ((l = p->n_left)->n_op != OREG)
845                         comperr("bad U&");
846                 p->n_op = PLUS;
847                 l->n_op = REG;
848                 l->n_type = INCREF(l->n_type);
ragge
1.130
849                 p->n_right = mklnode(ICONl->n_lval0INT);
ragge
1.90
850         }
ragge
1.40
851 }
852
853 /*
ragge
1.48
854  * for pointer/integer arithmetic, set pointer at left node
855  */
856 static void
857 setleft(NODE *p)          
858 {        
859         NODE *q;
860
861         /* only additions for now */
862         if (p->n_op != PLUS)
863                 return;
864         if (ISPTR(p->n_right->n_type) && !ISPTR(p->n_left->n_type)) {
865                 q = p->n_right;
866                 p->n_right = p->n_left;
867                 p->n_left = q;
868         }
869 }
870
ragge
1.180
871 /* It is OK to have these as externals */
872 static int oregr;
873 static CONSZ oregtemp;
874 static char *oregcp;
ragge
1.48
875 /*
ragge
1.23
876  * look for situations where we can turn * into OREG
ragge
1.180
877  * If sharp then do not allow temps.
ragge
1.23
878  */
ragge
1.179
879 int
ragge
1.180
880 oregok(NODE *pint sharp)
ragge
1.2
881 {
ragge
1.1
882
883         NODE *q;
ragge
1.2
884         NODE *ql, *qr;
ragge
1.180
885         int r;
886         CONSZ temp;
887         char *cp;
ragge
1.23
888
ragge
1.179
889         q = p->n_left;
ragge
1.182
890 #if 0
ragge
1.180
891         if ((q->n_op == REG || (q->n_op == TEMP && !sharp)) &&
892             q->n_rval == DECRA(q->n_reg0)) {
ragge
1.182
893 #endif
894         if (q->n_op == REG || (q->n_op == TEMP && !sharp)) {
ragge
1.180
895                 temp = q->n_lval;
896                 r = q->n_rval;
897                 cp = q->n_name;
ragge
1.179
898                 goto ormake;
899         }
ragge