Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /MLRISC/trunk/amd64/amd64MCFn.sml
ViewVC logotype

Annotation of /MLRISC/trunk/amd64/amd64MCFn.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3231 - (view) (download)

1 : mrainey 3231 (* amd64MCFn.sml
2 :     *
3 :     * Byte encoding for AMD64 instructions.
4 :     *)
5 :    
6 :     functor AMD64MCFn(
7 :     structure Instr : AMD64INSTR
8 :     structure Shuffle : AMD64SHUFFLE where I = Instr
9 :     structure MLTreeEval : MLTREE_EVAL where T = Instr.T
10 :     (* structure AsmEmitter : INSTRUCTION_EMITTER where I = Instr*)
11 :     ) : MC_EMIT =
12 :     struct
13 :    
14 :     structure I = Instr
15 :     structure C = I.C
16 :     structure Const = I.Constant
17 :     structure W32 = Word32
18 :     structure W8 = Word8
19 :     structure W = LargeWord
20 :     structure CB = CellsBasis
21 :    
22 :     val itow = Word.fromInt
23 :     val wtoi = Word.toInt
24 :    
25 :     fun const c = Int32.fromInt (Const.valueOf c)
26 :     fun lexp le = Int32.fromInt (MLTreeEval.valueOf le : int)
27 :    
28 :     val toWord8 = Word8.fromLargeWord o LargeWord.fromLargeInt o Int32.toLarge
29 :     val eBytes = Word8Vector.fromList
30 :     fun eByte i = eBytes [W8.fromInt i]
31 :     local
32 :     val toLWord = (W.fromLargeInt o Int32.toLarge)
33 :     fun shift (w,cnt) = W8.fromLargeWord(W.>>(w, cnt))
34 :     in
35 :     fun eShort i16 =
36 :     let val w = toLWord i16
37 :     in [shift(w, 0w0), shift(w,0w8)]
38 :     end
39 :     fun eLong i32 =
40 :     let val w = toLWord i32
41 :     in [shift(w, 0w0), shift(w,0w8), shift(w,0w16), shift(w,0w24)] end
42 :     end
43 :    
44 :     val regNum = CB.physicalRegisterNum
45 :    
46 :     val rsp = regNum C.rsp
47 :     val rbp = regNum C.rbp
48 :    
49 :     fun regNumBot8 r = r mod 8
50 :    
51 :     nonfix mod
52 :    
53 :     fun scale (n, m) = Word.toIntX(Word.<<(Word.fromInt n, Word.fromInt m))
54 :     fun modrm {mod, reg, rm} = W8.fromInt(scale(mod,6) + scale(reg,3) + rm)
55 :     fun sib {ss, index, base} = W8.fromInt(scale(ss,6) + scale(index,3) + base)
56 :    
57 :     type reg = int
58 :    
59 :     (* destination operands *)
60 :     datatype dst_opnd
61 :     = REG_OPND of reg
62 :     | OPCODE_OPND of int
63 :    
64 :     fun immedOpnd (I.Immed i32) = i32
65 :     | immedOpnd (I.ImmedLabel le) = lexp le
66 :     | immedOpnd (I.LabelEA le) = lexp le
67 :    
68 :     local
69 :    
70 :     datatype size = Zero | Bits8 | Bits32
71 :     fun size i =
72 :     if i = 0 then Zero
73 :     else if Int32.<(i, 128) andalso Int32.<=(~128, i) then Bits8
74 :     else Bits32
75 :    
76 :     (* register usage of an instruction *)
77 :     type reg_info = {indexReg : reg option, baseReg : reg option}
78 :     fun regsOfInstr (I.Direct(_, r)) = {indexReg=NONE, baseReg=SOME (regNum r)}
79 :     | regsOfInstr (I.Displace{base, ...}) = {indexReg=NONE, baseReg=SOME (regNum base)}
80 :     | regsOfInstr (I.Indexed {base=NONE, index, ...}) = {indexReg=SOME (regNum index), baseReg=NONE}
81 :     | regsOfInstr (I.Indexed {base=SOME b, index, ...}) = {indexReg=SOME (regNum b), baseReg=SOME (regNum index)}
82 :     | regsOfInstr _ = {indexReg=NONE, baseReg=NONE}
83 :    
84 :     (* to keep the destination operand at 3 bits, we truncate register operands; the upper bit goes in
85 :     * the rex byte.
86 :     *)
87 :     fun eDstOpnd (REG_OPND r) = regNumBot8 r
88 :     | eDstOpnd (OPCODE_OPND opc) = opc
89 :    
90 :     fun eImmedExt (dst, I.Direct (_, r)) =
91 :     [modrm{mod=3, reg=eDstOpnd dst, rm=regNumBot8(regNum r)}]
92 :     | eImmedExt (dst, I.Displace{base, disp, ...}) = let
93 :     val dst = eDstOpnd dst
94 :     val immed = immedOpnd disp
95 :     fun displace (mod, eDisp) =
96 :     if regNum base = rsp then
97 :     modrm{mod=mod, reg=dst, rm=4}::
98 :     sib{ss=0, index=4, base=rsp} :: eDisp immed
99 :     else
100 :     modrm{mod=mod, reg=dst, rm=regNum base} :: eDisp immed
101 :     in
102 :     case size immed
103 :     of Zero =>
104 :     if regNum base = rsp then
105 :     [modrm{mod=0, reg=dst, rm=4}, sib{ss=0,index=4,base=rsp}]
106 :     else if regNum base = rbp then
107 :     [modrm{mod=1, reg=dst, rm=rbp}, 0w0]
108 :     else
109 :     [modrm{mod=0, reg=dst, rm=regNum base}]
110 :     | Bits8 => displace (1, fn i => [toWord8 i])
111 :     | Bits32 => displace (2, eLong)
112 :     end
113 :    
114 :     fun eRex rb = raise Fail ""
115 :    
116 :     (* add the rex byte to an instruction over 32-bit operands *)
117 :     fun eRex32 (rb : Word8.word) = 0wx40 + rb
118 :     (* add the rex byte to an instruction over 64-bit operands *)
119 :     fun eRex64 rb = eRex rb + 0wx8
120 :    
121 :     fun isExtReg r = r > 7
122 :    
123 :     (* construct the rex byte depending on the operands *)
124 :     fun rexByte (REG_OPND dst, src) : Word8.word option = let
125 :     val {indexReg, baseReg} = regsOfInstr src
126 :     val rb1 = if isExtReg dst then 0wx4 else 0wx0
127 :     val rb2 = (case indexReg
128 :     of SOME r => if isExtReg r then rb1 + 0wx2 else rb1
129 :     | NONE => 0wx0
130 :     (* end case *))
131 :     val rb3 = (case baseReg
132 :     of SOME r => if isExtReg r then rb2 + 0wx1 else rb2
133 :     | NONE => 0wx0
134 :     (* end case *))
135 :     in
136 :     if rb3 = 0wx0 then NONE else SOME rb3
137 :     end
138 :    
139 :     fun encode32FromBytes (bytes, dst, src) = let
140 :     val e = eImmedExt(dst, src)
141 :     in
142 :     case rexByte (dst, src)
143 :     of SOME b => eRex32 b :: bytes @ e
144 :     | NONE => bytes @ e
145 :     end
146 :    
147 :    
148 :     in
149 :     (* encode an instruction with 32-bit operands *)
150 :     fun encode32 (byte1, dst, src) = eBytes(encode32FromBytes([byte1], dst, src))
151 :     fun encode64 x = raise Fail "todo"
152 :     end
153 :    
154 :     (* byte encoding of an instruction *)
155 :     fun eInstr instr = (
156 :     case instr
157 :     of I.UNARY{unOp, opnd} => (
158 :     case unOp
159 :     of I.INCL => encode32 (0wxff, OPCODE_OPND 0, opnd)
160 :     | I.INCQ => encode64 (0wxff, OPCODE_OPND 0, opnd)
161 :     | I.DECL => encode32 (0wxff, OPCODE_OPND 1, opnd)
162 :     | I.DECQ => encode64 (0wxff, OPCODE_OPND 1, opnd)
163 :     | I.NOTL => encode32 (0wxff, OPCODE_OPND 2, opnd)
164 :     | I.NOTQ => encode64 (0wxff, OPCODE_OPND 2, opnd)
165 :     | I.NEGL => encode32 (0wxff, OPCODE_OPND 3, opnd)
166 :     | I.NEGQ => encode64 (0wxff, OPCODE_OPND 3, opnd)
167 :     | _ => raise Fail "UNARY is not in DEC/INC/NEG,NOT"
168 :     (* esac *))
169 :     | _ => raise Fail "todo"
170 :     (* end case *))
171 :    
172 :     fun emitInstr _ = raise Fail "todo"
173 :    
174 :     end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0