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