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 /sml/trunk/src/MLRISC/x86/instructions/x86Props.sml
ViewVC logotype

Annotation of /sml/trunk/src/MLRISC/x86/instructions/x86Props.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1009 - (view) (download)

1 : monnier 247 (* x86Props.sml -- 32bit, x86 instruction semantic properties
2 :     *
3 :     * COPYRIGHT (c) 1997 Bell Laboratories.
4 :     *)
5 :    
6 : george 984 functor X86Props
7 :     (structure Instr : X86INSTR
8 :     structure MLTreeHash : MLTREE_HASH where T = Instr.T
9 :     structure MLTreeEval : MLTREE_EVAL where T = Instr.T
10 :     ) : INSN_PROPERTIES =
11 : monnier 247 struct
12 : george 984 structure I = Instr
13 : monnier 247 structure C = I.C
14 : leunga 775 structure T = I.T
15 : george 889 structure CB = CellsBasis
16 : monnier 247
17 :     exception NegateConditional
18 :    
19 : monnier 411 fun error msg = MLRiscErrorMsg.error("X86Props",msg)
20 : monnier 247
21 : george 545 datatype kind = IK_JUMP | IK_NOP | IK_INSTR | IK_COPY | IK_CALL
22 : leunga 796 | IK_CALL_WITH_CUTS | IK_PHI | IK_SOURCE | IK_SINK
23 : monnier 247 datatype target = LABELLED of Label.label | FALLTHROUGH | ESCAPES
24 :     (*========================================================================
25 :     * Instruction Kinds
26 :     *========================================================================*)
27 : george 1003 fun instrKind (I.ANNOTATION{i, ...}) = instrKind i
28 : george 1009 | instrKind (I.COPY _) = IK_COPY
29 : george 1003 | instrKind (I.INSTR i) =
30 :     (case i
31 :     of I.JMP _ => IK_JUMP
32 :     | I.JCC _ => IK_JUMP
33 :     | I.CALL{cutsTo=_::_,...} => IK_CALL_WITH_CUTS
34 :     | I.CALL _ => IK_CALL
35 :     | I.PHI _ => IK_PHI
36 :     | I.SOURCE _ => IK_SOURCE
37 :     | I.SINK _ => IK_SINK
38 :     | I.RET _ => IK_JUMP
39 :     | _ => IK_INSTR)
40 : monnier 247 | instrKind _ = IK_INSTR
41 :    
42 : george 1003 fun moveInstr(I.ANNOTATION{i, ...}) = moveInstr i
43 :     | moveInstr(I.LIVE _) = false
44 :     | moveInstr(I.KILL _) = false
45 : george 1009 | moveInstr(I.COPY _) = true
46 : george 1003 | moveInstr(I.INSTR i) =
47 :     (case i
48 : george 1009 of I.MOVE{mvOp=I.MOVL, src=I.Direct _, dst=I.MemReg _, ...} => true
49 : george 1003 | I.MOVE{mvOp=I.MOVL, src=I.MemReg _, dst=I.Direct _, ...} => true
50 :     | I.FMOVE{fsize=I.FP64,src=I.FPR _,dst=I.FPR _, ...} => true
51 :     | I.FMOVE{fsize=I.FP64,src=I.FPR _,dst=I.FDirect _, ...} => true
52 :     | I.FMOVE{fsize=I.FP64,src=I.FDirect _,dst=I.FPR _, ...} => true
53 :     | I.FMOVE{fsize=I.FP64,src=I.FDirect _,dst=I.FDirect _, ...} => true
54 :     | _ => false )
55 : monnier 247
56 :    
57 : george 1009 fun isMemMove(I.INSTR(i)) =
58 :     (case i
59 :     of I.MOVE{mvOp=I.MOVL, src=I.Direct _, dst=I.MemReg _, ...} => true
60 :     | I.MOVE{mvOp=I.MOVL, src=I.MemReg _, dst=I.Direct _, ...} => true
61 :     | I.FMOVE{fsize=I.FP64,src=I.FPR _,dst=I.FPR _, ...} => true
62 :     | I.FMOVE{fsize=I.FP64,src=I.FPR _,dst=I.FDirect _, ...} => true
63 :     | I.FMOVE{fsize=I.FP64,src=I.FDirect _,dst=I.FPR _, ...} => true
64 :     | I.FMOVE{fsize=I.FP64,src=I.FDirect _,dst=I.FDirect _, ...} => true
65 :     | _ => false
66 :     (*esac*))
67 :     | isMemMove _ = false
68 : monnier 247
69 :    
70 : george 1009 fun memMove(I.INSTR(i)) =
71 :     (case i
72 :     of I.MOVE{src=I.Direct rs, dst=I.MemReg rd, ...} => ([rd], [rs])
73 :     | I.MOVE{src=I.MemReg rs, dst=I.Direct rd, ...} => ([rd], [rs])
74 :     | I.FMOVE{src=I.FPR rs, dst=I.FPR rd, ...} => ([rd], [rs])
75 :     | I.FMOVE{src=I.FDirect rs, dst=I.FPR rd, ...} => ([rd], [rs])
76 :     | I.FMOVE{src=I.FPR rs, dst=I.FDirect rd, ...} => ([rd], [rs])
77 :     | I.FMOVE{src=I.FDirect rs, dst=I.FDirect rd, ...} => ([rd], [rs])
78 :     | _ => error "memMove: INSTR"
79 :     (*esac*))
80 :     | memMove _ = error "memMove"
81 :    
82 :     val nop = fn () => I.nop
83 :    
84 :    
85 : monnier 247 (*========================================================================
86 :     * Parallel Move
87 :     *========================================================================*)
88 : george 1003 fun moveTmpR(I.ANNOTATION{i,...}) = moveTmpR i
89 : george 1009 | moveTmpR(I.COPY{k=CB.GP, tmp=SOME(I.Direct r), ...}) = SOME r
90 :     | moveTmpR(I.COPY{k=CB.FP, tmp=SOME(I.FDirect f), ...}) = SOME f
91 :     | moveTmpR(I.COPY{k=CB.FP, tmp=SOME(I.FPR f), ...}) = SOME f
92 : monnier 247 | moveTmpR _ = NONE
93 :    
94 : george 1003 fun moveDstSrc(I.ANNOTATION{i,...}) = moveDstSrc i
95 : george 1009 | moveDstSrc(I.COPY{src, dst, ...}) = (dst, src)
96 : george 1003 | moveDstSrc(I.INSTR i) =
97 :     (case i
98 : george 1009 of I.MOVE{src=I.Direct rs, dst=I.MemReg rd, ...} => ([rd], [rs])
99 : george 1003 | I.MOVE{src=I.MemReg rs, dst=I.Direct rd, ...} => ([rd], [rs])
100 :     | I.FMOVE{src=I.FPR rs, dst=I.FPR rd, ...} => ([rd], [rs])
101 :     | I.FMOVE{src=I.FDirect rs, dst=I.FPR rd, ...} => ([rd], [rs])
102 :     | I.FMOVE{src=I.FPR rs, dst=I.FDirect rd, ...} => ([rd], [rs])
103 :     | I.FMOVE{src=I.FDirect rs, dst=I.FDirect rd, ...} => ([rd], [rs])
104 :     | _ => error "moveDstSrc")
105 :     | moveDstSrc _ = error "moveDstSrc2"
106 : monnier 247 (*=====================================================================
107 :     * Branches and Calls/Returns
108 :     *=====================================================================*)
109 : george 1003 fun branchTargets(I.ANNOTATION{i,...}) = branchTargets i
110 :     | branchTargets(I.INSTR i) =
111 :     (case i
112 :     of I.JMP(_, []) => [ESCAPES]
113 :     | I.JMP(_, labs) => map LABELLED labs
114 :     | I.RET _ => [ESCAPES]
115 :     | I.JCC{opnd=I.ImmedLabel(T.LABEL(lab)), ...} =>
116 :     [FALLTHROUGH, LABELLED lab]
117 :     | I.CALL{cutsTo, ...} => FALLTHROUGH :: map LABELLED cutsTo
118 :     | _ => error "branchTargets")
119 : monnier 247 | branchTargets _ = error "branchTargets"
120 :    
121 : george 1003 fun jump label = I.jmp (I.ImmedLabel(T.LABEL label), [label])
122 : monnier 247
123 :     exception NotImplemented
124 : george 1003
125 :     fun setTargets(I.ANNOTATION{i,a},l) = I.ANNOTATION{i=setTargets(i,l),a=a}
126 :     | setTargets(I.INSTR(I.JMP(I.ImmedLabel _,_)), [l]) = jump l
127 :     | setTargets(I.INSTR(I.JMP _), _) = error "setTargets"
128 :     | setTargets(I.INSTR(I.JCC{cond,opnd=I.ImmedLabel _}),[f,t]) =
129 :     I.jcc{cond=cond,opnd=I.ImmedLabel(T.LABEL t)}
130 :     | setTargets(I.INSTR(I.JCC _),_) = error "setTargets"
131 : monnier 429 | setTargets(i,_) = i
132 : george 1003
133 : monnier 247 fun negateConditional _ = raise NotImplemented
134 :    
135 : monnier 411 val immedRange={lo= ~1073741824, hi=1073741823}
136 :     val toInt32 = Int32.fromLarge o Int.toLarge
137 :     fun loadImmed{immed,t} =
138 : george 1003 I.move{mvOp=I.MOVL,src=I.Immed(toInt32 immed),dst=I.Direct t}
139 :     fun loadOperand{opn,t} = I.move{mvOp=I.MOVL,src=opn,dst=I.Direct t}
140 : monnier 411
141 :     (*=====================================================================
142 :     * Hashing and Equality on operands
143 :     *=====================================================================*)
144 :     fun hashOpn(I.Immed i) = Word.fromInt(Int32.toInt i)
145 : george 984 | hashOpn(I.ImmedLabel le) = MLTreeHash.hash le + 0w123
146 : monnier 411 | hashOpn(I.Relative i) = Word.fromInt i + 0w1232
147 : george 984 | hashOpn(I.LabelEA le) = MLTreeHash.hash le + 0w44444
148 : george 889 | hashOpn(I.Direct r) = CB.hashCell r
149 :     | hashOpn(I.MemReg r) = CB.hashCell r + 0w2123
150 :     | hashOpn(I.ST f) = CB.hashCell f + 0w88
151 :     | hashOpn(I.FPR f) = CB.hashCell f + 0w881
152 :     | hashOpn(I.FDirect f) = CB.hashCell f + 0w31245
153 : george 545 | hashOpn(I.Displace {base, disp, ...}) =
154 : george 889 hashOpn disp + CB.hashCell base
155 : monnier 411 | hashOpn(I.Indexed {base, index, scale, disp, ...}) =
156 : george 889 CB.hashCell index + Word.fromInt scale + hashOpn disp
157 : monnier 411 fun eqOpn(I.Immed a,I.Immed b) = a = b
158 : george 984 | eqOpn(I.ImmedLabel a,I.ImmedLabel b) = MLTreeEval.==(a,b)
159 : monnier 411 | eqOpn(I.Relative a,I.Relative b) = a = b
160 : george 984 | eqOpn(I.LabelEA a,I.LabelEA b) = MLTreeEval.==(a,b)
161 : george 889 | eqOpn(I.Direct a,I.Direct b) = CB.sameColor(a,b)
162 :     | eqOpn(I.MemReg a,I.MemReg b) = CB.sameColor(a,b)
163 :     | eqOpn(I.FDirect a,I.FDirect b) = CB.sameColor(a,b)
164 :     | eqOpn(I.ST a,I.ST b) = CB.sameColor(a,b)
165 :     | eqOpn(I.FPR a,I.FPR b) = CB.sameColor(a,b)
166 : monnier 411 | eqOpn(I.Displace{base=a,disp=b,...},I.Displace{base=c,disp=d,...}) =
167 : george 889 CB.sameColor(a,c) andalso eqOpn(b,d)
168 : monnier 411 | eqOpn(I.Indexed{base=a,index=b,scale=c,disp=d,...},
169 :     I.Indexed{base=e,index=f,scale=g,disp=h,...}) =
170 : george 889 CB.sameColor(b,f) andalso c = g
171 : leunga 744 andalso sameCellOption(a,e) andalso eqOpn(d,h)
172 : monnier 411 | eqOpn _ = false
173 : leunga 744 and sameCellOption(NONE, NONE) = true
174 : george 889 | sameCellOption(SOME x, SOME y) = CB.sameColor(x,y)
175 : leunga 744 | sameCellOption _ = false
176 : monnier 411
177 : monnier 247 (*========================================================================
178 :     * Definition and use (for register allocation mainly)
179 :     *========================================================================*)
180 :     val eaxPair = [C.edx, C.eax]
181 :    
182 :     fun defUseR instr = let
183 : george 1009 fun operandAcc(I.Direct r, acc) = r::acc
184 :     | operandAcc(I.MemReg r, acc) = r::acc
185 :     | operandAcc(I.Displace{base, ...}, acc) = base::acc
186 :     | operandAcc(I.Indexed{base=SOME b, index, ...}, acc) = b::index::acc
187 :     | operandAcc(I.Indexed{base=NONE, index, ...}, acc) = index::acc
188 :     | operandAcc(_, acc) = acc
189 :    
190 : george 1003 fun x86DefUseR instr = let
191 :     fun operandUse opnd = operandAcc(opnd, [])
192 : monnier 247
193 : george 1003 fun operandUse2(src1, src2) = ([], operandAcc(src1, operandUse src2))
194 :     fun operandUse3(x, y, z) = ([], operandAcc(x, operandAcc(y, operandUse y)))
195 : leunga 731
196 : george 1003 fun operandDef(I.Direct r) = [r]
197 :     | operandDef(I.MemReg r) = [r]
198 :     | operandDef _ = []
199 : monnier 247
200 : george 1003 fun multdiv{src, multDivOp} = let
201 :     val uses = operandUse src
202 :     in
203 :     case multDivOp
204 :     of (I.IDIVL1 | I.DIVL1) => (eaxPair, C.edx::C.eax::uses)
205 :     | I.MULL1 => (eaxPair, C.eax::uses)
206 :     end
207 :    
208 :     fun unary opnd = (operandDef opnd, operandUse opnd)
209 :     fun cmptest{lsrc, rsrc} = ([], operandAcc(lsrc, operandUse rsrc))
210 :     fun espOnly() = let val sp = [C.stackptrR] in (sp, sp) end
211 :     fun push arg = ([C.stackptrR], operandAcc(arg, [C.stackptrR]))
212 :     fun float opnd = ([], operandUse opnd)
213 : monnier 247 in
214 : george 1003 case instr
215 :     of I.JMP(opnd, _) => ([], operandUse opnd)
216 :     | I.JCC{opnd, ...} => ([], operandUse opnd)
217 :     | I.CALL{opnd,defs,uses,...} =>
218 :     (C.getReg defs, operandAcc(opnd, C.getReg uses))
219 :     | I.MOVE{src, dst=I.Direct r, ...} => ([r], operandUse src)
220 :     | I.MOVE{src, dst=I.MemReg r, ...} => ([r], operandUse src)
221 :     | I.MOVE{src, dst, ...} => ([], operandAcc(dst, operandUse src))
222 :     | I.LEA{r32, addr} => ([r32], operandUse addr)
223 :     | ( I.CMPL arg | I.CMPW arg | I.CMPB arg
224 :     | I.TESTL arg | I.TESTW arg | I.TESTB arg ) => cmptest arg
225 :     | I.BITOP{lsrc, rsrc, ...} => cmptest{lsrc=lsrc,rsrc=rsrc}
226 :     | I.BINARY{binOp=I.XORL,src=I.Direct rs,dst=I.Direct rd,...} =>
227 :     if CB.sameColor(rs,rd) then ([rd],[]) else ([rd],[rs,rd])
228 :     | I.BINARY{src,dst,...} =>
229 :     (operandDef dst, operandAcc(src, operandUse dst))
230 :     | I.CMPXCHG{src, dst, ...} =>
231 :     (C.eax::operandDef dst, C.eax::operandAcc(src, operandUse dst))
232 :     | I.ENTER _ => ([C.esp, C.ebp], [C.esp, C.ebp])
233 :     | I.LEAVE => ([C.esp, C.ebp], [C.esp, C.ebp])
234 :     | I.MULTDIV arg => multdiv arg
235 :     | I.MUL3{src1, dst, ...}=> ([dst], operandUse src1)
236 : monnier 247
237 : george 1003 | I.UNARY{opnd, ...} => unary opnd
238 :     | I.SET{opnd, ...} => unary opnd
239 :     | ( I.PUSHL arg | I.PUSHW arg | I.PUSHB arg ) => push arg
240 :     | I.POP arg => (C.stackptrR::operandDef arg, [C.stackptrR])
241 :     | I.PUSHFD => espOnly()
242 :     | I.POPFD => espOnly()
243 :     | I.CDQ => ([C.edx], [C.eax])
244 :     | I.FSTPT opnd => float opnd
245 :     | I.FSTPL opnd => float opnd
246 :     | I.FSTPS opnd => float opnd
247 :     | I.FSTL opnd => float opnd
248 :     | I.FSTS opnd => float opnd
249 :     | I.FLDL opnd => float opnd
250 :     | I.FLDS opnd => float opnd
251 :     | I.FILD opnd => float opnd
252 :     | I.FILDL opnd => float opnd
253 :     | I.FILDLL opnd => float opnd
254 :     | I.FBINARY{src, ...} => ([], operandUse src)
255 :     | I.FIBINARY{src, ...} => ([], operandUse src)
256 :     | I.FENV{opnd, ...} => ([], operandUse opnd)
257 :     | I.FNSTSW => ([C.eax], [])
258 :     | I.FUCOM opnd => float opnd
259 :     | I.FUCOMP opnd => float opnd
260 : monnier 247
261 : george 1003 | I.FMOVE{src, dst, ...} => operandUse2(src, dst)
262 :     | I.FILOAD{ea, dst, ...} => operandUse2(ea, dst)
263 :     | I.FCMP{lsrc, rsrc, ...} => operandUse2(lsrc, rsrc)
264 :     | I.FBINOP{lsrc, rsrc, dst, ...} => operandUse3(lsrc, rsrc, dst)
265 :     | I.FIBINOP{lsrc, rsrc, dst, ...} => operandUse3(lsrc, rsrc, dst)
266 :     | I.FUNOP{src, dst, ...} => operandUse2(src, dst)
267 : leunga 731
268 : george 1003 | I.SAHF => ([], [C.eax])
269 :     | I.LAHF => ([C.eax], [])
270 :     (* This sets the low order byte,
271 :     * do potentially it may define *and* use
272 :     *)
273 :     | I.CMOV{src,dst,...} => ([dst], operandAcc(src, [dst]))
274 :     | _ => ([], [])
275 :     end
276 :     in
277 :     case instr
278 :     of I.ANNOTATION{i, ...} => defUseR i
279 :     | I.LIVE{regs, ...} => ([], C.getReg regs)
280 :     | I.KILL{regs, ...} => (C.getReg regs, [])
281 : george 1009 | I.COPY{k=CB.GP, dst, src, tmp, ...} =>
282 :     (case tmp
283 :     of NONE => (dst, src)
284 :     | SOME(I.Direct r) => (r::dst, src)
285 :     | SOME(I.MemReg r) => (r::dst, src)
286 :     | SOME(ea) => (dst, operandAcc(ea, src))
287 :     (*esac*))
288 :     | I.COPY _ => ([], [])
289 : george 1003 | I.INSTR i => x86DefUseR(i)
290 :     end
291 : leunga 731
292 : monnier 247 fun defUseF instr = let
293 : leunga 731
294 : george 1003 fun x86DefUseF instr = let
295 :     fun operand(I.FDirect f) = [f]
296 :     | operand(I.FPR f) = [f]
297 :     | operand _ = []
298 : leunga 731
299 : george 1003 fun operandAcc(I.FDirect f, acc) = f::acc
300 :     | operandAcc(I.FPR f, acc) = f::acc
301 :     | operandAcc(_ , acc) = acc
302 : leunga 731
303 : george 1003 fun fbinop(lsrc, rsrc, dst) =
304 :     let val def = operand dst
305 :     val use = operandAcc(lsrc, operand rsrc)
306 :     in (def, use)
307 :     end
308 : leunga 731
309 : george 1003 val fcmpTmp = [C.ST 0]
310 : leunga 731
311 : george 1003 in
312 :     case instr
313 :     of I.FSTPT opnd => (operand opnd, [])
314 :     | I.FSTPL opnd => (operand opnd, [])
315 :     | I.FSTPS opnd => (operand opnd, [])
316 :     | I.FSTL opnd => (operand opnd, [])
317 :     | I.FSTS opnd => (operand opnd, [])
318 :     | I.FLDT opnd => ([], operand opnd)
319 :     | I.FLDL opnd => ([], operand opnd)
320 :     | I.FLDS opnd => ([], operand opnd)
321 :     | I.FUCOM opnd => ([], operand opnd)
322 :     | I.FUCOMP opnd => ([], operand opnd)
323 :     | I.CALL{defs, uses, ...} => (C.getFreg defs, C.getFreg uses)
324 :     | I.FBINARY{dst, src, ...}=> (operand dst, operand dst @ operand src)
325 : leunga 731
326 : george 1003 | I.FMOVE{src, dst, ...} => (operand dst, operand src)
327 :     | I.FILOAD{ea, dst, ...} => (operand dst, [])
328 :     | I.FCMP{lsrc, rsrc, ...} => (fcmpTmp, operandAcc(lsrc, operand rsrc))
329 :     | I.FBINOP{lsrc, rsrc, dst, ...} => fbinop(lsrc, rsrc, dst)
330 :     | I.FIBINOP{lsrc, rsrc, dst, ...} => fbinop(lsrc, rsrc, dst)
331 :     | I.FUNOP{src, dst, ...} => (operand dst, operand src)
332 :     | _ => ([], [])
333 :     end
334 :     in
335 :     case instr
336 :     of (I.ANNOTATION{i, ...}) => defUseF(i)
337 : george 1009 | I.LIVE{regs, ...} => ([], C.getFreg regs)
338 :     | I.KILL{regs, ...} => (C.getFreg regs, [])
339 :     | I.COPY{k=CB.FP, dst, src, tmp, ...} =>
340 :     (case tmp
341 :     of NONE => (dst, src)
342 :     | SOME(I.FDirect f) => (f::dst, src)
343 :     | SOME(I.FPR f) => (f::dst, src)
344 :     | _ => (dst, src)
345 :     (*esac*))
346 :     | I.COPY _ => ([], [])
347 : george 1003 | (I.INSTR i) => x86DefUseF(i)
348 : monnier 247 end
349 :    
350 : george 889 fun defUse CB.GP = defUseR
351 :     | defUse CB.FP = defUseF
352 : monnier 247 | defUse _ = error "defUse"
353 : monnier 411
354 :     (*========================================================================
355 :     * Annotations
356 :     *========================================================================*)
357 : monnier 469 fun getAnnotations(I.ANNOTATION{i,a}) =
358 :     let val (i,an) = getAnnotations i in (i,a::an) end
359 :     | getAnnotations i = (i,[])
360 : george 1003
361 : monnier 411 fun annotate(i,a) = I.ANNOTATION{i=i,a=a}
362 : leunga 657
363 :     (*========================================================================
364 :     * Replicate an instruction
365 :     *========================================================================*)
366 :     fun replicate(I.ANNOTATION{i,a}) = I.ANNOTATION{i=replicate i,a=a}
367 : george 1003 (*
368 : leunga 657 | replicate(I.COPY{tmp=SOME _, dst, src}) =
369 :     I.COPY{tmp=SOME(I.Direct(C.newReg())), dst=dst, src=src}
370 :     | replicate(I.FCOPY{tmp=SOME _, dst, src}) =
371 :     I.FCOPY{tmp=SOME(I.FDirect(C.newFreg())), dst=dst, src=src}
372 : george 1003 *)
373 : leunga 657 | replicate i = i
374 : monnier 247 end
375 :    

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