|
|
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.