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/instructions/amd64Props.sml
ViewVC logotype

Annotation of /MLRISC/trunk/amd64/instructions/amd64Props.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2810 - (view) (download)

1 : mrainey 2619 (* amd64Props.sml
2 :     *
3 :     * This functor encodes semantic information of instructions.
4 :     *
5 :     *)
6 :    
7 :     signature AMD64INSN_PROPERTIES =
8 :     sig
9 :     include INSN_PROPERTIES
10 :     (* returns the bit width of an instruction's source operand *)
11 :     val szOfInstr : I.instr -> int
12 :     (* returns the bit width of an floating-point instruction's source operand *)
13 :     val szOfFinstr : I.instr -> int
14 :     end
15 :    
16 :     functor AMD64Props (
17 :     structure Instr : AMD64INSTR
18 :     structure MLTreeHash : MLTREE_HASH
19 :     where T = Instr.T
20 :     structure MLTreeEval : MLTREE_EVAL
21 :     where T = Instr.T
22 :     ) : AMD64INSN_PROPERTIES =
23 :     struct
24 :    
25 :     structure I = Instr
26 :     structure C = I.C
27 :     structure T = I.T
28 :     structure CB = CellsBasis
29 :    
30 :     exception NegateConditional
31 :    
32 :     fun error msg = MLRiscErrorMsg.error("AMD64Props",msg)
33 :    
34 :     datatype kind = IK_JUMP | IK_NOP | IK_INSTR | IK_COPY | IK_CALL
35 :     | IK_CALL_WITH_CUTS | IK_PHI | IK_SOURCE | IK_SINK
36 :     datatype target = LABELLED of Label.label | FALLTHROUGH | ESCAPES
37 :    
38 :     fun instrKind (I.ANNOTATION {i, ...}) = instrKind i
39 :     | instrKind (I.COPY _) = IK_COPY
40 :     | instrKind (I.INSTR instr) = (case instr
41 :     of I.NOP => IK_NOP
42 :     | ( I.CALL {cutsTo=_::_, ...} | I.CALLQ {cutsTo=_::_, ...} ) =>
43 :     IK_CALL_WITH_CUTS
44 : mrainey 2781 | ( I.JMP _ | I.JCC _ | I.RET _ | I.INTO ) => IK_JUMP
45 : mrainey 2619 | ( I.CALL _ | I. CALLQ _ ) => IK_CALL
46 :     | I.PHI {} => IK_PHI
47 :     | I.SOURCE {} => IK_SOURCE
48 :     | I.SINK {} => IK_SINK
49 :     | _ => IK_INSTR
50 :     (* end case *))
51 :     | instrKind _ = IK_INSTR
52 :    
53 :     fun moveInstr (I.ANNOTATION {i, ...}) = moveInstr i
54 :     | moveInstr (I.COPY _) = true
55 :     | moveInstr _ = false
56 :    
57 :     fun moveTmpR (I.ANNOTATION {i, ...}) = moveTmpR i
58 :     | moveTmpR ( I.COPY {k=CB.GP, tmp=SOME (I.Direct (_, r)), ...}
59 :     | I.COPY {k=CB.FP, tmp=SOME (I.FDirect r), ...} ) =
60 :     SOME r
61 :     | moveTmpR _ = NONE
62 :    
63 :     fun moveDstSrc (I.ANNOTATION {i, ...}) = moveDstSrc i
64 :     | moveDstSrc (I.COPY {dst, src, ...}) = (dst, src)
65 :     | moveDstSrc _ = error "AMD64Props.moveDstSrc"
66 :    
67 :     fun nop () = I.nop
68 :    
69 :     fun jump l = I.jmp (I.ImmedLabel (T.LABEL l), [l])
70 :    
71 :     fun branchTargets(I.ANNOTATION{i,...}) = branchTargets i
72 :     | branchTargets(I.INSTR i) = (case i
73 :     of I.JMP(_, []) => [ESCAPES]
74 :     | I.JMP(_, labs) => map LABELLED labs
75 :     | I.RET _ => [ESCAPES]
76 :     | I.JCC{opnd=I.ImmedLabel(T.LABEL(lab)), ...} =>
77 :     [FALLTHROUGH, LABELLED lab]
78 :     | I.CALL{cutsTo, ...} => FALLTHROUGH :: map LABELLED cutsTo
79 :     | I.CALLQ{cutsTo, ...} => FALLTHROUGH :: map LABELLED cutsTo
80 :     | I.INTO => [ESCAPES]
81 :     | _ => error "branchTargets")
82 :     | branchTargets _ = error "branchTargets"
83 :    
84 :     fun jump label = I.jmp (I.ImmedLabel(T.LABEL label), [label])
85 :    
86 :     fun setJumpTarget(I.ANNOTATION {a,i}, l) =
87 :     I.ANNOTATION {a=a, i=setJumpTarget (i, l)}
88 :     | setJumpTarget(I.INSTR (I.JMP (I.ImmedLabel _, _)), lab) = jump lab
89 :     | setJumpTarget _ = error "setJumpTarget"
90 :    
91 :     fun setBranchTargets{i=I.ANNOTATION{a,i}, t, f} =
92 :     I.ANNOTATION{a=a, i=setBranchTargets{i=i, t=t, f=f}}
93 :     | setBranchTargets{i=I.INSTR(I.JCC{cond,opnd=I.ImmedLabel _}), t, ...} =
94 :     I.jcc{cond=cond,opnd=I.ImmedLabel(T.LABEL t)}
95 :     | setBranchTargets _ = error "setBranchTargets"
96 :    
97 :     val immedRange={lo= ~1073741824, hi=1073741823}
98 :     val toInt32 = Int32.fromLarge o Int.toLarge
99 :     (* immediates are restricted to 32 bits *)
100 :     fun loadImmed {immed, t} =
101 :     I.move {mvOp=I.MOVL, src=I.Immed (toInt32 immed), dst=I.Direct (32, t)}
102 :     fun loadOperand {opn, t} = I.move {mvOp=I.MOVQ, src=opn, dst=I.Direct (64, t)}
103 :    
104 :     fun hashOpn(I.Immed i) = Word.fromInt(Int32.toInt i)
105 :     | hashOpn(I.ImmedLabel le) = MLTreeHash.hash le + 0w123
106 :     | hashOpn(I.Relative i) = Word.fromInt i + 0w1232
107 :     | hashOpn(I.LabelEA le) = MLTreeHash.hash le + 0w44444
108 :     | hashOpn(I.Direct (_, r)) = CB.hashCell r
109 :     | hashOpn(I.FDirect f) = CB.hashCell f + 0w31245
110 :     | hashOpn(I.Displace {base, disp, ...}) =
111 :     hashOpn disp + CB.hashCell base
112 :     | hashOpn(I.Indexed {base, index, scale, disp, ...}) =
113 :     CB.hashCell index + Word.fromInt scale + hashOpn disp
114 :     fun eqOpn(I.Immed a,I.Immed b) = a = b
115 :     | eqOpn(I.ImmedLabel a,I.ImmedLabel b) = MLTreeEval.==(a,b)
116 :     | eqOpn(I.Relative a,I.Relative b) = a = b
117 :     | eqOpn(I.LabelEA a,I.LabelEA b) = MLTreeEval.==(a,b)
118 :     | eqOpn(I.Direct (_,a),I.Direct (_,b)) = CB.sameColor(a,b)
119 :     | eqOpn(I.FDirect a,I.FDirect b) = CB.sameColor(a,b)
120 :     | eqOpn(I.Displace{base=a,disp=b,...},I.Displace{base=c,disp=d,...}) =
121 :     CB.sameColor(a,c) andalso eqOpn(b,d)
122 :     | eqOpn(I.Indexed{base=a,index=b,scale=c,disp=d,...},
123 :     I.Indexed{base=e,index=f,scale=g,disp=h,...}) =
124 :     CB.sameColor(b,f) andalso c = g
125 :     andalso sameCellOption(a,e) andalso eqOpn(d,h)
126 :     | eqOpn _ = false
127 :     and sameCellOption(NONE, NONE) = true
128 :     | sameCellOption(SOME x, SOME y) = CB.sameColor(x,y)
129 :     | sameCellOption _ = false
130 :    
131 :     fun negateConditional (I.ANNOTATION{i,a}, lab) =
132 :     I.ANNOTATION{i=negateConditional(i,lab), a=a}
133 :     | negateConditional (I.INSTR(I.JCC{cond,
134 :     opnd=I.ImmedLabel(T.LABEL _)}), lab) = let
135 :     val cond' = (case cond
136 :     of I.EQ => I.NE
137 :     | I.NE => I.EQ
138 :     | I.LT => I.GE
139 :     | I.LE => I.GT
140 :     | I.GT => I.LE
141 :     | I.GE => I.LT
142 :     | I.B => I.AE
143 :     | I.BE => I.A
144 :     | I.A => I.BE
145 :     | I.AE => I.B
146 :     | I.C => I.NC
147 :     | I.NC => I.C
148 :     | I.P => I.NP
149 :     | I.NP => I.P
150 :     | I.O => I.NO
151 :     | I.NO => I.O
152 :     (* end case *))
153 :     in
154 :     I.INSTR(I.JCC{cond=cond', opnd=I.ImmedLabel(T.LABEL lab)})
155 :     end
156 :     | negateConditional _ = error "AMD64Props.negateConditional"
157 :    
158 :     val raxPair = [C.rdx, C.rax]
159 :    
160 :     fun defUseR i = let
161 :     fun operandAcc (opnd, acc) = (case opnd
162 :     of I.Direct (_, r) => r :: acc
163 :     | I.Displace {base, ...} => base :: acc
164 :     | I.Indexed {base=NONE, index, ...} => index :: acc
165 :     | I.Indexed {base=SOME b, index, ...} => b :: index :: acc
166 :     | _ => acc
167 :     (* end case *))
168 :     fun operandUse opnd = operandAcc (opnd, [])
169 :     fun operandDef (I.Direct (_, r)) = [r]
170 :     | operandDef _ = []
171 :     fun cmpTest {lsrc, rsrc} = ([], operandAcc (lsrc, operandUse rsrc))
172 :     fun unary opnd = (operandDef opnd, operandUse opnd)
173 :     fun multDiv {src, multDivOp} = let
174 :     val uses = operandUse src
175 :     in
176 :     case multDivOp
177 :     of (I.IDIVL1 | I.DIVL1 | I.IDIVQ1 | I.DIVQ1) =>
178 :     (raxPair, C.rdx::C.rax::uses)
179 :     | (I.IMULL1 | I.MULL1 | I.IMULQ1 | I.MULQ1) =>
180 :     (raxPair, C.rax::uses)
181 :     (* end case *)
182 :     end
183 :     fun rspOnly () = let val s = [C.stackptrR] in (s, s) end
184 :     fun push opnd = ([C.stackptrR], operandAcc (opnd, [C.stackptrR]))
185 :     fun f i = (case i
186 :     of ( I.JMP (opnd, _) | I.JCC {opnd, ...} ) => ([], operandUse opnd)
187 :     | ( I.CALL {opnd, defs, uses, ...} |
188 :     I.CALLQ {opnd, defs, uses, ...} )=>
189 :     (C.getReg defs, operandAcc (opnd, C.getReg uses))
190 :     | I.MOVE {src, dst=I.Direct (_, r), ...} => ([r], operandUse src)
191 :     | I.MOVE {src, dst, ...} => ([], operandAcc (dst, operandUse src))
192 :     | ( I.LEAL {r32=r, addr} | I.LEAQ {r64=r, addr} ) =>
193 :     ([r], operandUse addr)
194 :     | ( I.CMPQ arg | I.CMPL arg | I.CMPW arg | I.CMPB arg
195 :     | I.TESTQ arg | I.TESTL arg | I.TESTW arg | I.TESTB arg ) =>
196 :     cmpTest arg
197 :     | I.BITOP{lsrc, rsrc, ...} => cmpTest {lsrc=lsrc,rsrc=rsrc}
198 :     | I.BINARY{binOp=I.XORL, src=I.Direct (_,rs),
199 :     dst=I.Direct (_,rd),...} =>
200 :     if CB.sameColor(rs,rd) then ([rd],[]) else ([rd],[rs,rd])
201 :     | I.BINARY{binOp=I.XORQ, src=I.Direct (_,rs),
202 :     dst=I.Direct (_,rd),...} =>
203 :     if CB.sameColor(rs,rd) then ([rd],[]) else ([rd],[rs,rd])
204 :     | I.BINARY {src, dst,...} =>
205 :     (operandDef dst, operandAcc (src, operandUse dst))
206 :     | I.SHIFT {src,dst,count,...} =>
207 :     (operandDef dst,
208 :     operandAcc(count, operandAcc (src, operandUse dst)))
209 : mrainey 2805 | I.XADD {src, dst, ...} =>
210 : mrainey 2810 (operandAcc (src, operandDef dst), operandAcc (src, operandUse dst))
211 : mrainey 2619 | I.CMPXCHG {src, dst, ...} =>
212 :     (C.rax::operandDef dst, C.rax::operandAcc (src, operandUse dst))
213 :     | ( I.ENTER _ | I.LEAVE ) => ([C.rsp, C.rbp], [C.rsp, C.rbp])
214 :     | I.MULTDIV arg => multDiv arg
215 :     | ( I.MUL3 {src1, dst, ...} | I.MULQ3 {src1, dst, ...} ) =>
216 :     ([dst], operandUse src1)
217 :     | ( I.UNARY{opnd, ...} | I.SET {opnd, ...} ) => unary opnd
218 :     | (I.PUSHQ arg | I.PUSHL arg | I.PUSHW arg | I.PUSHB arg ) => push arg
219 :     | I.POP arg => (C.stackptrR::operandDef arg, [C.stackptrR])
220 :     | ( I.PUSHFD | I.POPFD )=> rspOnly ()
221 :     | I.CDQ => ([C.rdx], [C.rax])
222 :     | I.FMOVE {dst, src, ...} => ([], operandAcc (dst, operandUse src))
223 :     | I.FCOM {src, ...} => ([], operandUse src)
224 :     | I.SAHF => ([], [C.rax])
225 :     | I.LAHF => ([C.rax], [])
226 :     (* This sets the low order byte,
227 :     * do potentially it may define *and* use
228 :     *)
229 :     | I.CMOV {src, dst,...} => ([dst], operandAcc(src, [dst]))
230 :     | _ => ([], [])
231 :     (* end case *))
232 :     in
233 :     case i
234 :     of I.ANNOTATION {i, ...} => defUseR i
235 :     | I.LIVE {regs, ...} => ([], C.getReg regs)
236 :     | I.KILL {regs, ...} => (C.getReg regs, [])
237 :     | I.COPY {k=CB.GP, src, dst, tmp, ...} => (case tmp
238 :     of SOME (I.Direct (_, t)) => (t :: dst, src)
239 :     | SOME ea => (dst, operandAcc (ea, src))
240 :     | NONE => (dst, src)
241 :     (* end case *))
242 :     | I.COPY _ => ([], [])
243 :     | I.INSTR i => f i
244 :     (* end case *)
245 :     end (* defUseR *)
246 :    
247 :     fun defUseF i = let
248 :     fun operandAcc (I.FDirect r, acc) = r :: acc
249 :     | operandAcc (_, acc) = acc
250 :     fun operand opnd = operandAcc (opnd, [])
251 :     fun f i = (case i
252 :     of I.FMOVE {dst, src, ...} => (operand dst, operand src)
253 :     | I.FBINOP {dst, src, ...} => ([dst], [src])
254 : mrainey 2808 | ( I.XORPS {dst, src} | I.XORPD {dst, src} ) => (operand dst, operand src)
255 : mrainey 2619 | I.FCOM {dst, src, ...} => ([dst], operand src)
256 : mrainey 2638 | ( I.FSQRTS {dst, src} | I.FSQRTD {dst, src} )=>
257 :     (operand dst, operand src)
258 : mrainey 2619 | ( I.CALL {defs, uses, ...} | I.CALLQ {defs, uses, ...} ) =>
259 :     (C.getFreg defs, C.getFreg uses)
260 :     | _ => ([], [])
261 :     (* end case *))
262 :     in
263 :     case i
264 :     of I.ANNOTATION {i, ...} => defUseF i
265 :     | I.LIVE {regs, ...} => ([], C.getFreg regs)
266 :     | I.KILL {regs, ...} => (C.getFreg regs, [])
267 :     | I.COPY {k=CB.FP, src, dst, tmp, ...} => (case tmp
268 :     of SOME (I.FDirect t) => (t :: dst, src)
269 :     | SOME ea => (dst, operandAcc (ea, src))
270 :     | NONE => (dst, src)
271 :     (* end case *))
272 :     | I.COPY _ => ([], [])
273 :     | I.INSTR i => f i
274 :     (* end case *)
275 :     end (* defUseF *)
276 :    
277 :     fun defUse CB.GP = defUseR
278 :     | defUse CB.FP = defUseF
279 :     | defUse _ = error "defUse"
280 :    
281 :     fun getAnnotations (I.ANNOTATION {i, a}) = let
282 :     val (i, an) = getAnnotations i
283 :     in
284 :     (i, a::an)
285 :     end
286 :     | getAnnotations i = (i,[])
287 :    
288 :     fun annotate (i, a) = I.ANNOTATION {i=i, a=a}
289 :    
290 : mrainey 2810 fun szToInt I.I8 = 8
291 :     | szToInt I.I16 = 16
292 :     | szToInt I.I32 = 32
293 :     | szToInt I.I64 = 64
294 :    
295 : mrainey 2619 fun replicate(I.ANNOTATION{i,a}) = I.ANNOTATION{i=replicate i,a=a}
296 :     (* FIXME? *)
297 :     (* | replicate(I.COPY{tmp=SOME _, dst, src}) =
298 :     I.COPY{tmp=SOME(I.Direct(C.newReg())), dst=dst, src=src}
299 :     | replicate(I.FCOPY{tmp=SOME _, dst, src}) =
300 :     I.FCOPY{tmp=SOME(I.FDirect(C.newFreg())), dst=dst, src=src} *)
301 :     | replicate i = i
302 :    
303 :     (* determine the bit width of an instruction *)
304 :     fun szOfInstr instr = (case instr
305 :     of I.JCC _ => 32
306 : mrainey 2783 (* NOTE: CMOV encodes operand length in its operands! *)
307 :     | I.CMOV {src=I.Direct (sz, _), ...} => sz
308 : mrainey 2619 | I.MOVE {mvOp, ...} =>
309 :     (case mvOp
310 :     of ( I.MOVQ | I.MOVSWQ | I.MOVZWQ | I.MOVSBQ |
311 :     I.MOVZBQ | I.MOVSLQ ) => 64
312 :     | ( I.MOVL | I.MOVSWL | I.MOVZWL | I.MOVSBL |
313 :     I.MOVZBL ) => 32
314 :     | I.MOVW => 16
315 :     | I.MOVB => 8
316 :     (* esac *))
317 : mrainey 2783 | ( I.CALL _ | I.LEAL _ | I.CMPL _ | I.TESTL _ | I.MUL3 _ )
318 : mrainey 2619 => 32
319 : mrainey 2783 | ( I.CALLQ _ | I.LEAQ _ | I.CMPQ _ | I.TESTQ _ | I.MULQ3 _ | I.CMOV _)
320 : mrainey 2619 => 64
321 :     | ( I.CMPW _ | I.TESTW _ ) => 16
322 :     | ( I.CMPB _ | I.TESTB _ ) => 8
323 :     | I.SHIFT {shiftOp, ...} => (case shiftOp
324 :     of ( I.SHLDL | I.SHRDL ) => 32
325 :     (* esac *))
326 :     | I.UNARY {unOp, ...} =>
327 :     (case unOp
328 :     of ( I.DECQ | I.INCQ | I.NEGQ | I.NOTQ |
329 :     I.LOCK_DECQ | I.LOCK_INCQ | I.LOCK_NEGQ | I.LOCK_NOTQ ) => 64
330 :     | ( I.DECL | I.INCL | I.NEGL | I.NOTL ) => 32
331 :     | ( I.DECW | I.INCW | I.NEGW | I.NOTW ) => 16
332 :     | ( I.DECB | I.INCB | I.NEGB | I.NOTB ) => 8
333 :     (* esac *))
334 :     | I.MULTDIV {multDivOp, ...} =>
335 :     (case multDivOp
336 :     of ( I.IMULL1 | I.MULL1 | I.IDIVL1 | I.DIVL1 ) => 32
337 :     | ( I.IMULQ1 | I.MULQ1 | I.IDIVQ1 | I.DIVQ1 ) => 64
338 :     (* esac *))
339 :     | I.BINARY {binOp, ...} =>
340 :     (case binOp
341 :     of ( I.ADDQ | I.SUBQ | I.ANDQ | I.ORQ | I.XORQ | I.SHLQ | I.SARQ
342 :     | I.SHRQ | I.MULQ | I.IMULQ | I.ADCQ | I.SBBQ ) => 64
343 :     | ( I.ADDL | I.SUBL | I.ANDL | I.ORL | I.XORL | I.SHLL | I.SARL
344 :     | I.SHRL | I.MULL | I.IMULL | I.ADCL | I.SBBL | I.BTSL | I.BTCL
345 :     | I.BTRL | I.ROLL | I.RORL | I.XCHGL ) => 32
346 :     | ( I.ADDW | I.SUBW | I.ANDW | I.ORW | I.XORW | I.SHLW | I.SARW
347 :     | I.SHRW | I.MULW | I.IMULW | I.BTSW | I.BTCW | I.BTRW | I.ROLW
348 :     | I.RORW | I.XCHGW ) => 16
349 :     | ( I.ADDB | I.SUBB | I.ANDB | I.ORB | I.XORB | I.SHLB | I.SARB
350 :     | I.SHRB | I.MULB | I.IMULB | I.XCHGB ) => 8
351 :     | _ => raise Fail "" (* 64*)
352 :     (* esac *))
353 : mrainey 2810 | I.XADD {sz, ...} => szToInt sz
354 :     | I.CMPXCHG {sz, ...} => szToInt sz
355 : mrainey 2619 | _ => raise Fail "" (*64*)
356 :     (* esac *))
357 :    
358 :     fun szOfFinstr instr = (case instr
359 :     of I.FMOVE {fmvOp, ...} => (case fmvOp
360 :     of ( I.MOVSS | I.CVTSS2SD | I.CVTSS2SI | I.CVTSS2SIQ ) => 32
361 :     | ( I.MOVSD | I.CVTSD2SS | I.CVTSD2SI | I.CVTSD2SIQ ) => 64
362 :     | _ => error "AMD64Props.szOfFinstr"
363 :     (* end case *))
364 :     | I.FCOM {comOp, ...} => (case comOp
365 :     of ( I.COMISS | I.UCOMISS ) => 32
366 :     | ( I.COMISD | I.UCOMISD ) => 64
367 :     (* end case *))
368 :     | I.FBINOP {binOp, ...} => (case binOp
369 :     of ( I.ADDSS | I.SUBSS | I.MULSS | I.DIVSS ) => 32
370 :     | ( I.ADDSD | I.SUBSD | I.MULSD | I.DIVSD ) => 64
371 :     (* end case *))
372 : mrainey 2638 | I.FSQRTS _ => 32
373 :     | I.FSQRTD _ => 64
374 : mrainey 2810 | I.XORPS _ => 32
375 :     | I.XORPD _ => 64
376 : mrainey 2619 (* end case *))
377 :    
378 : mrainey 2781 end (* AMD64Props *)

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