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 2811 - (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 : mrainey 2811 | I.XCHG {src, dst, ...} =>
214 :     (operandDef dst, operandAcc (src, operandUse dst))
215 : mrainey 2619 | ( I.ENTER _ | I.LEAVE ) => ([C.rsp, C.rbp], [C.rsp, C.rbp])
216 :     | I.MULTDIV arg => multDiv arg
217 :     | ( I.MUL3 {src1, dst, ...} | I.MULQ3 {src1, dst, ...} ) =>
218 :     ([dst], operandUse src1)
219 :     | ( I.UNARY{opnd, ...} | I.SET {opnd, ...} ) => unary opnd
220 :     | (I.PUSHQ arg | I.PUSHL arg | I.PUSHW arg | I.PUSHB arg ) => push arg
221 :     | I.POP arg => (C.stackptrR::operandDef arg, [C.stackptrR])
222 :     | ( I.PUSHFD | I.POPFD )=> rspOnly ()
223 :     | I.CDQ => ([C.rdx], [C.rax])
224 :     | I.FMOVE {dst, src, ...} => ([], operandAcc (dst, operandUse src))
225 :     | I.FCOM {src, ...} => ([], operandUse src)
226 :     | I.SAHF => ([], [C.rax])
227 :     | I.LAHF => ([C.rax], [])
228 :     (* This sets the low order byte,
229 :     * do potentially it may define *and* use
230 :     *)
231 :     | I.CMOV {src, dst,...} => ([dst], operandAcc(src, [dst]))
232 :     | _ => ([], [])
233 :     (* end case *))
234 :     in
235 :     case i
236 :     of I.ANNOTATION {i, ...} => defUseR i
237 :     | I.LIVE {regs, ...} => ([], C.getReg regs)
238 :     | I.KILL {regs, ...} => (C.getReg regs, [])
239 :     | I.COPY {k=CB.GP, src, dst, tmp, ...} => (case tmp
240 :     of SOME (I.Direct (_, t)) => (t :: dst, src)
241 :     | SOME ea => (dst, operandAcc (ea, src))
242 :     | NONE => (dst, src)
243 :     (* end case *))
244 :     | I.COPY _ => ([], [])
245 :     | I.INSTR i => f i
246 :     (* end case *)
247 :     end (* defUseR *)
248 :    
249 :     fun defUseF i = let
250 :     fun operandAcc (I.FDirect r, acc) = r :: acc
251 :     | operandAcc (_, acc) = acc
252 :     fun operand opnd = operandAcc (opnd, [])
253 :     fun f i = (case i
254 :     of I.FMOVE {dst, src, ...} => (operand dst, operand src)
255 :     | I.FBINOP {dst, src, ...} => ([dst], [src])
256 : mrainey 2808 | ( I.XORPS {dst, src} | I.XORPD {dst, src} ) => (operand dst, operand src)
257 : mrainey 2619 | I.FCOM {dst, src, ...} => ([dst], operand src)
258 : mrainey 2638 | ( I.FSQRTS {dst, src} | I.FSQRTD {dst, src} )=>
259 :     (operand dst, operand src)
260 : mrainey 2619 | ( I.CALL {defs, uses, ...} | I.CALLQ {defs, uses, ...} ) =>
261 :     (C.getFreg defs, C.getFreg uses)
262 :     | _ => ([], [])
263 :     (* end case *))
264 :     in
265 :     case i
266 :     of I.ANNOTATION {i, ...} => defUseF i
267 :     | I.LIVE {regs, ...} => ([], C.getFreg regs)
268 :     | I.KILL {regs, ...} => (C.getFreg regs, [])
269 :     | I.COPY {k=CB.FP, src, dst, tmp, ...} => (case tmp
270 :     of SOME (I.FDirect t) => (t :: dst, src)
271 :     | SOME ea => (dst, operandAcc (ea, src))
272 :     | NONE => (dst, src)
273 :     (* end case *))
274 :     | I.COPY _ => ([], [])
275 :     | I.INSTR i => f i
276 :     (* end case *)
277 :     end (* defUseF *)
278 :    
279 :     fun defUse CB.GP = defUseR
280 :     | defUse CB.FP = defUseF
281 :     | defUse _ = error "defUse"
282 :    
283 :     fun getAnnotations (I.ANNOTATION {i, a}) = let
284 :     val (i, an) = getAnnotations i
285 :     in
286 :     (i, a::an)
287 :     end
288 :     | getAnnotations i = (i,[])
289 :    
290 :     fun annotate (i, a) = I.ANNOTATION {i=i, a=a}
291 :    
292 : mrainey 2810 fun szToInt I.I8 = 8
293 :     | szToInt I.I16 = 16
294 :     | szToInt I.I32 = 32
295 :     | szToInt I.I64 = 64
296 :    
297 : mrainey 2619 fun replicate(I.ANNOTATION{i,a}) = I.ANNOTATION{i=replicate i,a=a}
298 :     (* FIXME? *)
299 :     (* | replicate(I.COPY{tmp=SOME _, dst, src}) =
300 :     I.COPY{tmp=SOME(I.Direct(C.newReg())), dst=dst, src=src}
301 :     | replicate(I.FCOPY{tmp=SOME _, dst, src}) =
302 :     I.FCOPY{tmp=SOME(I.FDirect(C.newFreg())), dst=dst, src=src} *)
303 :     | replicate i = i
304 :    
305 :     (* determine the bit width of an instruction *)
306 :     fun szOfInstr instr = (case instr
307 :     of I.JCC _ => 32
308 : mrainey 2783 (* NOTE: CMOV encodes operand length in its operands! *)
309 :     | I.CMOV {src=I.Direct (sz, _), ...} => sz
310 : mrainey 2619 | I.MOVE {mvOp, ...} =>
311 :     (case mvOp
312 :     of ( I.MOVQ | I.MOVSWQ | I.MOVZWQ | I.MOVSBQ |
313 :     I.MOVZBQ | I.MOVSLQ ) => 64
314 :     | ( I.MOVL | I.MOVSWL | I.MOVZWL | I.MOVSBL |
315 :     I.MOVZBL ) => 32
316 :     | I.MOVW => 16
317 :     | I.MOVB => 8
318 :     (* esac *))
319 : mrainey 2783 | ( I.CALL _ | I.LEAL _ | I.CMPL _ | I.TESTL _ | I.MUL3 _ )
320 : mrainey 2619 => 32
321 : mrainey 2783 | ( I.CALLQ _ | I.LEAQ _ | I.CMPQ _ | I.TESTQ _ | I.MULQ3 _ | I.CMOV _)
322 : mrainey 2619 => 64
323 :     | ( I.CMPW _ | I.TESTW _ ) => 16
324 :     | ( I.CMPB _ | I.TESTB _ ) => 8
325 :     | I.SHIFT {shiftOp, ...} => (case shiftOp
326 :     of ( I.SHLDL | I.SHRDL ) => 32
327 :     (* esac *))
328 :     | I.UNARY {unOp, ...} =>
329 :     (case unOp
330 :     of ( I.DECQ | I.INCQ | I.NEGQ | I.NOTQ |
331 :     I.LOCK_DECQ | I.LOCK_INCQ | I.LOCK_NEGQ | I.LOCK_NOTQ ) => 64
332 :     | ( I.DECL | I.INCL | I.NEGL | I.NOTL ) => 32
333 :     | ( I.DECW | I.INCW | I.NEGW | I.NOTW ) => 16
334 :     | ( I.DECB | I.INCB | I.NEGB | I.NOTB ) => 8
335 :     (* esac *))
336 :     | I.MULTDIV {multDivOp, ...} =>
337 :     (case multDivOp
338 :     of ( I.IMULL1 | I.MULL1 | I.IDIVL1 | I.DIVL1 ) => 32
339 :     | ( I.IMULQ1 | I.MULQ1 | I.IDIVQ1 | I.DIVQ1 ) => 64
340 :     (* esac *))
341 :     | I.BINARY {binOp, ...} =>
342 :     (case binOp
343 :     of ( I.ADDQ | I.SUBQ | I.ANDQ | I.ORQ | I.XORQ | I.SHLQ | I.SARQ
344 :     | I.SHRQ | I.MULQ | I.IMULQ | I.ADCQ | I.SBBQ ) => 64
345 :     | ( I.ADDL | I.SUBL | I.ANDL | I.ORL | I.XORL | I.SHLL | I.SARL
346 :     | I.SHRL | I.MULL | I.IMULL | I.ADCL | I.SBBL | I.BTSL | I.BTCL
347 :     | I.BTRL | I.ROLL | I.RORL | I.XCHGL ) => 32
348 :     | ( I.ADDW | I.SUBW | I.ANDW | I.ORW | I.XORW | I.SHLW | I.SARW
349 :     | I.SHRW | I.MULW | I.IMULW | I.BTSW | I.BTCW | I.BTRW | I.ROLW
350 :     | I.RORW | I.XCHGW ) => 16
351 :     | ( I.ADDB | I.SUBB | I.ANDB | I.ORB | I.XORB | I.SHLB | I.SARB
352 :     | I.SHRB | I.MULB | I.IMULB | I.XCHGB ) => 8
353 :     | _ => raise Fail "" (* 64*)
354 :     (* esac *))
355 : mrainey 2810 | I.XADD {sz, ...} => szToInt sz
356 :     | I.CMPXCHG {sz, ...} => szToInt sz
357 : mrainey 2619 | _ => raise Fail "" (*64*)
358 :     (* esac *))
359 :    
360 :     fun szOfFinstr instr = (case instr
361 :     of I.FMOVE {fmvOp, ...} => (case fmvOp
362 :     of ( I.MOVSS | I.CVTSS2SD | I.CVTSS2SI | I.CVTSS2SIQ ) => 32
363 :     | ( I.MOVSD | I.CVTSD2SS | I.CVTSD2SI | I.CVTSD2SIQ ) => 64
364 :     | _ => error "AMD64Props.szOfFinstr"
365 :     (* end case *))
366 :     | I.FCOM {comOp, ...} => (case comOp
367 :     of ( I.COMISS | I.UCOMISS ) => 32
368 :     | ( I.COMISD | I.UCOMISD ) => 64
369 :     (* end case *))
370 :     | I.FBINOP {binOp, ...} => (case binOp
371 :     of ( I.ADDSS | I.SUBSS | I.MULSS | I.DIVSS ) => 32
372 :     | ( I.ADDSD | I.SUBSD | I.MULSD | I.DIVSD ) => 64
373 :     (* end case *))
374 : mrainey 2638 | I.FSQRTS _ => 32
375 :     | I.FSQRTD _ => 64
376 : mrainey 2810 | I.XORPS _ => 32
377 :     | I.XORPD _ => 64
378 : mrainey 2619 (* end case *))
379 :    
380 : mrainey 2781 end (* AMD64Props *)

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