|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: (* sparcmc.sml ! 3: * ! 4: * J.H. Reppy ! 5: * Cornell University ! 6: * Ithaca, NY 14853 ! 7: * [email protected] ! 8: * ! 9: * HISTORY: ! 10: * 11/20/89 created ! 11: * ! 12: * The SPARC machine code emitter. ! 13: *) ! 14: ! 15: structure SparcMCode = ! 16: struct ! 17: local open ByteArray in ! 18: ! 19: val code = ref (array(0, 0)) ! 20: ! 21: fun getCodeString () = let ! 22: val s = extract (!code, 0, length (!code)) ! 23: in ! 24: code := array(0, 0); ! 25: s ! 26: end ! 27: ! 28: end (* local *) ! 29: end (* SparcMCode *) ! 30: ! 31: structure SparcMCEmit : EMITTER = ! 32: struct ! 33: ! 34: (* +DEBUG *) ! 35: fun diag (s : string) f x = (f x) handle e => ( ! 36: print "?exception "; print (System.exn_name e); ! 37: print " in SparcCM."; print s; print "\n"; ! 38: raise e) ! 39: (* -DEBUG *) ! 40: ! 41: open SparcMCode SparcInstr ! 42: ! 43: (* Bit-wise operations *) ! 44: val << = Bits.lshift ! 45: val >> = Bits.rshift ! 46: val ++ = Bits.orb ! 47: val & = Bits.andb ! 48: infix << >> ++ & ! 49: ! 50: val loc = ref 0 (* the location counter *) ! 51: ! 52: fun emitByte n = let ! 53: val i = !loc ! 54: in ! 55: loc := i+1; ByteArray.update (!code, i, n) ! 56: end ! 57: (* +DEBUG *) ! 58: handle ByteArray.Subscript => ( ! 59: print "?exception Subscript in SparcMCEmit.emitByte. loc = "; ! 60: print(!loc); print "\n"; ! 61: raise ByteArray.Subscript) ! 62: (* -DEBUG *) ! 63: (* DEBUG *) val emitByte = diag "emitByte" emitByte ! 64: ! 65: fun emitWord n = if (n < 0) ! 66: then emitWord (n + 65536) ! 67: else (emitByte (n >> 8); emitByte (n & 255)) ! 68: ! 69: fun emitLong n = if (n < 0) ! 70: then let ! 71: val a = ~n ! 72: val b = (a >> 16) ! 73: val c = (a & 65535); ! 74: in ! 75: emitWord (~c + (if b = 0 then 0 else ~1)); emitWord (~b) ! 76: end ! 77: else (emitWord(n >> 16); emitWord (n & 65535)) ! 78: ! 79: fun emitString s = let ! 80: fun copy i = (emitByte(ordof(s, i)); copy(i+1)) ! 81: in ! 82: (copy 0) handle Ord => () ! 83: end ! 84: ! 85: structure IEEERealConst = RealConst(IEEEReal(val emitWord = emitWord)) ! 86: ! 87: val emitReal = IEEERealConst.realconst ! 88: ! 89: fun emitAddr (lab as Label{addr = ref a, ...}, k) = emitLong (k + a - !loc) ! 90: ! 91: fun define _ = () ! 92: ! 93: local ! 94: open System.Tags ! 95: in ! 96: fun mark () = emitLong (((!loc + 4) div 4) * power_tags + tag_backptr) ! 97: end (* local *) ! 98: ! 99: local ! 100: ! 101: fun valOf (LABELexp{base, dst, offset}) = ((addrOf dst) + offset) - (addrOf base) ! 102: ! 103: fun immed13 (IMrand i) = (i & 8191) (* 13 bits *) ! 104: | immed13 (LABrand labexp) = ((valOf labexp) & 8191) (* 13 bits *) ! 105: | immed13 (LOrand labexp) = ((valOf labexp) & 1023) (* 10 bits *) ! 106: | immed13 _ = ErrorMsg.impossible "[SparcMCEmit.immed13]" ! 107: ! 108: (* emit a 3 operand instruction with "11" in bits 31-30 *) ! 109: fun emitOp11 opcode (REG a, REGrand(REG b), REG c) = ( ! 110: emitWord(49152 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2)); ! 111: emitWord(((a & 3) << 14) ++ b)) ! 112: | emitOp11 opcode (REG a, b, REG c) = ( ! 113: emitWord(49152 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2)); ! 114: emitWord(((a & 3) << 14) ++ 8192 ++ (immed13 b))) ! 115: ! 116: val emit_ld = emitOp11 0 ! 117: val emit_st = emitOp11 4 ! 118: val emit_ldb = emitOp11 1 ! 119: val emit_stb = emitOp11 5 ! 120: fun emit_ldf (r, ri, FREG fr) = emitOp11 32 (r, ri, REG fr) ! 121: fun emit_stf (r, ri, FREG fr) = emitOp11 36 (r, ri, REG fr) ! 122: ! 123: (* emit a branch instruction *) ! 124: fun emitBcc opcode lab = let ! 125: val disp = (((addrOf lab) - !loc) div 4) ! 126: val d = if disp < 0 then (disp + 4194304) else disp ! 127: in ! 128: if ((disp < ~2097152) orelse (2097152 <= disp)) ! 129: then ErrorMsg.impossible "[SparcMCEmit.emitBcc]" else (); ! 130: emitLong ((opcode << 22) ++ d) ! 131: end ! 132: ! 133: val emit_ba = emitBcc 66 (* 1000010 *) ! 134: val emit_be = emitBcc 10 (* 0001010 *) ! 135: val emit_bne = emitBcc 74 (* 1001010 *) ! 136: val emit_ble = emitBcc 18 (* 0010010 *) ! 137: val emit_bge = emitBcc 90 (* 1011010 *) ! 138: val emit_bl = emitBcc 26 (* 0011010 *) ! 139: val emit_bg = emitBcc 82 (* 1010010 *) ! 140: val emit_fbe = emitBcc 78 (* 1001110 *) ! 141: val emit_fbne = emitBcc 14 (* 0001110 *) ! 142: val emit_fble = emitBcc 110 (* 1101110 *) ! 143: val emit_fbge = emitBcc 94 (* 1011110 *) ! 144: val emit_fbl = emitBcc 38 (* 0100110 *) ! 145: val emit_fbg = emitBcc 54 (* 0110110 *) ! 146: ! 147: (* emit a 3 operand instructions with "10" in bits 31-30. *) ! 148: fun emitOp10 opcode (REG a, REGrand(REG b), REG c) = ( ! 149: emitWord(32768 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2)); ! 150: emitWord(((a & 3) << 14) ++ b)) ! 151: | emitOp10 opcode (REG a, b, REG c) = ( ! 152: emitWord(32768 ++ (c << 9) ++ (opcode << 3) ++ (a >> 2)); ! 153: emitWord(((a & 3) << 14) ++ 8192 ++ (immed13 b))) ! 154: ! 155: val emit_jmpl = emitOp10 56 (* 111000 *) ! 156: ! 157: (* integer operations *) ! 158: val emit_add = emitOp10 0 (* 000000 *) ! 159: val emit_addcc = emitOp10 16 (* 010000 *) ! 160: val emit_taddcctv = emitOp10 34 (* 100010 *) ! 161: val emit_sub = emitOp10 4 (* 000100 *) ! 162: val emit_subcc = emitOp10 20 (* 010100 *) ! 163: val emit_sll = emitOp10 37 (* 100101 *) ! 164: val emit_sra = emitOp10 39 (* 100111 *) ! 165: val emit_and = emitOp10 1 (* 000001 *) ! 166: val emit_andcc = emitOp10 17 (* 010001 *) ! 167: val emit_or = emitOp10 2 (* 000010 *) ! 168: val emit_xor = emitOp10 3 (* 000011 *) ! 169: val emit_xnor = emitOp10 7 (* 000111 *) ! 170: ! 171: (* emit a floating-point instruction of three args; this has "10" in ! 172: * bits 31-30 and "110100" in bits 24-19. ! 173: *) ! 174: fun emitFOp3 opcode (FREG a, FREG b, FREG c) = ( ! 175: emitWord (33184 ++ (c << 9) ++ (a >> 2)); ! 176: emitWord (((a & 3) << 14) ++ (opcode << 5) ++ b)) ! 177: (* emit a 2 operand floating-point instruction (same bits as above) *) ! 178: fun emitFOp2 opcode (FREG a, FREG b) = ( ! 179: emitWord (33184 ++ (b << 9)); ! 180: emitWord ((opcode << 5) ++ a)) ! 181: (* emit a 2 operand floating-point instruction with "110101" in bits 24-19. *) ! 182: fun emitFOp2' opcode (FREG a, FREG b) = ( ! 183: emitWord (33192 ++ (a >> 2)); ! 184: emitWord (((a & 3) << 14) ++ (opcode << 5) ++ b)) ! 185: val emit_fadd = emitFOp3 66 (* 001000010 *) ! 186: val emit_fsub = emitFOp3 70 (* 001000110 *) ! 187: val emit_fmul = emitFOp3 74 (* 001001010 *) ! 188: val emit_fdiv = emitFOp3 78 (* 001001110 *) ! 189: val emit_fneg = emitFOp2 5 (* 000000101 *) ! 190: val emit_fcmp = emitFOp2' 82 (* 001010010 *) ! 191: in ! 192: ! 193: fun emitInstr (I_nop) = emitLong 16777216 (* really "sethi 0,%g0" *) ! 194: | emitInstr (I_ld args) = emit_ld args ! 195: | emitInstr (I_ldb args) = emit_ldb args ! 196: | emitInstr (I_ldf args) = emit_ldf args ! 197: | emitInstr (I_st args) = emit_st args ! 198: | emitInstr (I_stb args) = emit_stb args ! 199: | emitInstr (I_stf args) = emit_stf args ! 200: | emitInstr (I_sethi(arg, REG rd)) = let ! 201: val im = case arg ! 202: of (IMrand i) => i ! 203: | (HIrand labexp) => ((valOf labexp) >> 10) ! 204: | _ => ErrorMsg.impossible "[SparcMCEmit.emitInstr:sethi]" ! 205: in ! 206: emitWord(256 ++ (rd << 9) ++ ((im >> 16) & 63)); ! 207: emitWord(im & 65535) ! 208: end ! 209: | emitInstr (I_ba lab) = emit_ba lab ! 210: | emitInstr (I_bcc(EQL, lab)) = emit_be lab ! 211: | emitInstr (I_bcc(NEQ, lab)) = emit_bne lab ! 212: | emitInstr (I_bcc(LSS, lab)) = emit_bl lab ! 213: | emitInstr (I_bcc(LEQ, lab)) = emit_ble lab ! 214: | emitInstr (I_bcc(GTR, lab)) = emit_bg lab ! 215: | emitInstr (I_bcc(GEQ, lab)) = emit_bge lab ! 216: | emitInstr (I_fbcc(EQL, lab)) = emit_fbe lab ! 217: | emitInstr (I_fbcc(NEQ, lab)) = emit_fbne lab ! 218: | emitInstr (I_fbcc(LSS, lab)) = emit_fbl lab ! 219: | emitInstr (I_fbcc(LEQ, lab)) = emit_fble lab ! 220: | emitInstr (I_fbcc(GTR, lab)) = emit_fbg lab ! 221: | emitInstr (I_fbcc(GEQ, lab)) = emit_fbge lab ! 222: | emitInstr (I_jmpl args) = emit_jmpl args ! 223: | emitInstr (I_add args) = emit_add args ! 224: | emitInstr (I_addcc args) = emit_addcc args ! 225: | emitInstr (I_taddcctv args) = emit_taddcctv args ! 226: | emitInstr (I_sub args) = emit_sub args ! 227: | emitInstr (I_subcc args) = emit_subcc args ! 228: | emitInstr (I_sll args) = emit_sll args ! 229: | emitInstr (I_sra args) = emit_sra args ! 230: | emitInstr (I_and args) = emit_and args ! 231: | emitInstr (I_andcc args) = emit_andcc args ! 232: | emitInstr (I_or args) = emit_or args ! 233: | emitInstr (I_xor args) = emit_xor args ! 234: | emitInstr (I_not(r1, rd)) = emit_xnor (r1, REGrand(REG 0), rd) ! 235: | emitInstr (I_tvs) = (emitWord 36816; emitWord 8199) (* "tvs 0x7" *) ! 236: | emitInstr (I_fadd args) = emit_fadd args ! 237: | emitInstr (I_fsub args) = emit_fsub args ! 238: | emitInstr (I_fmul args) = emit_fmul args ! 239: | emitInstr (I_fdiv args) = emit_fdiv args ! 240: | emitInstr (I_fneg args) = emit_fneg args ! 241: | emitInstr (I_fcmp args) = emit_fcmp args ! 242: (* DEBUG *) val emitInstr = diag "emitInstr" emitInstr ! 243: ! 244: end (* local *) ! 245: ! 246: fun comment _ = () ! 247: ! 248: fun init n = (code := ByteArray.array(n, 0); loc := 0) ! 249: ! 250: end (* structure SparcMCEmit *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.