|
|
1.1 root 1: /* C compiler: MC68020 code generator */
2:
3: #include "c.h"
4:
5: #define AREG 0 /* an address register */
6: #define DREG 1 /* a data register */
7: #define FREG 2 /* a floating point register */
8:
9: #if mc68020 || mc68030 || NeXT
10: #include <stab.h>
11: #include "stabbsd.c"
12: #endif
13:
14: dclproto(static void address,(Symbol, Symbol, int));
15: dclproto(static void defaddress,(Symbol));
16: dclproto(static void defconst,(int, Value));
17: dclproto(static void defstring,(int, char *));
18: dclproto(static void defsymbol,(Symbol));
19: dclproto(static void doarg,(Node));
20: dclproto(static void emitspecial,(Node));
21: dclproto(static void function,(Symbol, Symbol [], Symbol [], int));
22: dclproto(static void global,(Symbol));
23: dclproto(static void import,(Symbol));
24: dclproto(static void local,(Symbol));
25: dclproto(static void progbeg,(int, char **));
26: dclproto(static void segment,(int));
27: dclproto(static void space,(int));
28:
29: dclproto(static void initgen,(void));
30: dclproto(static void final,(Node));
31:
32: Interface mcInterface = {
33: "mc",
34: 1, 1, 0, /* char */
35: 2, 2, 0, /* short */
36: 4, 2, 0, /* int */
37: 4, 2, 1, /* float */
38: 8, 2, 1, /* double */
39: 4, 2, 0, /* T * */
40: 0, 2, 0, /* struct */
41: 1, /* left_to_right */
42: 0, /* little_endian */
43: 1, /* jump_on_return */
44: 0, /* mulops_are_calls */
45: 0, /* compl_band */
46: 0, /* no_argb */
47: NODAG, /* no_dag */
48: address,
49: blockbeg,
50: blockend,
51: defaddress,
52: defconst,
53: defstring,
54: defsymbol,
55: 0,
56: export,
57: function,
58: gen,
59: global,
60: import,
61: local,
62: progbeg,
63: progend,
64: segment,
65: space,
66: #if mc68020 || mc68030 || NeXT
67: stabblock, 0, 0, stabinit, stabline, stabsym, stabtype,
68: #else
69: 0, 0, 0, 0, 0, 0, 0,
70: #endif
71: {".globl %s\n", 1, 0, {".text", ".bss", ".data", ".text", ".data2"},
72: doarg, docall, 0, 0, 0,
73: final, 0, emitspecial }
74: }, nextInterface = {
75: "next",
76: 1, 1, 0, /* char */
77: 2, 2, 0, /* short */
78: 4, 2, 0, /* int */
79: 4, 2, 1, /* float */
80: 8, 2, 1, /* double */
81: 4, 2, 0, /* T * */
82: 0, 2, 0, /* struct */
83: 1, /* left_to_right */
84: 0, /* little_endian */
85: 1, /* jump_on_return */
86: 0, /* mulops_are_calls */
87: 0, /* compl_band */
88: 0, /* no_argb */
89: NODAG, /* no_dag */
90: address,
91: blockbeg,
92: blockend,
93: defaddress,
94: defconst,
95: defstring,
96: defsymbol,
97: 0,
98: export,
99: function,
100: gen,
101: global,
102: import,
103: local,
104: progbeg,
105: progend,
106: segment,
107: space,
108: #if mc68020 || mc68030 || NeXT
109: stabblock, 0, 0, stabinit, stabline, stabsym, stabtype,
110: #else
111: 0, 0, 0, 0, 0, 0, 0,
112: #endif
113: {".globl %s\n", 1, 0, {".text", ".bss", ".data", ".text", ".data2"},
114: doarg, docall, 0, 0, 0,
115: final, 0, emitspecial }
116:
117: };
118:
119: static Symbol a0, a1, d0, d1, d1234, fp0;
120:
121: /* address - initialize q for addressing expression p+n */
122: static void address(q, p, n) Symbol q, p; {
123: q->x.offset = p->x.offset + n;
124: if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN)
125: q->x.name = stringf("%s%s%d", p->x.name, n >= 0 ? "+" : "", n);
126: else
127: q->x.name = stringd(q->x.offset);
128: }
129:
130: static void defaddress(p) Symbol p; {
131: if (p->scope == LABELS)
132: print(".align 2; "); /* for switch tables */
133: print(".long %s\n", p->x.name);
134: }
135:
136: /* defconst - define a constant */
137: static void defconst(ty, v) Value v; {
138: struct real r;
139:
140: switch (ty) {
141: case C: print(".byte %d\n", v.uc); break;
142: case S: print(".word %d\n", v.ss); break;
143: case I: print(".long %d\n", v.i ); break;
144: case U: print(".long 0x%x\n", v.u ); break;
145: case P: print(".long 0x%x\n", v.p ); break;
146: case F:
147: r = decode(F, v.f);
148: if (v.f)
149: r.exp = (r.exp + 127)&0xff;
150: print(".long 0x%x\n", (r.sign<<31) | (r.exp<<23) | (r.msb>>9));
151: break;
152: case D:
153: r = decode(D, v.d);
154: if (v.d)
155: r.exp = (r.exp + 1023)&0x7ff;
156: print(".long 0x%x,0x%x\n",
157: (r.sign<<31) | (r.exp<<20) | (r.msb>>12),
158: ( r.msb<<20) | (r.lsb>>12));
159: break;
160: default:
161: assert(0);
162: }
163: }
164:
165: static void defstring(n, s) char *s; {
166: genascii(".ascii", ".byte", n, s);
167: }
168:
169: /* defsymbol - compute and store p's back-end name */
170: static void defsymbol(p) Symbol p; {
171: if (p->scope == CONSTANTS)
172: p->x.name = p->name;
173: else if (p->scope >= LOCAL && p->sclass == STATIC)
174: p->x.name = stringf("L%d", genlabel(1));
175: else if (p->generated)
176: p->x.name = stringf("L%s", p->name);
177: else
178: p->x.name = stringf("_%s", p->name);
179: }
180:
181: /* doarg - assign offset for next ARG node */
182: static void doarg(p) Node p; {
183: assert(p);
184: assert(p->syms[0]);
185: assert(p->syms[1]);
186: p->syms[2] = intconst(mkactual(p->syms[1]->u.c.v.i, p->syms[0]->u.c.v.i, 4));
187: }
188:
189: static void emitspecial(p) Node p; {}
190:
191: /* function - generate code for a function */
192: static void function(p, caller, callee, n) Symbol p, callee[], caller[]; {
193: int i;
194: unsigned fmask, imask;
195:
196: initfunc(n, 8, 0);
197: for (i = 0; callee[i]; i++) {
198: assert(caller[i]);
199: callee[i]->x.offset = caller[i]->x.offset = offset;
200: callee[i]->x.name = caller[i]->x.name = stringd(offset);
201: offset = roundup(offset + caller[i]->type->size, 4);
202: getregvar(callee[i], rmap[ttob(callee[i]->type)]);
203: }
204: assert(caller[i] == 0);
205: offset = 0;
206: gencode(caller, callee);
207: mvregvars();
208: fmask = 0;
209: if (usedmask[FREG])
210: for (i = 0; i < 8; i++)
211: if (usedmask[FREG]&(1<<i))
212: fmask |= 0x80>>i;
213: imask = (((usedmask[AREG]&eemask[AREG])<<8) | (usedmask[DREG]&eemask[DREG]));
214: maxoffset += 12*bitcount(fmask) + 4*bitcount(imask);
215: print(".align 2\n%s:link a6,#-%d\n", p->x.name, maxoffset + argbuildsize);
216: savemask[DREG] = usedmask[DREG]&eemask[DREG];
217: savemask[AREG] = usedmask[AREG]&eemask[AREG];
218: savemask[FREG] = usedmask[FREG]&eemask[FREG];
219: savebase[DREG] = -maxoffset;
220: savebase[AREG] = savebase[DREG] + 4*bitcount(savemask[DREG]);
221: savebase[FREG] = savebase[AREG] + 4*bitcount(savemask[AREG]);
222: if (fmask)
223: print("fmovemx #0x%x,a6@(%d)\n", fmask, -maxoffset + 4*bitcount(imask));
224: if (imask)
225: print("moveml #0x%x,a6@(%d)\n", imask, -maxoffset);
226: if (isstruct(freturn(p->type)))
227: print("movl a1,a6@(-4)\n");
228: if (pflag) {
229: int lab = genlabel(1);
230: print("movl #L%d,a0\njsr mcount\n", lab);
231: print("%s\n.even\nL%d: .skip 4\n.text\n", IR->x.segnames[BSS-1], lab);
232: }
233: emitcode();
234: if (ttob(p->type->type) == F)
235: print("fmoves fp0,d0\n");
236: else if (ttob(p->type->type) == D)
237: print("fmoved fp0,sp@-; movl sp@+,d0; movl sp@+,d1\n");
238: if (imask)
239: print("moveml a6@(%d),#0x%x\n", -maxoffset, imask);
240: if (fmask)
241: print("fmovemx a6@(%d),#0x%x\n", -maxoffset + 4*bitcount(imask), fmask);
242: print("unlk a6\nrts\n");
243: }
244:
245: /* global - global id */
246: static void global(p) Symbol p; {
247: assert(p->u.seg);
248: if (IR == &nextInterface && p->u.seg == BSS && Aflag >= 2) {
249: if (p->type->align > 1)
250: print(".align %d; ", p->type->align);
251: print("%s:.skip ", p->x.name);
252: } else if (p->u.seg == BSS && (p->sclass == STATIC || Aflag >= 2))
253: print(".lcomm %s,", p->x.name);
254: else if (p->u.seg == BSS)
255: print(".comm %s,", p->x.name);
256: else {
257: if (p->type->align > 1)
258: print(".align %d; ", p->type->align);
259: print("%s:", p->x.name);
260: }
261: }
262:
263: static void import(p) Symbol p; {}
264:
265: /* local - local */
266: static void local(p) Symbol p; {
267: if (getregvar(p, rmap[ttob(p->type)]) == 0)
268: p->x.name = stringd(mkauto(p, 4));
269: }
270:
271: /* progbeg - beginning of program */
272: static void progbeg(argc, argv) char *argv[]; {
273: nregsets = 3;
274: eemask[AREG] = 0x3c; eemask[DREG] = 0xfc; eemask[FREG] = 0xff;
275: tmask[AREG] = 0x07; tmask[DREG] = 0x1f; tmask[FREG] = 0x0f;
276: vmask[AREG] = 0x38; vmask[DREG] = 0xe0; vmask[FREG] = 0xf0;
277: parseflags(argc, argv);
278: kflag = IR == &nextInterface;
279: if (kflag)
280: IR->x.segnames[BSS-1] = ".data";
281: initgen();
282: a0 = mkregs("%d", 0, 0, 1, 1, AREG, P, 0);
283: a1 = mkregs("%d", 1, 1, 1, 1, AREG, P, 0);
284: d0 = mkregs("%d", 0, 0, 1, 1, DREG, I, 0);
285: d1234 = mkregs("%d", 1, 4, 1, 1, DREG, I, 0);
286: fp0 = mkregs("%d", 0, 0, 1, 1, FREG, D, 0);
287: rmap[P] = mkregs("%d", 0, 5, 1, 1, AREG, P, 0);
288: rmap[I] = mkregs("%d", 0, 7, 1, 1, DREG, I, 0);
289: rmap[D] = mkregs("%d", 0, 7, 1, 1, FREG, D, 0);
290: rmap[F] = rmap[D]; rmap[C] = rmap[S] = rmap[U] = rmap[I];
291: }
292:
293: static void segment(n) {
294: setseg(n);
295: }
296:
297: static void space(n) {
298: spacen(n, ".skip");
299: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.