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