Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081115093443

Diff

Diff from 1.241 to:

Annotations

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

Annotated File View

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