|
|
1.1 root 1: /* C compiler: MC68020 code generator */
2:
3: #include "c.h"
4:
5: Symbol a0, a1, d0, d1, d1234, fp0;
6: char *segnames[] = {"text", 0, "data", "text", "data 2"};
7: unsigned eemask[] = {0x3c,0xfc,0xff};
8: unsigned tmask[] = {0x07,0x1f,0x0f};
9: unsigned vmask[] = {0x38,0xe0,0xf0};
10:
11: /* address - initialize q for addressing expression p+n */
12: void address(q, p, n) Symbol q, p; int n; {
13: q->x.offset = p->x.offset + n;
14: if (p->scope == GLOBAL || p->class == STATIC || p->class == EXTERN)
15: q->x.name = stringf("%s%s%d", p->x.name, n >= 0 ? "+" : "", n);
16: else
17: q->x.name = stringd(q->x.offset);
18: }
19:
20: /* asmname - print assembler code for symbol p (FIX) */
21: void asmname(p) Symbol p; {
22: if (p->class == REGISTER)
23: switch (ttob(p->type)) {
24: case P: print("a%s", p->x.name); break;
25: case F: case D: print("fp%s", p->x.name); break;
26: case I: case U: case C: case S: print("d%s", p->x.name); break;
27: default: assert(0);
28: }
29: else if (p->scope >= PARAM && p->class == AUTO)
30: print("%s(a6)", p->x.name);
31: else
32: print("_%s", p->x.name);
33: }
34:
35: /* defconst - define a constant */
36: void defconst(ty, v) Value v; {
37: switch (ty) {
38: case C: print("byte %d\n", v.uc); break;
39: case S: print("word %d\n", v.ss); break;
40: case I: print("long %d\n", v.i ); break;
41: case U: print("long 0x%x\n", v.u ); break;
42: case P: print("long 0x%x\n", v.p ); break;
43: case F:
44: if (v.f == 0.0)
45: print("long 0x0\n");
46: else {
47: struct real r;
48: r = decode(F, v.f);
49: r.exp = (r.exp + 127)&0xff;
50: print("long 0x%x\n", (r.sign<<31) | (r.exp<<23) | (r.msb>>9));
51: }
52: break;
53: case D:
54: if (v.d == 0.0)
55: print("long 0x0,0x0\n");
56: else {
57: struct real r;
58: r = decode(D, v.d);
59: r.exp = (r.exp + 1023)&0x7ff;
60: print("long 0x%x,0x%x\n", (r.sign<<31) | (r.exp<<20) | (r.msb>>12),
61: (r.msb<<20) | (r.lsb>>12));
62: }
63: break;
64: default:
65: assert(0);
66: }
67: }
68:
69: /* doarg - assign offset for next ARG node */
70: void doarg(p) Node p; {
71: assert(p);
72: assert(p->syms[0]);
73: assert(p->syms[1]);
74: p->syms[2] = intconst(mkactual(p->syms[1]->u.c.v.i, p->syms[0]->u.c.v.i, 4));
75: }
76:
77: /* docall - finalize a call */
78: void docall(p) Node p; {
79: if (argoffset > argbuildsize)
80: argbuildsize = argoffset;
81: p->syms[0] = intconst(argoffset);
82: argoffset = 0;
83: }
84:
85: /* function - generate code for a function */
86: void function(p, caller, callee, n) Symbol p, callee[], caller[]; {
87: int i;
88: unsigned fmask, imask;
89:
90: initfunc(n, 8, 0);
91: for (i = 0; callee[i]; i++) {
92: assert(caller[i]);
93: callee[i]->x.offset = caller[i]->x.offset = offset;
94: callee[i]->x.name = caller[i]->x.name = stringd(offset);
95: offset = roundup(offset + caller[i]->type->size, 4);
96: getregvar(callee[i], rmap[ttob(callee[i]->type)]);
97: }
98: assert(caller[i] == 0);
99: offset = 0;
100: gencode(caller, callee);
101: mvregvars();
102: fmask = 0;
103: if (usedmask[FREG])
104: for (i = 0; i < 8; i++)
105: if (usedmask[FREG]&(1<<i))
106: fmask |= 0x80>>i;
107: imask = (((usedmask[AREG]&eemask[AREG])<<8) | (usedmask[DREG]&eemask[DREG]));
108: maxoffset += 12*bitcount(fmask) + 4*bitcount(imask);
109: print("even\n_%s:link $a6,&-%d\n", p->x.name, maxoffset + argbuildsize);
110: if (fmask)
111: print("fmovemx &0x%x,%d($a6)\n", fmask, -maxoffset + 4*bitcount(imask));
112: if (imask)
113: print("movm.l &0x%x,%d($a6)\n", imask, -maxoffset);
114: if (isstruct(freturn(p->type)))
115: print("mov.l a1,-4($a6)\n");
116: if (pflag) {
117: int lab = genlabel(1);
118: print("mov.l &L%d,$a0\njsr mcount\n", lab);
119: print("%s\n.even\nL%d: .skip 4\n.text\n", segnames[BSS-1], lab);
120: }
121: emitcode();
122: if (ttob(p->type->type) == F)
123: print("fmoves fp0,d0\n");
124: else if (ttob(p->type->type) == D)
125: print("fmoved fp0,-($sp); movl ($sp)+,d0; movl ($sp)+,d1\n");
126: if (imask)
127: print("movm.l %d($a6),&0x%x\n", -maxoffset, imask);
128: if (fmask)
129: print("fmovemx %d($a6),&0x%x\n", -maxoffset + 4*bitcount(imask), fmask);
130: print("unlk $a6\nrts\n");
131: }
132:
133: /* global - global id */
134: void global(p) Symbol p; {
135: assert(p->u.seg);
136: if (p->u.seg == BSS && (p->class == STATIC || Aflag >= 2))
137: print("lcomm _%s,", p->x.name);
138: else if (p->u.seg == BSS)
139: print("comm _%s,", p->x.name);
140: else {
141: if (p->type->align > 1)
142: print("even; ");
143: print("_%s:", p->x.name);
144: }
145: }
146:
147: /* local - local */
148: void local(p) Symbol p; {
149: if (getregvar(p, rmap[ttob(p->type)]) == 0)
150: p->x.name = stringd(mkauto(p, 4));
151: }
152:
153: /* progbeg - beginning of program */
154: void progbeg(argc, argv) char *argv[]; {
155: parseflags(argc, argv);
156: if (kflag)
157: segnames[BSS-1] = "data";
158: initgen();
159: a0 = mkregs("%d", 0, 0, 1, 1, AREG, P, 0);
160: a1 = mkregs("%d", 1, 1, 1, 1, AREG, P, 0);
161: d0 = mkregs("%d", 0, 0, 1, 1, DREG, I, 0);
162: d1234 = mkregs("%d", 1, 4, 1, 1, DREG, I, 0);
163: fp0 = mkregs("%d", 0, 0, 1, 1, FREG, D, 0);
164: rmap[P] = mkregs("%d", 0, 5, 1, 1, AREG, P, 0);
165: rmap[I] = mkregs("%d", 0, 7, 1, 1, DREG, I, 0);
166: rmap[D] = mkregs("%d", 0, 7, 1, 1, FREG, D, 0);
167: rmap[F] = rmap[D]; rmap[C] = rmap[S] = rmap[U] = rmap[I];
168: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.