|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: (* sparcas.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 assembly code emitter. ! 13: *) ! 14: ! 15: structure SparcAsCode = ! 16: struct ! 17: val outfile = ref std_out ! 18: end (* SparcAsCode *) ! 19: ! 20: ! 21: structure SparcAsEmit : EMITTER = ! 22: struct ! 23: ! 24: open SparcAsCode SparcInstr ! 25: ! 26: (** The location counter **) ! 27: val loc = ref 0 ! 28: fun advance n = (loc := !loc + n) ! 29: fun advance4 () = (loc := !loc + 4) ! 30: ! 31: (** utility routines **) ! 32: local ! 33: val hexDigits = "0123456789abcdef" ! 34: fun f (0, l) = l ! 35: | f (n, l) = ( ! 36: f (Bits.rshift(n, 4), chr(ordof(hexDigits, Bits.andb(n, 15))) :: l)) ! 37: fun cvt 0 = ["0", "x", "0"] ! 38: | cvt n = ("0" :: "x" :: f(n, nil)) ! 39: in ! 40: fun atoi i = implode(if (i < 0) then "-" :: cvt(~i) else cvt i) ! 41: end ! 42: ! 43: fun emit s = output (!outfile) s ! 44: ! 45: fun newLine () = emit "\n" ! 46: ! 47: val emitLabel = emit o nameOf ! 48: ! 49: fun emitOffset 0 = () ! 50: | emitOffset i = (if (i < 0) ! 51: then (emit "-"; emit(atoi(~i))) ! 52: else (emit "+"; emit(atoi i))) ! 53: ! 54: ! 55: fun emitLong i = (emit "\t.long\t"; emit(atoi i); newLine(); advance4()) ! 56: ! 57: local ! 58: fun oct i = let ! 59: val m = Integer.makestring ! 60: in ! 61: m(i div 64)^m((i div 8)mod 8)^m(i mod 8) ! 62: end ! 63: fun c_char "\n" = "\\n" ! 64: | c_char "\t" = "\\t" ! 65: | c_char "\\" = "\\\\" ! 66: | c_char "\"" = "\\\"" ! 67: | c_char c = if ord c < 32 then "\\"^oct(ord c) else c ! 68: fun a_str s = implode(map c_char (explode s)) ! 69: in ! 70: fun emitString s = ( ! 71: emit "\t.ascii \""; emit(a_str s); emit "\"\n"; emit "\t.align\t4\n"; ! 72: advance(size s)) ! 73: end (* local *) ! 74: ! 75: fun emitReal r = (emit "\t.double\t"; emit r; newLine(); advance 8) ! 76: ! 77: fun emitAddr (lab as Label{addr = ref a, ...}, k) = ( ! 78: emit "\t.long\t("; emitLabel lab; emit "-.)"; emitOffset k; ! 79: emit "\t| "; emit(atoi(k + a - !loc)); newLine(); ! 80: advance4()) ! 81: ! 82: fun define (lab as Label{addr=ref a, ...}) = ( ! 83: (***** ! 84: emitLabel lab; emit ":\t| "; emit(atoi a); newLine()) ! 85: *****) ! 86: emitLabel lab; emit ":\t| .="; emit(atoi(!loc)); emit ", "; emit(atoi a); newLine()) ! 87: ! 88: local ! 89: open System.Tags ! 90: in ! 91: fun mark () = ( ! 92: emit "\t.long\t(((.-L0)/4+1)*power_tags)+tag_backptr\t| "; ! 93: emit (atoi (((!loc + 4) div 4) * power_tags + tag_backptr)); newLine(); ! 94: advance4()) ! 95: end (* local *) ! 96: ! 97: local ! 98: fun comma () = emit "," ! 99: ! 100: fun emitReg (REG i) = if (i < 16) ! 101: then if (i < 8) ! 102: then (emit "%g"; emit (makestring i)) ! 103: else (emit "%o"; emit (makestring (i-8))) ! 104: else if (i < 24) ! 105: then (emit "%l"; emit (makestring (i-16))) ! 106: else (emit "%i"; emit (makestring (i-24))) ! 107: ! 108: fun emitFReg (FREG i) = (emit "%f"; emit (makestring i)) ! 109: ! 110: fun emitCond EQL = emit "e" | emitCond NEQ = emit "ne" ! 111: | emitCond LSS = emit "l" | emitCond LEQ = emit "le" ! 112: | emitCond GTR = emit "g" | emitCond GEQ = emit "ge" ! 113: ! 114: fun emitLExp (LABELexp{base, dst, offset=0}) = ( ! 115: emitLabel dst; emit "-"; emitLabel base) ! 116: | emitLExp (LABELexp{base, dst, offset}) = ( ! 117: emit "("; emitLabel dst; emitOffset offset; emit ")-"; emitLabel base) ! 118: ! 119: fun emitRand (REGrand r) = emitReg r ! 120: | emitRand (IMrand i) = emit (atoi i) ! 121: | emitRand (LABrand lexp) = emitLExp lexp ! 122: | emitRand (LOrand lexp) = (emit "%lo("; emitLExp lexp; emit ")") ! 123: | emitRand (HIrand lexp) = (emit "%hi("; emitLExp lexp; emit ")") ! 124: ! 125: fun emitArgs (r1, arg, rd) = ( ! 126: emitReg r1; comma(); emitRand arg; comma(); emitReg rd) ! 127: ! 128: fun emitAddr (r1, b) = (emitReg r1; ! 129: case b ! 130: of REGrand(REG 0) => () ! 131: | REGrand r2 => (emit "+"; emitReg r2) ! 132: | IMrand i => emitOffset i ! 133: | LABrand l => (emit "+"; emitLExp l) ! 134: | LOrand l => (emit "+%lo("; emitLExp l; emit ")") ! 135: | _ => (ErrorMsg.impossible "[emitAddr]")) ! 136: ! 137: fun emitMemAddr args = (emit "["; emitAddr args; emit "]") ! 138: ! 139: fun emitFArgs (f1, f2, fd) = ( ! 140: emitFReg f1; comma(); emitFReg f2; comma(); emitFReg fd) ! 141: ! 142: in ! 143: ! 144: fun emitInstr I = ( ! 145: emit "\t"; ! 146: case I ! 147: of (I_nop) => emit "nop" ! 148: | (I_ld(a, b, c)) => (emit "ld "; emitMemAddr(a, b); comma(); emitReg c) ! 149: | (I_ldb(a, b, c)) => (emit "ldub "; emitMemAddr(a, b); comma(); emitReg c) ! 150: | (I_ldf(a, b, c)) => (emit "ldf "; emitMemAddr(a, b); comma(); emitFReg c) ! 151: | (I_st(a, b, c)) => (emit "st "; emitReg c; comma(); emitMemAddr(a, b)) ! 152: | (I_stb(a, b, c)) => (emit "stb "; emitReg c; comma(); emitMemAddr(a, b)) ! 153: | (I_stf(a, b, c)) => (emit "stf "; emitFReg c; comma(); emitMemAddr(a, b)) ! 154: | (I_sethi(x, rd)) => ( ! 155: emit "sethi "; ! 156: case x ! 157: of IMrand i => emit(atoi i) ! 158: | HIrand _ => emitRand x ! 159: | _ => ErrorMsg.impossible "[emitInstr.sethi]"; ! 160: comma(); emitReg rd) ! 161: | (I_ba l) => (emit "ba "; emitLabel l) ! 162: | (I_bcc(cc, l)) => (emit "b"; emitCond cc; emit " "; emitLabel l) ! 163: | (I_fbcc(cc, l)) => (emit "fb"; emitCond cc; emit " "; emitLabel l) ! 164: | (I_jmpl(a, b, REG 0)) => (emit "jmp "; emitAddr(a, b)) ! 165: | (I_jmpl(a, b, rd)) => (emit "jmpl "; emitAddr(a, b); comma(); emitReg rd) ! 166: | (I_add args) => (emit "add "; emitArgs args) ! 167: | (I_addcc args) => (emit "addcc "; emitArgs args) ! 168: | (I_taddcctv args) => (emit "taddcctv "; emitArgs args) ! 169: | (I_sub args) => (emit "sub "; emitArgs args) ! 170: | (I_subcc(a, b, REG 0)) => ( ! 171: emit "cmp "; emitReg a; comma(); ! 172: case b ! 173: of REGrand r2 => emitReg r2 ! 174: | IMrand i => emit(atoi i) ! 175: | _ => ErrorMsg.impossible "[emitInstr.addcc]") ! 176: | (I_subcc args) => (emit "subcc "; emitArgs args) ! 177: | (I_sll args) => (emit "sll "; emitArgs args) ! 178: | (I_sra args) => (emit "sra "; emitArgs args) ! 179: | (I_and args) => (emit "and "; emitArgs args) ! 180: | (I_andcc(a, b, REG 0)) => ( ! 181: emit "btst "; emitReg a; comma(); ! 182: case b ! 183: of REGrand r2 => emitReg r2 ! 184: | IMrand i => emit(atoi i) ! 185: | _ => ErrorMsg.impossible "[emitInstr.andcc]") ! 186: | (I_andcc args) => (emit "andcc "; emitArgs args) ! 187: | (I_or(REG 0, arg, rd)) => (emit "mov "; emitRand arg; comma(); emitReg rd) ! 188: | (I_or args) => (emit "or "; emitArgs args) ! 189: | (I_xor args) => (emit "xor "; emitArgs args) ! 190: | (I_not(r1, rd)) => (emit "not "; emitReg r1; comma(); emitReg rd) ! 191: | (I_tvs) => emit "tvs ST_INT_OVERFLOW" ! 192: | (I_fadd args) => (emit "faddd "; emitFArgs args) ! 193: | (I_fsub args) => (emit "fsubd "; emitFArgs args) ! 194: | (I_fmul args) => (emit "fmuld "; emitFArgs args) ! 195: | (I_fdiv args) => (emit "fdivd "; emitFArgs args) ! 196: | (I_fneg(f1, f2)) => (emit "fneg "; emitFReg f1; comma(); emitFReg f2) ! 197: | (I_fcmp(f1, f2)) => (emit "fcmp "; emitFReg f1; comma(); emitFReg f2) ! 198: (* end of case *); ! 199: emit "\t| .="; emit(atoi(!loc)); ! 200: newLine(); ! 201: advance4()) ! 202: ! 203: end (* local *) ! 204: ! 205: fun comment s = emit s ! 206: ! 207: fun init (n : int) = ( ! 208: loc := 0; ! 209: emit "| code size = "; emit(makestring n); emit " bytes\n") ! 210: ! 211: end (* structure SparcAsEmit *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.