|
|
1.1 root 1: /* @(#) local2.c : 1.6 3/14/84 */
2: /* local2.c - machine dependent grunge for back end
3: *
4: * Bellmac32
5: * R. J. Mascitti
6: */
7:
8: # include "mfile2.h"
9: # define istnode(p) (p->in.op==REG && istreg(p->tn.rval))
10: # define STHRESH 6 /* max # of words to unroll copy loop */
11:
12: static int strcall; /* have we made a call to a structure function? */
13:
14:
15:
16: lineid(l, fn) /* identify line l and file fn */
17: int l;
18: char *fn;
19: {
20: printf("# line %d, file %s\n", l, fn);
21: }
22:
23:
24: eobl2() /* end of function stuff */
25: {
26: strcall = 0;
27: eobl2dbg(); /* very end debug code */
28: }
29:
30:
31: char *rnames[]=
32: {
33: "%r0",
34: "%r1",
35: "%r2",
36: "%r3",
37: "%r4",
38: "%r5",
39: "%r6",
40: "%r7",
41: "%r8"
42: };
43:
44: static char * ccbranches[] =
45: {
46: "je",
47: "jne",
48: "jle",
49: "jl",
50: "jge",
51: "jg",
52: "jleu",
53: "jlu",
54: "jgeu",
55: "jgu"
56: };
57:
58: static char * arithjump[] =
59: {
60: "jz",
61: "jnz",
62: "jnpos",
63: "jneg",
64: "jnneg",
65: "jpos",
66: "jnpos",
67: "jneg",
68: "jnneg",
69: "jpos"
70: };
71:
72: static int cmpflag = 0; /* have we done a cmp? */
73:
74: zzzcode(pnode, ppc, q) /* hard stuff escaped from templates */
75: NODE *pnode;
76: char **ppc;
77: OPTAB *q; /* not used in m32 zzzcode */
78: {
79: int stlab, i;
80: OPTAB *q;
81: NODE *pl, *pr;
82:
83: switch (*++(*ppc))
84: {
85:
86: case 'H':
87: /* put out word relative bit shift for insv and extv
88: /* instruction. Similar to case 'H' case in expand(),
89: /* but no difference for different types
90: */
91: {
92: extern int fldsz, fldshf;
93:
94: pl = getlr( pnode, *++(*ppc) );
95: if (pl->tn.op != FLD ) cerror( "bad FLD for ZH" );
96: fldsz = UPKFSZ(pl->tn.rval);
97: fldshf = SZINT - fldsz - UPKFOFF(pl->tn.rval);
98: printf( "%d", fldshf );
99: }
100: break;
101:
102:
103: case 'D': /* output address of second half of double */
104: dbladrput( pl = getlr(pnode,*++(*ppc)) );
105: break;
106:
107:
108: case 'B':
109: bycode(pnode->in.left->tn.lval, 0);
110: break;
111:
112: case 'b':
113: ++cmpflag;
114: break;
115:
116: case 'C':
117: printf("%s\t.L%d\n",
118: cmpflag ? ccbranches[pnode->bn.lop - EQ] :
119: arithjump[pnode->bn.lop - EQ], pnode->bn.label);
120: cmpflag = 0;
121: break;
122:
123: case 'c': /* # of word-length args */
124: printf("%d", pnode->stn.argsize / SZINT);
125: break;
126:
127: case 'h': /* deal with the BM32's weird treatment
128: of half-word compares */
129: /* If a 16 bit positive constant is used, it will
130: not be sign extended, but the othe operand will */
131: {
132: register NODE *r, *l;
133: int lchg = 0, rchg = 0;
134: l = pnode ->in.left;
135: if ((l->tn.op == ICON) &&
136: ((l->tn.type == TUSHORT) ||
137: (l->tn.type == TSHORT)) &&
138: (l->tn.lval > 0x7fff)) {
139: lchg = 1;
140: }
141: r = pnode->in.right;
142: if ((r->tn.op == ICON) &&
143: ((r->tn.type == TUSHORT) ||
144: (r->tn.type == TSHORT)) &&
145: (r->tn.lval > 0x7fff)) {
146: rchg = 1;
147: }
148: if ((!rchg && !lchg) || (rchg && lchg)) {
149: expand(pnode, FORCC, "cmph AL,AR", q);
150: } else if (rchg) {
151: expand(pnode, FORCC,
152: "movzhw AL,A1\n cmpw A1,AR", q);
153: } else {
154: expand(pnode, FORCC,
155: "movzhw AR,A1\n cmpw AL,A1", q);
156: }
157: break;
158: }
159:
160: case 'S': /* STASG */
161: q = ophead[STASG];
162: if (istnode(pnode->in.left))
163: pl = pnode->in.left;
164: else
165: {
166: pl = &resc[1];
167: if (pnode->in.left->in.op == UNARY AND)
168: expand(pnode, FOREFF, " movaw A(LL),A2\n", q);
169: else
170: expand(pnode, FOREFF, " movw AL,A2\n", q);
171: }
172: if (istnode(pnode->in.right))
173: pr = pnode->in.right;
174: else
175: {
176: pr = &resc[0];
177: if (pnode->in.right->in.op == UNARY AND)
178: expand(pnode, FOREFF, " movaw A(RL),A1\n", q);
179: else
180: expand(pnode, FOREFF, " movw AR,A1\n", q);
181: }
182: if ((i = pnode->stn.stsize / SZINT) <= STHRESH)
183: while (i--)
184: printf("\tmovw\t%d(%s),%d(%s)\n", i << 2,
185: rnames[pr->tn.rval], i << 2,
186: rnames[pl->tn.rval]);
187: else
188: {
189: int lastlab = getlab();
190:
191: printf(" movw &%d,", i);
192: expand(pnode, FOREFF, "A3\n.\\L", q);
193: printf("%d:\tmovw\t0(%s),0(%s)\n\taddw2\t&4,%s\n\taddw2\t&4,%s\n",
194: lastlab, rnames[pr->tn.rval], rnames[pl->tn.rval],
195: rnames[pr->tn.rval], rnames[pl->tn.rval]);
196: expand(pnode,FOREFF, "\tsubw2\t&1,A3\n\tjpos\t.\\L", q);
197: printf("%d\n", lastlab);
198: }
199: break;
200:
201: case 's': /* STARG */
202: q = ophead[STARG];
203: if (istnode(pnode->in.left))
204: pl = pnode->in.left;
205: else
206: {
207: pl = &resc[0];
208: if (pnode->in.left->in.op == UNARY AND)
209: expand(pnode, FOREFF, " movaw A(LL),A1\n", q);
210: else
211: expand(pnode, FOREFF, " movw AL,A1\n", q);
212: }
213: printf(" addw2 &%d,%%sp\n movaw -%d(%%sp),",
214: pnode->stn.stsize / SZCHAR, pnode->stn.stsize / SZCHAR);
215: expand(pnode, FOREFF, "A2\n", q);
216: if ((i = pnode->stn.stsize / SZINT) <= STHRESH)
217: while (i--)
218: {
219: printf(" movw %d(%s),%d(", i << 2,
220: rnames[pl->tn.rval], i << 2);
221: expand(pnode, FOREFF, "A2)\n", q);
222: }
223: else
224: {
225: int lastlab = getlab();
226:
227: printf(" movw &%d,", i);
228: expand(pnode, FOREFF, "A3\n.\\L", q);
229: printf("%d:\tmovw\t0(%s),0(", lastlab,
230: rnames[pl->tn.rval]);
231: expand(pnode, FOREFF, "A2)\n\taddw2\t&4,", q);
232: printf("%s\n\taddw2\t&4,", rnames[pl->tn.rval]);
233: expand(pnode, FOREFF,
234: "A2\n\tsubw2\t&1,A3\n\tjpos\t.\\L", q);
235: printf("%d\n", lastlab);
236: }
237: break;
238:
239: default:
240: cerror("botched Z macro %c", **ppc);
241: /*NOTREACHED*/
242: }
243: }
244:
245:
246: staradr(p) /* dereference p */
247: NODE *p;
248: {
249: NODE *pp;
250:
251: pp = talloc();
252: pp->tn.op = STAR;
253: pp->in.left = p;
254: upput(pp);
255: pp->tn.op = FREE;
256: }
257:
258: conput(p) /* name for a known */
259: register NODE *p;
260: {
261: switch(p->in.op)
262: {
263: case ICON:
264: acon(p);
265: break;
266: case REG:
267: fputs(rnames[p->tn.rval], stdout);
268: break;
269: default:
270: cerror("confused node in conput");
271: /*NOTREACHED*/
272: }
273: }
274:
275: insput(p) /* we don't have any */
276: NODE *p;
277: {
278: cerror("insput");
279: }
280:
281: upput(p) /* generate address incl. indirect, offset */
282: NODE *p;
283: {
284: register NODE *r, *l, *pp;
285:
286: sideff = 0;
287: if (p->in.op == STAR)
288: pp = p->in.left;
289: else
290: pp = p;
291: again:
292: switch (pp->tn.op)
293: {
294: case NAME:
295: case TEMP:
296: case VAUTO:
297: case VPARAM:
298: if (p->in.op == STAR)
299: putchar('*');
300: adrput(pp);
301: break;
302:
303: case REG:
304: if (p->in.op == STAR)
305: {
306: fputs("0(", stdout);
307: conput(pp);
308: putchar(')');
309: }
310: else
311: conput(pp);
312: break;
313:
314: case ICON:
315: if (p->in.op == STAR)
316: putchar('*');
317: acon(pp);
318: break;
319:
320: case STAR:
321: putchar('*');
322: p = pp;
323: pp = pp->in.left;
324: goto again;
325:
326: case PLUS:
327: case MINUS:
328: case INCR:
329: case DECR:
330: if (p->in.op == STAR && pp->in.left->in.op != REG)
331: putchar('*');
332: if (pp->in.op == MINUS)
333: putchar('-');
334: acon(pp->in.right);
335: putchar('(');
336: conput(pp->in.left);
337: putchar(')');
338: break;
339:
340: default:
341: cerror("upput: confused addressing mode matched");
342: /*NOTREACHED*/
343: }
344: }
345:
346: adrput(p) /* output address from p */
347: NODE *p;
348: {
349: sideff = 0;
350: while (p->in.op == FLD || p->in.op == CONV)
351: p = p->in.left;
352: switch (p->in.op)
353: {
354: case ICON: /* value of the constant */
355: putchar('&');
356: case NAME:
357: acon(p);
358: break;
359: case REG:
360: conput(p);
361: break;
362: case STAR:
363: upput(p);
364: break;
365: case TEMP:
366: printf("%d(%%fp)", p->tn.lval + maxboff / SZCHAR);
367: break;
368: case VAUTO:
369: printf("%d(%%fp)", p->tn.lval);
370: break;
371: case VPARAM:
372: printf("%d(%%ap)", p->tn.lval);
373: break;
374: default:
375: cerror("adrput: illegal address");
376: break;
377: }
378: }
379:
380:
381:
382:
383: dbladrput(p)
384: NODE *p;
385: /* output address of word after p. used for double moves */
386: {
387: while (p->in.op == FLD || p->in.op == CONV)
388: p = p->in.left;
389: switch (p->in.op)
390: {
391: case NAME:
392: printf("%s+%ld", p->in.name, p->tn.lval + 4);
393: break;
394: case REG:
395: fputs(rnames[p->tn.rval + 1],stdout);
396: break;
397: case TEMP:
398: printf("%d(%%fp)", (p->tn.lval+maxboff/SZCHAR)+4);
399: break;
400: case VAUTO:
401: printf("%d(%%fp)", p->tn.lval + 4);
402: break;
403: case VPARAM:
404: printf("%d(%%ap)", p->tn.lval + 4);
405: break;
406: default:
407: cerror("dbladrput: illegal double address substitution");
408: /*NOTREACHED*/
409: }
410: }
411:
412:
413:
414:
415: acon(p) /* print out a constant */
416: register NODE *p;
417: {
418:
419: if (p->in.name == (char *) 0) /* constant only */
420: {
421: if (p->in.op == ICON &&
422: (p->in.type == TCHAR || p->in.type == TUCHAR))
423: p->tn.lval &= 0xff;
424: printf("%ld", p->tn.lval);
425: }
426: else if (p->tn.lval == 0) /* name only */
427: printf("%s", p->in.name);
428: else /* name + offset */
429: printf ("%s+%ld", p->in.name, p->tn.lval);
430: }
431:
432:
433:
434: special(sc,p)
435: NODE *p;
436: {
437: cerror("special shape used");
438: return (INFINITY);
439: }
440:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.