Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081116115241

Diff

Diff from 1.242 to:

Annotations

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

Annotated File View

ragge
1.242
1 /*      $Id: reader.c,v 1.242 2008/11/16 11:52:41 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.242
91 static void fixxasm(struct p2env *);
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.242
103 struct p2env p2env;
ragge
1.241
104
ragge
1.26
105 #ifdef PCC_DEBUG
ragge
1.241
106 static int *lbldef, *lbluse;
ragge
1.26
107 static void
108 cktree(NODE *p)
109 {
ragge
1.241
110         int i;
111
ragge
1.26
112         if (p->n_op > MAXOP)
ragge
1.218
113                 cerror("%p) op %d slipped through"pp->n_op);
ragge
1.199
114         if (BTYPE(p->n_type) > MAXTYPES)
ragge
1.218
115                 cerror("%p) type %x slipped through"pp->n_type);
ragge
1.241
116         if (p->n_op == CBRANCH) {
117                  if (!logop(p->n_left->n_op))
118                         cerror("%p) not logop branch"p);
119                 i = p->n_right->n_lval;
ragge
1.242
120                 if (i < p2env.ipp->ip_lblnum || i >= p2env.epp->ip_lblnum)
ragge
1.241
121                         cerror("%p) label %d outside boundaries %d-%d",
ragge
1.242
122                             pip2env.ipp->ip_lblnump2env.epp->ip_lblnum);
123                 lbluse[i-p2env.ipp->ip_lblnum] = 1;
ragge
1.241
124         }
ragge
1.47
125         if ((dope[p->n_op] & ASGOPFLG) && p->n_op != RETURN)
ragge
1.218
126                 cerror("%p) asgop %d slipped through"pp->n_op);
ragge
1.241
127         if (p->n_op == TEMP &&
ragge
1.242
128             (regno(p) < p2env.ipp->ip_tmpnum || regno(p) >= p2env.epp->ip_tmpnum))
ragge
1.241
129                 cerror("%p) temporary %d outside boundaries %d-%d",
ragge
1.242
130                     pregno(p), p2env.ipp->ip_tmpnump2env.epp->ip_tmpnum);
ragge
1.241
131         if (p->n_op == GOTO) {
132                 i = p->n_left->n_lval;
ragge
1.242
133                 if (i < p2env.ipp->ip_lblnum || i >= p2env.epp->ip_lblnum)
ragge
1.241
134                         cerror("%p) label %d outside boundaries %d-%d",
ragge
1.242
135                             pip2env.ipp->ip_lblnump2env.epp->ip_lblnum);
136                 lbluse[i-p2env.ipp->ip_lblnum] = 1;
ragge
1.241
137         }
138 }
139
140 /*
141  * Check that the trees are in a suitable state for pass2.
142  */
143 static void
144 sanitychecks(void)
145 {
146         struct interpass *ip;
147         int i;
148 #ifdef notyet
149         TMPMARK();
150 #endif
ragge
1.242
151         lbldef = tmpcalloc(sizeof(int) * (p2env.epp->ip_lblnum - p2env.ipp->ip_lblnum));
152         lbluse = tmpcalloc(sizeof(int) * (p2env.epp->ip_lblnum - p2env.ipp->ip_lblnum));
ragge
1.241
153
ragge
1.242
154         DLIST_FOREACH(ip, &p2env.ipoleqelem) {
ragge
1.241
155                 if (ip->type == IP_DEFLAB) {
156                         i = ip->ip_lbl;
ragge
1.242
157                         if (i < p2env.ipp->ip_lblnum || i >= p2env.epp->ip_lblnum)
ragge
1.241
158                                 cerror("label %d outside boundaries %d-%d",
ragge
1.242
159                                     ip2env.ipp->ip_lblnump2env.epp->ip_lblnum);
160                         lbldef[i-p2env.ipp->ip_lblnum] = 1;
ragge
1.241
161                 }
162                 if (ip->type == IP_NODE)
163                         walkf(ip->ip_nodecktree);
164         }
ragge
1.242
165         for (i = 0i < (p2env.epp->ip_lblnum - p2env.ipp->ip_lblnum); i++)
ragge
1.241
166                 if (lbluse[i] != 0 && lbldef[i] == 0)
167                         cerror("internal label %d not defined",
ragge
1.242
168                             i + p2env.ipp->ip_lblnum);
ragge
1.241
169
170 #ifdef notyet
171         TMPFREE();
172 #endif
ragge
1.26
173 }
174 #endif
ragge
1.8
175
ragge
1.130
176 /*
ragge
1.89
177  * Check if a node has side effects.
178  */
179 static int
180 isuseless(NODE *n)
181 {
182         switch (n->n_op) {
ragge
1.216
183         case XASM:
ragge
1.89
184         case FUNARG:
185         case UCALL:
186         case UFORTCALL:
187         case FORCE:
188         case ASSIGN:
189         case CALL:
190         case FORTCALL:
191         case CBRANCH:
192         case RETURN:
193         case GOTO:
194         case STCALL:
195         case USTCALL:
196         case STASG:
197         case STARG:
198                 return 0;
199         default:
200                 return 1;
201         }
202 }
203
ragge
1.130
204 /*
205  * Delete statements with no meaning (like a+b; or 513.4;)
206  */
ragge
1.238
207 NODE *
ragge
1.89
208 deluseless(NODE *p)
209 {
210         struct interpass *ip;
211         NODE *l, *r;
212
213         if (optype(p->n_op) == LTYPE) {
214                 nfree(p);
215                 return NULL;
216         }
217         if (isuseless(p) == 0)
218                 return p;
219
220         if (optype(p->n_op) == UTYPE) {
221                 l = p->n_left;
222                 nfree(p);
223                 return deluseless(l);
224         }
225
226         /* Be sure that both leaves may be valid */
227         l = deluseless(p->n_left);
228         r = deluseless(p->n_right);
229         nfree(p);
230         if (l && r) {
ragge
1.201
231                 ip = ipnode(l);
232                 DLIST_INSERT_AFTER(&prepoleipqelem);
ragge
1.89
233                 return r;
234         } else if (l)
235                 return l;
236         else if (r)
237                 return r;
238         return NULL;
239 }
240
ragge
1.172
241 /*
242  * Receives interpass structs from pass1.
243  */
244 void
245 pass2_compile(struct interpass *ip)
246 {
247         if (ip->type == IP_PROLOG) {
ragge
1.242
248                 memset(&p2env0sizeof(struct p2env));
ragge
1.172
249                 tmpsave = NULL;
ragge
1.242
250                 p2env.ipp = (struct interpass_prolog *)ip;
251                 DLIST_INIT(&p2env.ipoleqelem);
ragge
1.172
252         }
ragge
1.242
253         DLIST_INSERT_BEFORE(&p2env.ipoleipqelem);
ragge
1.172
254         if (ip->type != IP_EPILOG)
255                 return;
256
257 #ifdef PCC_DEBUG
258         if (e2debug) {
259                 printf("Entering pass2\n");
ragge
1.242
260                 printip(&p2env.ipole);
ragge
1.172
261         }
262 #endif
ragge
1.174
263
ragge
1.242
264         p2env.epp = (struct interpass_prolog *)DLIST_PREV(&p2env.ipoleqelem);
265         p2maxautooff = p2autooff = p2env.epp->ipp_autos;
ragge
1.174
266
ragge
1.241
267 #ifdef PCC_DEBUG
268         sanitychecks();
269 #endif
ragge
1.242
270         myreader(&p2env.ipole); /* local massage of input */
ragge
1.174
271
ragge
1.242
272         DLIST_FOREACH(ip, &p2env.ipoleqelem) {
ragge
1.172
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.242
279         DLIST_FOREACH(ip, &p2env.ipoleqelem) {
ragge
1.172
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.242
294         fixxasm(&p2env); /* setup for extended asm */
ragge
1.216
295
ragge
1.242
296         optimize(&p2env);
297         ngenregs(&p2env);
ragge
1.172
298
ragge
1.242
299         DLIST_FOREACH(ip, &p2env.ipoleqelem)
ragge
1.172
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