|
|
1.1 root 1: # include "mfile2.h"
2: /* a lot of the machine dependent parts of the second pass */
3:
4: char *
5: ccbranches[] = {
6: " jeql L%d\n",
7: " jneq L%d\n",
8: " jleq L%d\n",
9: " jlss L%d\n",
10: " jgeq L%d\n",
11: " jgtr L%d\n",
12: " jlequ L%d\n",
13: " jlssu L%d\n",
14: " jgequ L%d\n",
15: " jgtru L%d\n",
16: };
17:
18: cbgen( o, lab, mode )
19: int o, lab, mode;
20: { /* printf conditional and unconditional branches */
21:
22: if( !o ) printf( " jbr L%d\n", lab );
23: else if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] );
24: else printf( ccbranches[o-EQ], lab );
25: }
26:
27: zzzcode( p, ppc, q )
28: NODE *p; char **ppc; OPTAB *q;
29: {
30: register c;
31:
32: switch( c= *++(*ppc) )
33: {
34: case 'I':
35: cbgen( p->bn.lop, p->bn.label, c );
36: return;
37:
38:
39: case 'k': /* complement mask for bit instr */
40: printf("$%ld", ~p->in.right->tn.lval);
41: return;
42:
43: case 'c':
44: /* argument size */
45: printf( "$%d", p->stn.argsize/SZINT);
46: return;
47:
48: case 'U': /* 32 - n, for unsigned right shifts */
49: printf("$%d", 32 - p->in.right->tn.lval );
50: return;
51:
52: case 'T': /* structure length for arguments */
53: printf("$%d", p->stn.stsize / SZCHAR);
54: break;
55:
56: case 'M': /* move address */
57: staradr( p->in.right );
58: break;
59:
60: case 'S': /* structure assignment */
61: {
62: register NODE *l, *r;
63: register size;
64:
65: if( p->in.op == STASG )
66: {
67: l = p->in.left;
68: r = p->in.right;
69: }
70: else if( p->in.op == STARG )
71: { /* store an arg */
72: r = p->in.left;
73: }
74: else cerror( "STASG bad" );
75:
76: size = p->stn.stsize/SZCHAR;
77:
78: if( size <= 0 || size > 65535 )
79: cerror("structure size <0=0 or >65535");
80:
81: switch(size)
82: {
83: case 1:
84: printf(" movb ");
85: break;
86: case 2:
87: printf(" movw ");
88: break;
89: case 4:
90: printf(" movl ");
91: break;
92: case 8:
93: printf(" movq ");
94: break;
95: default:
96: printf(" movc3 $%d,", size);
97: break;
98: }
99: staradr( r );
100: printf(",");
101: if( p->in.op == STARG ) printf( "(sp)" );
102: else staradr( l );
103: printf("\n");
104:
105: }
106: break;
107:
108: default:
109: cerror( "illegal zzzcode" );
110: }
111: }
112:
113: staradr( p )
114: NODE *p;
115: {
116: NODE *pp;
117: pp = talloc();
118: pp->in.op = STAR;
119: pp->in.left = p;
120: upput( pp );
121: pp->in.op = FREE;
122: }
123:
124: conput( p )
125: register NODE *p;
126: {
127: switch( p->in.op )
128: {
129: case ICON:
130: acon( p );
131: return;
132:
133: case REG:
134: printf( "%s", rnames[p->tn.rval] );
135: return;
136:
137: default:
138: cerror( "illegal conput" );
139: }
140: }
141:
142: insput( p )
143: NODE *p;
144: {
145: cerror( "insput" );
146: }
147:
148: /* new use for an old routine
149: * upput now puts out an indirect address ( STAR node )
150: * equivalent to the old case STAR in adrput
151: * as upput, we can now get to this routine directly from the
152: * templates, using the U symbol
153: */
154:
155: int sideff;
156:
157: upput( p )
158: NODE *p;
159: {
160: register NODE *r, *l, *pp;
161: register o;
162: pp = ( STAR == p->in.op ) ? p->in.left : p ;
163: o = pp->in.op;
164: if( o==NAME || o==STAR || o==TEMP || o==VAUTO || o==VPARAM )
165: {
166: printf( "*" );
167: adrput(pp);
168: return;
169: }
170: if( o==ICON )
171: {
172: acon( pp );
173: sideff = 0;
174: return;
175: }
176: if( o == PLUS )
177: {
178: r = pp->in.right;
179: l = pp->in.left;
180: if( l->in.op == REG && r->in.op == ICON )
181: {
182: acon( r );
183: pp = pp->in.left;
184: }
185: else
186: {
187: /* index mode (shudder) */
188: /* save the index, rewrite p to point to
189: /* the rest, call adrput recursively, and
190: /* then tack on the index */
191: if( l->in.op == UNARY AND )
192: { /* double index */
193: adrput( l->in.left );
194: l = r;
195: }
196: else
197: {
198: p->in.left = r;
199: adrput( p );
200: p->in.left = pp; /* back to normal */
201: }
202: if( l->in.op == LS ) l = l->in.left;
203: if( l->in.op != REG ) cerror("illegal address");
204: printf( "[%s]", rnames[l->tn.rval] );
205: return;
206: }
207: }
208: else if( o == MINUS )
209: {
210: r = pp->in.right;
211: if( r->tn.op != ICON || r->tn.name ) cerror("illegal address");
212: r->tn.lval = -r->tn.lval;
213: acon( r );
214: r->tn.lval = -r->tn.lval;
215: pp = pp->in.left;
216: }
217: else if( o == ASG MINUS )
218: {
219: r = pp->in.right;
220: if( r->tn.op != ICON ) cerror("illegal address");
221: r = pp->in.left;
222: if( r->tn.op != REG ) cerror("illegal address");
223: /* always do the side effect */
224: printf( "-(%s)", rnames[r->tn.rval] );
225: sideff = 1; /* cream it */
226: return;
227: }
228: else if( o == INCR )
229: {
230: r = pp->in.right;
231: if( r->tn.op != ICON ) cerror("illegal address");
232: r = pp->in.left;
233: if( r->tn.op != REG ) cerror("illegal address");
234: if( sideff ) printf( "(%s)+", rnames[r->tn.rval] );
235: else printf( "(%s)", rnames[r->tn.rval] );
236: return;
237: }
238: if( pp->tn.op != REG ) cerror("illegal address");
239: printf( "(%s)", rnames[pp->tn.rval] );
240: return;
241: }
242:
243: adrput( p )
244: register NODE *p;
245: {
246: /* output an address, with offsets, from p */
247: register o;
248:
249: while( (o=p->in.op) == FLD || o==CONV )
250: {
251: p = p->in.left;
252: o = p->in.op;
253: }
254: switch( o )
255: {
256: case NAME:
257: acon( p );
258: sideff = 0;
259: return;
260:
261: case ICON:
262: /* addressable value of the constant */
263: printf( "$" );
264: acon( p );
265: sideff = 0;
266: return;
267:
268: case REG:
269: printf( "%s", rnames[p->tn.rval] );
270: sideff = 0;
271: return;
272:
273: case STAR:
274: upput( p );
275: return;
276:
277: case TEMP:
278: sideff = 0;
279: printf( "%ld(fp)", p->tn.lval - maxboff / SZCHAR );
280: return;
281:
282: case VAUTO:
283: sideff = 0;
284: printf( "%ld(fp)", p->tn.lval );
285: return;
286:
287: case VPARAM:
288: sideff = 0;
289: printf( "%ld(ap)", p->tn.lval );
290: return;
291:
292: default:
293: cerror( "illegal address" );
294: return;
295: }
296: }
297:
298: acon(p)
299: NODE *p;
300: { /* print out a constant */
301:
302: if( p->tn.name == 0 )
303: { /* constant only */
304: printf( "%ld", p->tn.lval);
305: }
306: else if( p->tn.lval == 0 )
307: { /* name only */
308: printf( "%s", p->tn.name );
309: }
310: else
311: { /* name + offset */
312: printf( "%s+%ld", p->tn.name, p->tn.lval );
313: }
314: }
315:
316: special()
317: {
318: cerror("reached special");
319: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.