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