Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081025090839

Diff

Diff from 1.240 to:

Annotations

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

Annotated File View

ragge
1.240
1 /*      $Id: reader.c,v 1.240 2008/10/25 09:08:39 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.236
64  * Everything is entered via pass2_compile().  No functions are 
65  * allowed to recurse back into pass2_compile().
ragge
1.123
66  */
67
ragge
1.1
68 # include "pass2.h"
69
ragge
1.70
70 #include <string.h>
ragge
1.71
71 #include <stdarg.h>
ragge
1.94
72 #include <stdlib.h>
ragge
1.70
73
ragge
1.1
74 /*      some storage declarations */
75 int nrecur;
76 int lflag;
ragge
1.9
77 int x2debug;
ragge
1.1
78 int udebug = 0;
ragge
1.103
79 int thisline;
ragge
1.72
80 int fregs;
ragge
1.123
81 int p2autooffp2maxautooff;
ragge
1.1
82
ragge
1.72
83 NODE *nodepole;
ragge
1.197
84 FILE *prfil;
ragge
1.238
85 struct interpass prepole;
ragge
1.23
86
ragge
1.37
87 void saveip(struct interpass *ip);
ragge
1.40
88 void deltemp(NODE *p);
ragge
1.232
89 static void cvtemps(struct interpass *ipoleint opint off);
ragge
1.72
90 NODE *store(NODE *);
ragge
1.216
91 static void fixxasm(struct interpass *ip);
ragge
1.65
92
ragge
1.72
93 static void gencode(NODE *pint cookie);
ragge
1.216
94 static void genxasm(NODE *p);
ragge
1.69
95
ragge
1.121
96 /* used when removing nodes */
97 struct tmpsave {
98         struct tmpsave *next;
99         CONSZ tempaddr;
100         int tempno;
101 } *tmpsave;
102
ragge
1.26
103 #ifdef PCC_DEBUG
104 static void
105 cktree(NODE *p)
106 {
107         if (p->n_op > MAXOP)
ragge
1.218
108                 cerror("%p) op %d slipped through"pp->n_op);
ragge
1.199
109         if (BTYPE(p->n_type) > MAXTYPES)
ragge
1.218
110                 cerror("%p) type %x slipped through"pp->n_type);
ragge
1.35
111         if (p->n_op == CBRANCH && !logop(p->n_left->n_op))
ragge
1.218
112                 cerror("%p) not logop branch"p);
ragge
1.47
113         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
ragge
1.218
114                 cerror("%p) asgop %d slipped through"pp->n_op);
ragge
1.26
115 }
116 #endif
ragge
1.8
117
ragge
1.130
118 /*
ragge
1.89
119  * Check if a node has side effects.
120  */
121 static int
122 isuseless(NODE *n)
123 {
124         switch (n->n_op) {
ragge
1.216
125         case XASM:
ragge
1.89
126         case FUNARG:
127         case UCALL:
128         case UFORTCALL:
129         case FORCE:
130         case ASSIGN:
131         case CALL:
132         case FORTCALL:
133         case CBRANCH:
134         case RETURN:
135         case GOTO:
136         case STCALL:
137         case USTCALL:
138         case STASG:
139         case STARG:
140                 return 0;
141         default:
142                 return 1;
143         }
144 }
145
ragge
1.130
146 /*
147  * Delete statements with no meaning (like a+b; or 513.4;)
148  */
ragge
1.238
149 NODE *
ragge
1.89
150 deluseless(NODE *p)
151 {
152         struct interpass *ip;
153         NODE *l, *r;
154
155         if (optype(p->n_op) == LTYPE) {
156                 nfree(p);
157                 return NULL;
158         }
159         if (isuseless(p) == 0)
160                 return p;
161
162         if (optype(p->n_op) == UTYPE) {
163                 l = p->n_left;
164                 nfree(p);
165                 return deluseless(l);
166         }
167
168         /* Be sure that both leaves may be valid */
169         l = deluseless(p->n_left);
170         r = deluseless(p->n_right);
171         nfree(p);
172         if (l && r) {
ragge
1.201
173                 ip = ipnode(l);
174                 DLIST_INSERT_AFTER(&prepoleipqelem);
ragge
1.89
175                 return r;
176         } else if (l)
177                 return l;
178         else if (r)
179                 return r;
180         return NULL;
181 }
182
ragge
1.172
183 static struct interpass ipole;
ragge
1.174
184 struct interpass_prolog *ipp, *epp;
ragge
1.172
185
186 /*
187  * Receives interpass structs from pass1.
188  */
189 void
190 pass2_compile(struct interpass *ip)
191 {
192         if (ip->type == IP_PROLOG) {
193                 tmpsave = NULL;
ragge
1.174
194                 ipp = (struct interpass_prolog *)ip;
ragge
1.172
195                 DLIST_INIT(&ipoleqelem);
196         }
197         DLIST_INSERT_BEFORE(&ipoleipqelem);
198         if (ip->type != IP_EPILOG)
199                 return;
200
201 #ifdef PCC_DEBUG
202         if (e2debug) {
203                 printf("Entering pass2\n");
204                 printip(&ipole);
205         }
206 #endif
ragge
1.174
207
ragge
1.172
208         epp = (struct interpass_prolog *)DLIST_PREV(&ipoleqelem);
209         p2maxautooff = p2autooff = epp->ipp_autos;
ragge
1.174
210
211         myreader(&ipole); /* local massage of input */
212
ragge
1.172
213         DLIST_FOREACH(ip, &ipoleqelem) {
214                 if (ip->type != IP_NODE)
215                         continue;
216                 if (xtemps == 0)
217                         walkf(ip->ip_nodedeltemp);
218         }
ragge
1.201
219         DLIST_INIT(&prepoleqelem);
ragge
1.172
220         DLIST_FOREACH(ip, &ipoleqelem) {
221                 if (ip->type != IP_NODE)
222                         continue;
223                 canon(ip->ip_node);
gmcgarry
1.220
224 #ifdef PCC_DEBUG
ragge
1.172
225                 walkf(ip->ip_nodecktree);
gmcgarry
1.220
226 #endif
ragge
1.201
227                 if ((ip->ip_node = deluseless(ip->ip_node)) == NULL) {
ragge
1.172
228                         DLIST_REMOVE(ipqelem);
ragge
1.201
229                 } else while (!DLIST_ISEMPTY(&prepoleqelem)) {
gmcgarry
1.224
230                         struct interpass *tipp;
ragge
1.201
231
gmcgarry
1.224
232                         tipp = DLIST_NEXT(&prepoleqelem);
233                         DLIST_REMOVE(tippqelem);
234                         DLIST_INSERT_BEFORE(iptippqelem);
ragge
1.201
235                 }
ragge
1.172
236         }
237
ragge
1.216
238         fixxasm(&ipole); /* setup for extended asm */
239
ragge
1.172
240         optimize(&ipole);
241         ngenregs(&ipole);
242
243         DLIST_FOREACH(ip, &ipoleqelem)
244                 emit(ip);
245 }
246
ragge
1.124
247 void
ragge
1.125
248 emit(struct interpass *ip)
ragge
1.124
249 {
gmcgarry
1.208
250         NODE *p, *r;
251         struct optab *op;
ragge
1.149
252         int o;
ragge
1.124
253
ragge
1.125
254         switch (ip->type) {
255         case IP_NODE:
256                 p = ip->ip_node;
ragge
1.124
257
ragge
1.149
258                 nodepole = p;
ragge
1.180
259                 canon(p); /* may convert stuff after genregs */
ragge
1.240
260                 if (c2debug > 1) {
261                         printf("emit IP_NODE:\n");
262                         fwalk(pe2print0);
263                 }
ragge
1.124
264                 switch (p->n_op) {
265                 case CBRANCH:
266                         /* Only emit branch insn if RESCC */
gmcgarry
1.208
267                         /* careful when an OPLOG has been elided */
268                         if (p->n_left->n_su == 0 && p->n_left->n_left != NULL) {
269                                 op = &table[TBLIDX(p->n_left->n_left->n_su)];
270                                 r = p->n_left;
271                         } else {
272                                 op = &table[TBLIDX(p->n_left->n_su)];
273                                 r = p;
274                         }
275                         if (op->rewrite & RESCC) {
ragge
1.124
276                                 o = p->n_left->n_op;
gmcgarry
1.208
277                                 gencode(rFORCC);
ragge
1.124
278                                 cbgen(op->n_right->n_lval);
gmcgarry
1.208
279                         } else {
280                                 gencode(rFORCC);
281                         }
ragge
1.124
282                         break;
283                 case FORCE:
ragge
1.151
284                         gencode(p->n_leftINREGS);
ragge
1.124
285                         break;
ragge
1.216
286                 case XASM:
287                         genxasm(p);
288                         break;
ragge
1.124
289                 default:
290                         if (p->n_op != REG || p->n_type != VOID/* XXX */
291                                 gencode(pFOREFF); /* Emit instructions */
292                 }
293
ragge
1.125
294                 tfree(p);
295                 break;
ragge
1.124
296         case IP_PROLOG:
297                 prologue((struct interpass_prolog *)ip);
298                 break;
299         case IP_EPILOG:
300                 eoftn((struct interpass_prolog *)ip);
301                 tmpsave = NULL/* Always forget old nodes */
ragge
1.174
302                 p2maxautooff = p2autooff = AUTOINIT/SZCHAR;
ragge
1.124
303                 break;
304         case IP_DEFLAB:
305                 deflab(ip->ip_lbl);
306                 break;
307         case IP_ASM:
gmcgarry
1.229
308                 printf("%s"ip->ip_asm);
ragge
1.124
309                 break;
310         default:
ragge
1.216
311                 cerror("emit %d"ip->type);
ragge
1.124
312         }
ragge
1.123
313 }
ragge
1.124
314
ragge
1.30
315 #ifdef PCC_DEBUG
ragge
1.1
316 char *cnames[] = {
317         "SANY",
318         "SAREG",
319         "SBREG",
ragge
1.153
320         "SCREG",
321         "SDREG",
ragge
1.1
322         "SCC",
323         "SNAME",
324         "SCON",
325         "SFLD",
326         "SOREG",
327         "STARNM",
328         "STARREG",
329         "INTEMP",
330         "FORARG",
331         "SWADD",
332         0,
ragge
1.72
333 };
ragge
1.1
334
ragge
1.2
335 /*
336  * print a nice-looking description of cookie
337  */
ragge
1.70
338 char *
ragge
1.2
339 prcook(int cookie)
340 {
ragge
1.70
341         static char buf[50];
ragge
1.1
342         int iflag;
343
ragge
1.70
344         if (cookie & SPECIAL) {
345                 switch (cookie) {
346                 case SZERO:
347                         return "SZERO";
348                 case SONE:
349                         return "SONE";
350                 case SMONE:
351                         return "SMONE";
352                 default:
ragge
1.200
353                         snprintf(bufsizeof(buf), "SPECIAL+%d"cookie & ~SPECIAL);
ragge
1.70
354                         return buf;
ragge
1.1
355                 }
ragge
1.70
356         }
ragge
1.1
357
358         flag = 0;
ragge
1.70
359         buf[0] = 0;
360         for (i = 0cnames[i]; ++i) {
361                 if (cookie & (1<<i)) {
362                         if (flag)
ragge
1.200
363                                 strlcat(buf"|"sizeof(buf));
ragge
1.1
364                         ++flag;
ragge
1.200
365                         strlcat(bufcnames[i], sizeof(buf));
ragge
1.1
366                 }
ragge
1.70
367         }
368         return buf;
369 }
ragge
1.1
370
ragge
1.30
371 #endif
ragge
1.1
372
373 int odebug = 0;
374
ragge
1.151
375 int
ragge
1.69
376 geninsn(NODE *pint cookie)
377 {
ragge
1.71
378         NODE *p1, *p2;
ragge
1.236
379         int qorv = 0;
ragge
1.69
380
381 #ifdef PCC_DEBUG
382         if (odebug) {
ragge
1.70
383                 printf("geninsn(%p, %s)\n"pprcook(cookie));
ragge
1.69
384                 fwalk(pe2print0);
385         }
386 #endif
387
ragge
1.236
388         q = cookie & QUIET;
389         cookie &= ~QUIET/* XXX - should not be necessary */
390
ragge
1.69
391 again:  switch (o = p->n_op) {
ragge
1.71
392         case EQ:
393         case NE:
394         case LE:
395         case LT:
396         case GE:
397         case GT:
398         case ULE:
399         case ULT:
400         case UGE:
401         case UGT:
gmcgarry
1.208
402                 p1 = p->n_left;
403                 p2 = p->n_right;
ragge
1.210
404                 if (p2->n_op == ICON && p2->n_lval == 0 &&
405                     optype(p1->n_op) == BITYPE) {
ragge
1.236
406 #ifdef mach_pdp11 /* XXX all targets? */
407                         if ((rv = geninsn(p1FORCC|QUIET)) != FFAIL)
408                                 break;
409 #else
410                         if (findops(p1FORCC) > 0)
gmcgarry
1.208
411                                 break;
ragge
1.236
412 #endif
gmcgarry
1.208
413                 }
ragge
1.159
414                 rv = relops(p);
415                 break;
ragge
1.71
416
ragge
1.69
417         case PLUS:
418         case MINUS:
419         case MUL:
420         case DIV:
421         case MOD:
422         case AND:
423         case OR:
424         case ER:
425         case LS:
426         case RS:
ragge
1.151
427                 rv = findops(pcookie);
428                 break;
ragge
1.77
429
ragge
1.69
430         case ASSIGN:
ragge
1.236
431 #ifdef FINDMOPS
432                 if ((rv = findmops(pcookie)) != FFAIL)
433                         break;
434                 /* FALLTHROUGH */
435 #endif
ragge
1.174
436         case STASG:
ragge
1.151
437                 rv = findasg(pcookie);
438                 break;
ragge
1.159
439
ragge
1.178
440         case UMUL/* May turn into an OREG */
ragge
1.179
441                 rv = findumul(pcookie);
442                 break;
443
ragge
1.69
444         case REG:
ragge
1.144
445         case TEMP:
ragge
1.72
446         case NAME:
ragge
1.71
447         case ICON:
ragge
1.213
448         case FCON:
ragge
1.69
449         case OREG:
ragge
1.152
450                 rv = findleaf(pcookie);
451                 break;
ragge
1.69
452
ragge
1.172
453         case STCALL:
454         case CALL:
455                 /* CALL arguments are handled special */
456                 for (p1 = p->n_rightp1->n_op == CMp1 = p1->n_left)
ragge
1.239
457                         (void)geninsn(p1->n_rightFOREFF);
458                 (void)geninsn(p1FOREFF);
ragge
1.172
459                 /* FALLTHROUGH */
ragge
1.206
460         case FLD:
ragge
1.86
461         case COMPL:
ragge
1.85
462         case UMINUS:
ragge
1.71
463         case PCONV:
464         case SCONV:
ragge
1.198
465 /*      case INIT: */
ragge
1.70
466         case GOTO:
467         case FUNARG:
ragge
1.172
468         case STARG:
ragge
1.72
469         case UCALL:
ragge
1.103
470         case USTCALL:
ragge
1.207
471         case ADDROF:
ragge
1.155
472                 rv = finduni(pcookie);
473                 break;
ragge
1.69
474
ragge
1.71
475         case CBRANCH:
476                 p1 = p->n_left;
477                 p2 = p->n_right;
478                 p1->n_label = p2->n_lval;
ragge
1.239
479                 (void)geninsn(p1FORCC);
ragge
1.187
480                 p->n_su = 0;
ragge
1.71
481                 break;
482
ragge
1.187
483         case FORCE/* XXX needed? */
ragge
1.239
484                 (void)geninsn(p->n_leftINREGS);
ragge
1.187
485                 p->n_su = 0/* su calculations traverse left */
ragge
1.71
486                 break;
487
ragge
1.216
488         case XASM:
489                 for (p1 = p->n_leftp1->n_op == CMp1 = p1->n_left)
ragge
1.239
490                         (void)geninsn(p1->n_rightFOREFF);
491                 (void)geninsn(p1FOREFF);
ragge
1.216
492                 break;  /* all stuff already done? */
493
494         case XARG:
495                 /* generate code for correct class here */
ragge
1.221
496 //              geninsn(p->n_left, 1 << p->n_label);
ragge
1.216
497                 break;
498
ragge
1.69
499         default:
ragge
1.174
500                 comperr("geninsn: bad op %s, node %p"opst[o], p);
ragge
1.69
501         }
ragge
1.236
502         if (rv == FFAIL && !q)
ragge
1.160
503                 comperr("Cannot generate code, node %p op %s"p,opst[p->n_op]);
504         if (rv == FRETRY)
505                 goto again;
ragge
1.236
506 #ifdef PCC_DEBUG
507         if (odebug) {
508                 printf("geninsn(%p, %s) rv %d\n"pprcook(cookie), rv);
509                 fwalk(pe2print0);
510         }
511 #endif
ragge
1.153
512         return rv;
ragge
1.69
513 }
514
ragge
1.72
515 /*
516  * Store a given subtree in a temporary location.
517  * Return an OREG node where it is located.
518  */
519 NODE *
520 store(NODE *p)
ragge
1.2
521 {
ragge
1.130
522         extern struct interpass *storesave;
523         struct interpass *ip;
524         NODE *q, *r;
525         int s;
ragge
1.49
526
ragge
1.130
527         s = BITOOR(freetemp(szty(p->n_type)));
528         q = mklnode(OREGsFPREGp->n_type);
529         r = mklnode(OREGsFPREGp->n_type);
530         ip = ipnode(mkbinode(ASSIGNqpp->n_type));
531
ragge
1.149
532         storesave = ip;
ragge
1.72
533         return r;
ragge
1.8
534 }
ragge
1.1
535
ragge
1.170
536 #ifdef PCC_DEBUG
537 #define CDEBUG(x) if (c2debug) printf x
538 #else
539 #define CDEBUG(x)
540 #endif
541
ragge
1.69
542 /*
ragge
1.188
543  * Do a register-register move if necessary.
544  */
545 static void
546 ckmove(NODE *pNODE *q)
547 {
ragge
1.189
548         if (q->n_op != REG || p->n_reg == -1)
ragge
1.188
549                 return/* no register */
550         if (DECRA(p->n_reg0) == DECRA(q->n_reg0))
551                 return/* no move necessary */
ragge
1.190
552         CDEBUG(("rmove: node %p, %s -> %s\n"prnames[DECRA(q->n_reg0)],
553             rnames[DECRA(p->n_reg0)]));
ragge
1.188
554         rmove(DECRA(q->n_reg0), DECRA(p->n_reg0), p->n_type);
555         q->n_reg = q->n_rval = DECRA(p->n_reg0);
556 }
557
558 /*
559  * Rewrite node to register after instruction emit.
ragge
1.75
560  */
561 static void
gmcgarry
1.224
562 rewrite(NODE *pint dorewriteint cookie)
ragge
1.75
563 {
ragge
1.79
564         NODE *l, *r;
565         int o;
566
ragge
1.80
567         l = getlr(p'L');
568         r = getlr(p'R');
ragge
1.79
569         o = p->n_op;
ragge
1.75
570         p->n_op = REG;
ragge
1.76
571         p->n_lval = 0;
ragge
1.95
572         p->n_name = "";
ragge
1.158
573
ragge
1.190
574         if (o == ASSIGN) {
575                 /* special rewrite care */
576                 int reg = DECRA(p->n_reg0);
ragge
1.191
577 #define TL(x) (TBLIDX(x->n_su) || x->n_op == REG)
ragge
1.190
578                 if (p->n_reg == -1)
579                         ;
ragge
1.191
580                 else if (TL(l) && (DECRA(l->n_reg0) == reg))
ragge
1.190
581                         ;
ragge
1.191
582                 else if (TL(r) && (DECRA(r->n_reg0) == reg))
ragge
1.190
583                         ;
ragge
1.191
584                 else if (TL(l))
ragge
1.190
585                         rmove(DECRA(l->n_reg0), regp->n_type);
ragge
1.191
586                 else if (TL(r))
ragge
1.190
587                         rmove(DECRA(r->n_reg0), regp->n_type);
588 #if 0
589                 else
590                         comperr("rewrite");
591 #endif
ragge
1.191
592 #undef TL
ragge
1.190
593         }
ragge
1.79
594         if (optype(o) != LTYPE)
595                 tfree(l);
596         if (optype(o) == BITYPE)
597                 tfree(r);
gmcgarry
1.224
598         if (dorewrite == 0)
ragge
1.190
599                 return;
mickey
1.205
600         CDEBUG(("rewrite: %p, reg %s\n"p,
601             p->n_reg == -1"<none>" : rnames[DECRA(p->n_reg0)]));
ragge
1.187
602         p->n_rval = DECRA(p->n_reg0);
ragge
1.75
603 }
604
ragge
1.228
605 #ifndef XASM_TARGARG
606 #define XASM_TARGARG(x,y) 0
607 #endif
608
ragge
1.216
609 /*
610  * printout extended assembler.
611  */
612 void
613 genxasm(NODE *p)
614 {
615         NODE *q, **nary;
616         int n = 1o = 0;
617         char *w;
618
ragge
1.228
619         if (p->n_left->n_op != ICON || p->n_left->n_type != STRTY) {
620                 for (q = p->n_leftq->n_op == CMq = q->n_left)
621                         n++;
622                 nary = tmpalloc(sizeof(NODE *)*n);
623                 o = n;
624                 for (q = p->n_leftq->n_op == CMq = q->n_left) {
625                         gencode(q->n_right->n_leftINREGS);
626                         nary[--o] = q->n_right;
627                 }
628                 gencode(q->n_leftINREGS);
629                 nary[--o] = q;
630         } else
631                 nary = 0;
ragge
1.216
632
633         w = p->n_name;
634         putchar('\t');
635         while (*w != 0) {
636                 if (*w == '%') {
ragge
1.225
637                         if (w[1] == '%')
638                                 putchar('%');
ragge
1.228
639                         else if (XASM_TARGARG(wnary))
640                                 ; /* handled by target */
ragge
1.225
641                         else if (w[1] < '0' || w[1] > (n + '0'))
ragge
1.228
642                                 uerror("bad xasm arg number %c"w[1]);
ragge
1.216
643                         else
ragge
1.221
644                                 adrput(stdoutnary[(int)w[1]-'0']->n_left);
ragge
1.216
645                         w++;
ragge
1.228
646                 } else if (*w == '\\') { /* Always 3-digit octal */
647                         int num = *++w - '0';
648                         num = (num << 3) + *++w - '0';
649                         num = (num << 3) + *++w - '0';
650                         putchar(num);
ragge
1.216
651                 } else
652                         putchar(*w);
653                 w++;
654         }
655         putchar('\n');
656 }
657
ragge
1.69
658 void
ragge
1.72
659 gencode(NODE *pint cookie)
ragge
1.69
660 {
661         struct optab *q = &table[TBLIDX(p->n_su)];
ragge
1.188
662         NODE *p1, *l, *r;
ragge
1.190
663         int o = optype(p->n_op);
ragge
1.240
664 #ifdef FINDMOPS
665         int ismops = (p->n_op == ASSIGN && (p->n_flags & 1));
666 #endif
ragge
1.188
667
668         l = p->n_left;
669         r = p->n_right;
ragge
1.69
670
ragge
1.186
671         if (TBLIDX(p->n_su) == 0) {
672                 if (o == BITYPE && (p->n_su & DORIGHT))
ragge
1.188
673                         gencode(r0);
ragge
1.185
674                 if (optype(p->n_op) != LTYPE)
ragge
1.188
675                         gencode(l0);
ragge
1.186
676                 if (o == BITYPE && !(p->n_su & DORIGHT))
ragge
1.188
677                         gencode(r0);
ragge
1.185
678                 return;
679         }
ragge
1.69
680
ragge
1.170
681         CDEBUG(("gencode: node %p\n"p));
682
683         if (p->n_op == REG && DECRA(p->n_reg0) == p->n_rval)
ragge
1.156
684                 return/* meaningless move to itself */
ragge
1.175
685
686         if (callop(p->n_op))
687                 lastcall(p); /* last chance before function args */
688         if (p->n_op == CALL || p->n_op == FORTCALL || p->n_op == STCALL) {
689                 /* Print out arguments first */
ragge
1.188
690                 for (p1 = rp1->n_op == CMp1 = p1->n_left)
ragge
1.175
691                         gencode(p1->n_rightFOREFF);
692                 gencode(p1FOREFF);
ragge
1.190
693                 o = UTYPE/* avoid going down again */
ragge
1.175
694         }
695
ragge
1.190
696         if (o == BITYPE && (p->n_su & DORIGHT)) {
ragge
1.188
697                 gencode(rINREGS);
698                 if (q->rewrite & RRIGHT)
699                         ckmove(pr);
700         }
ragge
1.190
701         if (o != LTYPE) {
ragge
1.188
702                 gencode(lINREGS);
ragge
1.240
703 #ifdef FINDMOPS
704                 if (ismops)
705                         ;
706                 else
707 #endif
708                      if (q->rewrite & RLEFT)
ragge
1.188
709                         ckmove(pl);
710         }
ragge
1.190
711         if (o == BITYPE && !(p->n_su & DORIGHT)) {
ragge
1.188
712                 gencode(rINREGS);
713                 if (q->rewrite & RRIGHT)
714                         ckmove(pr);
715         }
ragge
1.185
716
ragge
1.236
717 #ifdef FINDMOPS
ragge
1.240
718         if (ismops) {
ragge
1.236
719                 /* reduce right tree to make expand() work */
720                 if (optype(r->n_op) != LTYPE) {
ragge
1.240
721                         p->n_op = r->n_op;
ragge
1.236
722                         r = tcopy(r->n_right);
723                         tfree(p->n_right);
724                         p->n_right = r;
725                 }
726         }
727 #endif
728
ragge
1.188
729         canon(p);
ragge
1.185
730
ragge
1.188
731         if (q->needs & NSPECIAL) {
732                 int rr = rspecial(qNRIGHT);
733                 int lr = rspecial(qNLEFT);
ragge
1.187
734
ragge
1.188
735                 if (rr >= 0) {
gmcgarry
1.211
736 #ifdef PCC_DEBUG
737                         if (optype(p->n_op) != BITYPE)
738                                 comperr("gencode: rspecial borked");
739 #endif
ragge
1.188
740                         if (r->n_op != REG)
741                                 comperr("gencode: rop != REG");
742                         if (rr != r->n_rval)
743                                 rmove(r->n_rvalrrr->n_type);
744                         r->n_rval = r->n_reg = rr;
745                 }
746                 if (lr >= 0) {
747                         if (l->n_op != REG)
ragge
1.192
748                                 comperr("gencode: %p lop != REG"p);
ragge
1.188
749                         if (lr != l->n_rval)
750                                 rmove(l->n_rvallrl->n_type);
751                         l->n_rval = l->n_reg = lr;
752                 }
753                 if (rr >= 0 && lr >= 0 && (l->n_reg == rr || r->n_reg == lr))
754                         comperr("gencode: cross-reg-move");
755         }
ragge
1.161
756
ragge
1.162
757         if (p->n_op == ASSIGN &&
758             p->n_left->n_op == REG && p->n_right->n_op == REG &&
ragge
1.237
759             p->n_left->n_rval == p->n_right->n_rval &&
ragge
1.239
760             (p->n_su & RVCC) == 0) { /* XXX should check if necessary */
ragge
1.161
761                 /* do not emit anything */
ragge
1.170
762                 CDEBUG(("gencode(%p) assign nothing\n"p));
ragge
1.161
763                 rewrite(pq->rewritecookie);
764                 return;
765         }
ragge
1.147
766
ragge
1.170
767         CDEBUG(("emitting node %p\n"p));
ragge
1.190
768         if (TBLIDX(p->n_su) == 0)
ragge
1.173
769                 return;
ragge
1.170
770
ragge
1.72
771         expand(pcookieq->cstring);
ragge
1.240
772 #ifdef FINDMOPS
773         if (ismops && DECRA(p->n_reg0) != regno(l) && cookie != FOREFF) {
774                 CDEBUG(("gencode(%p) rmove\n"p));
775                 rmove(regno(l), DECRA(p->n_reg0), p->n_type);
776         } else
777 #endif
ragge
1.169
778         if (callop(p->n_op) && cookie != FOREFF &&
ragge
1.170
779             DECRA(p->n_reg0) != RETREG(p->n_type)) {
780                 CDEBUG(("gencode(%p) retreg\n"p));
781                 rmove(RETREG(p->n_type), DECRA(p->n_reg0), p->n_type);
ragge
1.156
782         } else if (q->needs & NSPECIAL) {
ragge
1.158
783                 int rr = rspecial(qNRES);
ragge
1.150
784
ragge
1.188
785                 if (rr >= 0 && DECRA(p->n_reg0) != rr) {
ragge
1.170
786                         CDEBUG(("gencode(%p) nspec retreg\n"p));
787                         rmove(rrDECRA(p->n_reg0), p->n_type);
788                 }
ragge
1.162
789         } else if ((q->rewrite & RESC1) &&
ragge
1.170
790             (DECRA(p->n_reg1) != DECRA(p->n_reg0))) {
791                 CDEBUG(("gencode(%p) RESC1 retreg\n"p));
792                 rmove(DECRA(p->n_reg1), DECRA(p->n_reg0), p->n_type);
ragge
1.190
793         }
794 #if 0
795                 /* XXX - kolla upp det här */
796            else if (p->n_op == ASSIGN) {
ragge
1.176
797                 /* may need move added if RLEFT/RRIGHT */
798                 /* XXX should be handled in sucomp() */
799                 if ((q->rewrite & RLEFT) && (p->n_left->n_op == REG) &&
800                     (p->n_left->n_rval != DECRA(p->n_reg0)) &&
801                     TCLASS(p->n_su)) {
802                         rmove(p->n_left->n_rvalDECRA(p->n_reg0), p->n_type);
803                 } else if ((q->rewrite & RRIGHT) && (p->n_right->n_op == REG) &&
804                     (p->n_right->n_rval != DECRA(p->n_reg0)) &&
805                     TCLASS(p->n_su)) {
806                         rmove(p->n_right->n_rvalDECRA(p->n_reg0), p->n_type);
807                 }
ragge
1.149
808         }
ragge
1.190
809 #endif
ragge
1.160
810         rewrite(pq->rewritecookie);
ragge
1.2
811 }
ragge
1.1
812
813 int negrel[] = { NEEQGTGELTLEUGTUGEULTULE } ;  /* negatives of relationals */
ragge
1.204
814 size_t negrelsize = sizeof negrel / sizeof negrel[0];
ragge
1.1
815
ragge
1.30
816 #ifdef PCC_DEBUG
ragge
1.87
817 #undef  PRTABLE
ragge
1.174
818 void
ragge
1.8
819 e2print(NODE *pint downint *aint *b)
ragge
1.2
820 {
ragge
1.85
821 #ifdef PRTABLE
822         extern int tablesize;
823 #endif
ragge
1.1
824
ragge
1.197
825         prfil = stdout;
ragge
1.1
826         *a = *b = down+1;
827         whiledown >= 2 ){
ragge
1.148
828                 fprintf(prfil"\t");
ragge
1.1
829                 down -= 2;
830                 }
ragge
1.148
831         ifdown-- ) fprintf(prfil"    " );
ragge
1.1
832
833
ragge
1.148
834         fprintf(prfil"%p) %s"popst[p->n_op] );
ragge
1.13
835         switchp->n_op ) { /* special cases */
ragge
1.1
836
837         case REG:
ragge
1.148
838                 fprintf(prfil" %s"rnames[p->n_rval] );
ragge
1.1
839                 break;
840
ragge
1.121
841         case TEMP:
ragge
1.214
842                 fprintf(prfil" %d"regno(p));
ragge
1.121
843                 break;
844
ragge
1.216
845         case XASM:
846         case XARG:
847                 fprintf(prfil" '%s'"p->n_name);
848                 break;
849
ragge
1.1
850         case ICON:
851         case NAME:
852         case OREG:
ragge
1.148
853                 fprintf(prfil" " );
854                 adrput(prfilp );
ragge
1.1
855                 break;
856
857         case STCALL:
ragge
1.68
858         case USTCALL:
ragge
1.1
859         case STARG:
860         case STASG:
ragge
1.148
861                 fprintf(prfil" size=%d"p->n_stsize );
862                 fprintf(prfil" align=%d"p->n_stalign );
ragge
1.1
863                 break;
864                 }
865
ragge
1.148
866         fprintf(prfil", " );
867         tprint(prfilp->n_typep->n_qual);
868         fprintf(prfil", " );
ragge
1.215
869
870         prtreg(prfilp);
ragge
1.239
871         fprintf(prfil", SU= %d(%cREG,%s,%s,%s,%s,%s,%s)\n",
ragge
1.85
872             TBLIDX(p->n_su), 
ragge
1.151
873             TCLASS(p->n_su)+'@',
ragge
1.85
874 #ifdef PRTABLE
875             TBLIDX(p->n_su) >= 0 && TBLIDX(p->n_su) <= tablesize ?
876             table[TBLIDX(p->n_su)].cstring : "",
877 #else
878             "",
879 #endif
ragge
1.239
880             p->n_su & LREG ? "LREG" : ""p->n_su & RREG ? "RREG" : "",
881             p->n_su & RVEFF ? "RVEFF" : ""p->n_su & RVCC ? "RVCC" : "",
882             p->n_su & DORIGHT ? "DORIGHT" : "");
ragge
1.2
883 }