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 565 - (view) (download)

1 : monnier 247 (* x86Props.sml -- 32bit, x86 instruction semantic properties
2 :     *
3 :     * COPYRIGHT (c) 1997 Bell Laboratories.
4 :     *)
5 :    
6 : monnier 411 functor X86Props(X86Instr : X86INSTR) : INSN_PROPERTIES =
7 : monnier 247 struct
8 :     structure I = X86Instr
9 :     structure C = I.C
10 : george 545 structure LE = I.LabelExp
11 : monnier 247
12 :     exception NegateConditional
13 :    
14 : monnier 411 fun error msg = MLRiscErrorMsg.error("X86Props",msg)
15 : monnier 247
16 : george 545 datatype kind = IK_JUMP | IK_NOP | IK_INSTR | IK_COPY | IK_CALL
17 : monnier 411 | IK_PHI | IK_SOURCE | IK_SINK
18 : monnier 247 datatype target = LABELLED of Label.label | FALLTHROUGH | ESCAPES
19 :     (*========================================================================
20 :     * Instruction Kinds
21 :     *========================================================================*)
22 :     fun instrKind (I.JMP _) = IK_JUMP
23 :     | instrKind (I.JCC _) = IK_JUMP
24 : monnier 411 | instrKind (I.COPY _) = IK_COPY
25 :     | instrKind (I.FCOPY _) = IK_COPY
26 :     | instrKind (I.CALL _) = IK_CALL
27 :     | instrKind (I.ANNOTATION{i,...}) = instrKind i
28 : monnier 247 | instrKind _ = IK_INSTR
29 :    
30 :    
31 :     fun moveInstr(I.COPY _) = true
32 :     | moveInstr(I.FCOPY _) = true
33 : monnier 498 | moveInstr(I.MOVE{mvOp=I.MOVL, src=I.Direct _, dst=I.MemReg _, ...}) = true
34 :     | moveInstr(I.MOVE{mvOp=I.MOVL, src=I.MemReg _, dst=I.Direct _, ...}) = true
35 : monnier 411 | moveInstr(I.ANNOTATION{i,...}) = moveInstr i
36 : monnier 247 | moveInstr _ = false
37 :    
38 :     val nop = fn () => I.NOP
39 :    
40 :    
41 :     (*========================================================================
42 :     * Parallel Move
43 :     *========================================================================*)
44 :     fun moveTmpR(I.COPY{tmp=SOME(I.Direct r), ...}) = SOME r
45 :     | moveTmpR(I.FCOPY{tmp=SOME(I.FDirect f), ...}) = SOME f
46 : monnier 411 | moveTmpR(I.ANNOTATION{i,...}) = moveTmpR i
47 : monnier 247 | moveTmpR _ = NONE
48 :    
49 :     fun moveDstSrc(I.COPY{src, dst, ...}) = (dst, src)
50 :     | moveDstSrc(I.FCOPY{src, dst, ...}) = (dst, src)
51 : monnier 498 | moveDstSrc(I.MOVE{src=I.Direct rs, dst=I.MemReg rd, ...}) = ([rd], [rs])
52 :     | moveDstSrc(I.MOVE{src=I.MemReg rs, dst=I.Direct rd, ...}) = ([rd], [rs])
53 : monnier 411 | moveDstSrc(I.ANNOTATION{i,...}) = moveDstSrc i
54 : monnier 247 | moveDstSrc _ = error "moveDstSrc"
55 :    
56 :     (*=====================================================================
57 :     * Branches and Calls/Returns
58 :     *=====================================================================*)
59 :     fun branchTargets(I.JMP(_, [])) = [ESCAPES]
60 :     | branchTargets(I.JMP(_, labs)) = map LABELLED labs
61 : monnier 429 | branchTargets(I.RET _) = [ESCAPES]
62 : monnier 247 | branchTargets(I.JCC{opnd=I.ImmedLabel(LE.LABEL(lab)), ...}) =
63 :     [FALLTHROUGH, LABELLED lab]
64 : monnier 411 | branchTargets(I.ANNOTATION{i,...}) = branchTargets i
65 : monnier 247 | branchTargets _ = error "branchTargets"
66 :    
67 :     fun jump label = I.JMP (I.ImmedLabel(LE.LABEL label), [label])
68 :    
69 :     exception NotImplemented
70 : monnier 429 fun setTargets(I.JMP(I.ImmedLabel _,_),[l]) = jump l
71 :     | setTargets(I.JMP(opnd,_),_) = error "setTargets"
72 :     | setTargets(I.JCC{cond,opnd=I.ImmedLabel _},[f,t]) =
73 :     I.JCC{cond=cond,opnd=I.ImmedLabel(LE.LABEL t)}
74 :     | setTargets(I.JCC _,_) = error "setTargets"
75 :     | setTargets(I.ANNOTATION{i,a},l) = I.ANNOTATION{i=setTargets(i,l),a=a}
76 :     | setTargets(i,_) = i
77 : monnier 247 fun negateConditional _ = raise NotImplemented
78 :    
79 : monnier 411 val immedRange={lo= ~1073741824, hi=1073741823}
80 :     val toInt32 = Int32.fromLarge o Int.toLarge
81 :     fun loadImmed{immed,t} =
82 :     I.MOVE{mvOp=I.MOVL,src=I.Immed(toInt32 immed),dst=I.Direct t}
83 :    
84 :     (*=====================================================================
85 :     * Hashing and Equality on operands
86 :     *=====================================================================*)
87 :     fun hashOpn(I.Immed i) = Word.fromInt(Int32.toInt i)
88 : george 545 | hashOpn(I.ImmedLabel le) = LE.hash le + 0w123
89 : monnier 411 | hashOpn(I.Relative i) = Word.fromInt i + 0w1232
90 : george 545 | hashOpn(I.LabelEA le) = LE.hash le + 0w44444
91 : monnier 411 | hashOpn(I.Direct r) = Word.fromInt r
92 : monnier 498 | hashOpn(I.MemReg r) = Word.fromInt r + 0w2123
93 : george 555 | hashOpn(I.ST f) = Word.fromInt f + 0w88
94 : monnier 411 | hashOpn(I.FDirect f) = Word.fromInt f + 0w8888
95 : george 545 | hashOpn(I.Displace {base, disp, ...}) =
96 :     hashOpn disp + Word.fromInt base
97 : monnier 411 | hashOpn(I.Indexed {base, index, scale, disp, ...}) =
98 :     Word.fromInt index + Word.fromInt scale + hashOpn disp
99 :     fun eqOpn(I.Immed a,I.Immed b) = a = b
100 : george 545 | eqOpn(I.ImmedLabel a,I.ImmedLabel b) = LE.==(a,b)
101 : monnier 411 | eqOpn(I.Relative a,I.Relative b) = a = b
102 : george 545 | eqOpn(I.LabelEA a,I.LabelEA b) = LE.==(a,b)
103 : monnier 411 | eqOpn(I.Direct a,I.Direct b) = a = b
104 : monnier 498 | eqOpn(I.MemReg a,I.MemReg b) = a = b
105 : george 555 | eqOpn(I.ST a,I.ST b) = a = b
106 : monnier 411 | eqOpn(I.FDirect a,I.FDirect b) = a = b
107 :     | eqOpn(I.Displace{base=a,disp=b,...},I.Displace{base=c,disp=d,...}) =
108 :     a = c andalso eqOpn(b,d)
109 :     | eqOpn(I.Indexed{base=a,index=b,scale=c,disp=d,...},
110 :     I.Indexed{base=e,index=f,scale=g,disp=h,...}) =
111 :     b = f andalso c = g andalso a = e andalso eqOpn(d,h)
112 :     | eqOpn _ = false
113 :    
114 : monnier 247 (*========================================================================
115 :     * Definition and use (for register allocation mainly)
116 :     *========================================================================*)
117 :     val eaxPair = [C.edx, C.eax]
118 :    
119 :     fun defUseR instr = let
120 :     fun operandAcc(I.Direct r, acc) = r::acc
121 : monnier 498 | operandAcc(I.MemReg r, acc) = r::acc
122 : monnier 247 | operandAcc(I.Displace{base, ...}, acc) = base::acc
123 :     | operandAcc(I.Indexed{base=SOME b, index, ...}, acc) = b::index::acc
124 :     | operandAcc(I.Indexed{base=NONE, index, ...}, acc) = index::acc
125 :     | operandAcc(_, acc) = acc
126 :    
127 :     fun operandUse opnd = operandAcc(opnd, [])
128 :    
129 :     fun operandDef(I.Direct r) = [r]
130 : monnier 498 | operandDef(I.MemReg r) = [r]
131 : monnier 247 | operandDef _ = []
132 :    
133 :     fun multdiv{src, multDivOp} = let
134 :     val uses = operandUse src
135 :     in
136 :     case multDivOp
137 :     of (I.IDIV | I.UDIV) => (eaxPair, C.edx::C.eax::uses)
138 :     | I.UMUL => (eaxPair, C.eax::uses)
139 :     end
140 :    
141 : george 545 fun unary opnd = (operandDef opnd, operandUse opnd)
142 :     fun cmptest{lsrc, rsrc} = ([], operandAcc(lsrc, operandUse rsrc))
143 :     fun push arg = ([], operandUse arg)
144 :     fun float opnd = ([], operandUse opnd)
145 : monnier 247 in
146 :     case instr
147 :     of I.JMP(opnd, _) => ([], operandUse opnd)
148 :     | I.JCC{opnd, ...} => ([], operandUse opnd)
149 : monnier 411 | I.CALL(opnd,defs,uses,_)=> (#1 defs, operandAcc(opnd, #1 uses))
150 : monnier 498 | I.MOVE{src, dst=I.Direct r, ...} => ([r], operandUse src)
151 :     | I.MOVE{src, dst=I.MemReg r, ...} => ([r], operandUse src)
152 : monnier 247 | I.MOVE{src, dst, ...} => ([], operandAcc(dst, operandUse src))
153 :     | I.LEA{r32, addr} => ([r32], operandUse addr)
154 : george 545 | ( I.CMPL arg | I.CMPW arg | I.CMPB arg
155 :     | I.TESTL arg | I.TESTW arg | I.TESTB arg) => cmptest arg
156 :     | I.BINARY{binOp=I.XORL,src=I.Direct rs,dst=I.Direct rd,...} =>
157 :     if rs=rd then ([rd],[]) else ([rd],[rs,rd])
158 :     | I.BINARY{src,dst,...} =>
159 :     (operandDef dst, operandAcc(src, operandUse dst))
160 :     | I.LEAVE => error "leave"
161 : monnier 247 | I.MULTDIV arg => multdiv arg
162 :     | I.MUL3{src1, src2=SOME _, dst}=> ([dst], operandUse src1)
163 :     | I.MUL3{src1, dst, ...}=> ([dst], dst::operandUse src1)
164 :    
165 : george 545 | I.UNARY{opnd, ...} => unary opnd
166 :     | I.SET{opnd, ...} => unary opnd
167 :     | ( I.PUSHL arg | I.PUSHW arg | I.PUSHB arg ) => push arg
168 : monnier 247 | I.POP arg => (operandDef arg, [])
169 :     | I.CDQ => ([C.edx], [C.eax])
170 :    
171 :     | I.COPY{dst, src, tmp=SOME(I.Direct r), ...} => (r::dst, src)
172 :     | I.COPY{dst, src, ...} => (dst, src)
173 : george 555 | I.FSTPT opnd => float opnd
174 : george 545 | I.FSTPL opnd => float opnd
175 :     | I.FSTPS opnd => float opnd
176 :     | I.FLDL opnd => float opnd
177 :     | I.FLDS opnd => float opnd
178 :     | I.FILD opnd => float opnd
179 : leunga 565 | I.FILDL opnd => float opnd
180 :     | I.FILDLL opnd => float opnd
181 : monnier 247 | I.FBINARY{src, ...} => ([], operandUse src)
182 : leunga 565 | I.FIBINARY{src, ...} => ([], operandUse src)
183 : george 545 | I.FENV{opnd, ...} => ([], operandUse opnd)
184 : monnier 247 | I.FNSTSW => ([C.eax], [])
185 :     | I.SAHF => ([], [C.eax])
186 : george 545 (* This sets the low order byte,
187 :     * do potentially it may define *and* use
188 :     *)
189 :     | I.CMOV{src,dst,...} => ([dst], operandAcc(src, [dst]))
190 : monnier 498 | I.ANNOTATION{a, i, ...} => defUseR i
191 : monnier 247 | _ => ([], [])
192 :     end (* defUseR *)
193 :    
194 :     fun defUseF instr = let
195 :     fun operand(I.FDirect f) = [f]
196 :     | operand _ = []
197 :     in
198 :     case instr
199 : george 555 of I.FSTPT opnd => (operand opnd, [])
200 :     | I.FSTPL opnd => (operand opnd, [])
201 : george 545 | I.FSTPS opnd => (operand opnd, [])
202 : george 555 | I.FLDT opnd => ([], operand opnd)
203 : george 545 | I.FLDL opnd => ([], operand opnd)
204 :     | I.FLDS opnd => ([], operand opnd)
205 : monnier 411 | I.CALL(_, defs, uses,_) => (#2 defs, #2 uses)
206 : monnier 247 | I.FBINARY{dst, src, ...}=> (operand dst, operand dst @ operand src)
207 :     | I.FCOPY{dst, src, tmp=SOME(I.FDirect f), ...} => (f::dst, src)
208 :     | I.FCOPY{dst, src, ...} => (dst, src)
209 : monnier 498 | I.ANNOTATION{a, i, ...} => defUseF i
210 : monnier 247 | _ => ([], [])
211 :     end
212 :    
213 :     fun defUse C.GP = defUseR
214 :     | defUse C.FP = defUseF
215 :     | defUse _ = error "defUse"
216 : monnier 411
217 :     (*========================================================================
218 :     * Annotations
219 :     *========================================================================*)
220 : monnier 469 fun getAnnotations(I.ANNOTATION{i,a}) =
221 :     let val (i,an) = getAnnotations i in (i,a::an) end
222 :     | getAnnotations i = (i,[])
223 : monnier 411 fun annotate(i,a) = I.ANNOTATION{i=i,a=a}
224 : monnier 247 end
225 :    

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