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/ra/x86Spill.sml
ViewVC logotype

Annotation of /sml/trunk/src/MLRISC/x86/ra/x86Spill.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 429 - (view) (download)
Original Path: sml/branches/SMLNJ/src/MLRISC/x86/ra/x86Spill.sml

1 : monnier 247 (* X86Spill.sml
2 :     *
3 :     * X86 spilling is complicated business.
4 :     *)
5 :     signature X86SPILL = sig
6 :     structure I : X86INSTR
7 :     val spill :
8 :     I.instruction * int * I.operand ->
9 :     {code:I.instruction list, proh:int list, instr:I.instruction option}
10 :    
11 :     val reload :
12 :     I.instruction * int * I.operand -> {code:I.instruction list, proh:int list}
13 :    
14 :     val fspill :
15 :     I.instruction * int * I.operand ->
16 :     {code:I.instruction list, proh:int list, instr:I.instruction option}
17 :    
18 :     val freload :
19 :     I.instruction * int * I.operand -> {code:I.instruction list, proh:int list}
20 :     end
21 :    
22 :    
23 :     functor X86Spill(structure Instr: X86INSTR
24 : monnier 411 structure Asm : INSTRUCTION_EMITTER where I = Instr (* XXX *)
25 : monnier 247
26 :     ) : X86SPILL = struct
27 :    
28 :     (* XXX: Looks like the wrong thing is done with CMPL.
29 :     * That is to say, does not recognize memory arguments.
30 :     *)
31 : monnier 429 structure I = Instr
32 :     structure C = I.C
33 :     structure SL = SortedList
34 : monnier 247
35 : monnier 411 fun error msg = MLRiscErrorMsg.impossible("X86Spill: "^ msg)
36 : monnier 247
37 :     type s = I.instruction * int * I.operand ->
38 :     {code:I.instruction list, proh:int list, instr:I.instruction option}
39 :     type r = I.instruction * int * I.operand -> {code:I.instruction list, proh:int list}
40 :    
41 :     val newReg = C.newReg
42 :    
43 :     fun immed(I.Immed _) = true
44 :     | immed(I.ImmedLabel _) = true
45 :     | immed(I.Const _) = true
46 :     | immed(I.LabelEA _) = true
47 :     | immed _ = false
48 :    
49 :     fun immedOrReg(I.Direct r) = true
50 :     | immedOrReg opnd = immed opnd
51 :    
52 : monnier 411 fun eqEA(I.Displace{base=b1, disp=d1,...},I.Displace{base=b2, disp=d2,...}) =
53 : monnier 247 b1=b2 andalso
54 :     (case (d1, d2)
55 :     of (I.Immed i1, I.Immed i2) => i1 = i2
56 :     | _ => false
57 :     (*esac*))
58 :     | eqEA _ = false
59 :    
60 :     (* XXX:: Need to go through all the cases where 'done' is used
61 :     * to make sure that a the src cannot contain the register
62 :     * being spilled.
63 :     *)
64 :     fun spill(instr, reg, spillLoc) = let
65 :     fun done code = {code=code, proh=[], instr=NONE}
66 :     fun rewrite new old = if old=reg then new else old
67 : monnier 411 fun spillIt instr =
68 : monnier 247 case instr
69 : monnier 429 of I.CALL(opnd, defs, uses, mem) =>
70 :     {proh=[],
71 :     instr=SOME(I.CALL(opnd, C.rmvReg(reg,defs), uses, mem)),
72 :     code=[] }
73 : monnier 247 | I.MOVE{mvOp=I.MOVZX, src, dst} => let(* dst must always be a register *)
74 :     val tmpR = newReg()
75 :     in
76 :     {proh=[tmpR],
77 :     instr=SOME(I.MOVE{mvOp=I.MOVZX, src=src, dst=I.Direct tmpR}),
78 :     code=[I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]}
79 :     end
80 :     | I.MOVE{mvOp, src as I.Direct rs, dst} =>
81 :     if rs=reg then {code=[], proh=[], instr=NONE}
82 :     else done [I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}]
83 :     | I.MOVE{mvOp, src, dst=I.Direct _} =>
84 :     if immed src then done [I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}]
85 :     else if eqEA(src, spillLoc) then {code=[], proh=[], instr=NONE}
86 :     else let
87 :     val tmpR = newReg()
88 :     in
89 :     {instr=SOME(I.MOVE{mvOp=mvOp, src=src, dst=I.Direct tmpR}),
90 :     proh=[tmpR],
91 :     code=[I.MOVE{mvOp=mvOp, src=I.Direct tmpR, dst=spillLoc}]}
92 :     end
93 :     | I.LEA{addr, r32} => let
94 :     val tmpR = newReg()
95 :     in {instr=SOME(I.LEA{addr=addr, r32=tmpR}),
96 :     proh=[tmpR],
97 :     code=[I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]}
98 :     end
99 :     | I.BINARY{binOp, src, dst} =>
100 :     if immedOrReg src then
101 :     {instr=SOME(I.BINARY{binOp=binOp, src=src, dst=spillLoc}),
102 :     proh=[],
103 :     code=[]}
104 :     else let
105 :     val tmpR = newReg()
106 :     in
107 :     {instr=SOME(I.MOVE{mvOp=I.MOVL, src=src, dst=I.Direct tmpR}),
108 :     proh=[tmpR],
109 :     code=[I.BINARY{binOp=binOp, src=I.Direct tmpR, dst=spillLoc}]}
110 :     end
111 :     | I.MULTDIV _ => error "spill: MULTDIV"
112 :     | I.MUL3{src1, src2, dst} => let
113 :     val tmpR = newReg()
114 :     in
115 :     {instr=SOME(I.MUL3{src1=src1, src2=src2, dst=tmpR}),
116 :     proh=[tmpR],
117 :     code=[I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]}
118 :     end
119 :     | I.UNARY{unOp, opnd} => done [I.UNARY{unOp=unOp, opnd=spillLoc}]
120 :     | I.POP _ => done [I.POP spillLoc]
121 :     | I.COPY _ => error "spill: COPY"
122 :     | I.FNSTSW => error "spill: FNSTSW"
123 : monnier 411 | I.ANNOTATION{i,a} => spillIt i
124 : monnier 247 | _ => error "spill"
125 : monnier 411 in spillIt instr
126 : monnier 247 end
127 :    
128 :     fun reload(instr, reg, spillLoc) = let
129 :     fun operand(rt, opnd) =
130 :     (case opnd
131 :     of I.Direct r => if r=reg then I.Direct rt else opnd
132 : monnier 411 | I.Displace{base, disp, mem} =>
133 :     if base=reg then I.Displace{base=rt, disp=disp, mem=mem} else opnd
134 :     | I.Indexed{base=NONE, index, scale, disp, mem=mem} =>
135 : monnier 247 if index=reg then
136 : monnier 411 I.Indexed{base=NONE, index=rt, scale=scale, disp=disp, mem=mem}
137 : monnier 247 else opnd
138 : monnier 411 | I.Indexed{base as SOME b, index, scale, disp, mem=mem} =>
139 : monnier 247 if b=reg then
140 :     operand(rt, I.Indexed{base=SOME rt, index=index,
141 : monnier 411 scale=scale, disp=disp, mem=mem})
142 : monnier 247 else if index=reg then
143 : monnier 411 I.Indexed{base=base, index=rt, scale=scale, disp=disp, mem=mem}
144 : monnier 247 else opnd
145 :     | opnd => opnd
146 :     (*esac*))
147 :    
148 :     fun uses(I.Direct r) = r = reg (* XXX *)
149 : monnier 411 | uses(I.Displace{base, disp, mem}) = base=reg
150 :     | uses(I.Indexed{base=NONE, index, scale, disp, mem}) = index=reg
151 :     | uses(I.Indexed{base=SOME b, index, scale, disp, mem})=
152 :     b=reg orelse index=reg
153 : monnier 247 | uses _ = false
154 :     fun done c = {code=c, proh=[]}
155 :     fun rewrite rt r = if r=reg then rt else r
156 :     fun ldSpillLoc (tmpR) = I.MOVE{mvOp=I.MOVL, src=spillLoc, dst=I.Direct tmpR}
157 :     fun withTmp f = let
158 :     val tmpR = newReg()
159 :     in {code=[ldSpillLoc(tmpR), f tmpR], proh=[tmpR]}
160 :     end
161 : monnier 411 fun reloadIt instr =
162 : monnier 247 case instr
163 :     of I.JMP(I.Direct _, labs) => {code=[I.JMP(spillLoc, labs)], proh=[]}
164 :     | I.JMP(opnd, labs) => withTmp(fn tmpR => I.JMP(operand(tmpR, opnd), labs))
165 :     | I.JCC{opnd=I.Direct _, cond} => done[I.JCC{opnd=spillLoc, cond=cond}]
166 :     | I.JCC{opnd, cond} =>
167 :     withTmp(fn tmpR => I.JCC{opnd=operand(tmpR, opnd), cond=cond})
168 : monnier 429 | I.CALL(opnd, defs, uses, mem) => let
169 :     val tmpR = newReg()
170 :     in
171 :     {code=[I.CALL(operand(tmpR, opnd), defs, C.rmvReg(reg,uses), mem)],
172 :     proh=[tmpR]}
173 :     end
174 : monnier 247 | I.MOVE{mvOp, src, dst as I.Direct _} =>
175 :     withTmp(fn tmpR =>I.MOVE{mvOp=mvOp, src=operand(tmpR, src), dst=dst})
176 :     | I.MOVE{mvOp, src as I.Direct _, dst} =>
177 :     if eqEA(dst, spillLoc) then {code=[], proh=[]}
178 :     else withTmp
179 :     (fn tmpR =>
180 :     I.MOVE{mvOp=mvOp, src=operand(tmpR, src), dst=operand(tmpR, dst)})
181 :     | I.MOVE{mvOp, src, dst} =>
182 :     withTmp
183 :     (fn tmpR =>
184 :     I.MOVE{mvOp=mvOp, src=operand(tmpR, src), dst=operand(tmpR, dst)})
185 :     | I.LEA{r32, addr} =>
186 :     withTmp(fn tmpR => I.LEA{r32=r32, addr=operand(tmpR, addr)})
187 :     | I.CMP{lsrc, rsrc} =>
188 :     withTmp(fn tmpR => I.CMP{lsrc=operand(tmpR, lsrc), rsrc=operand(tmpR, rsrc)})
189 :     | I.BINARY{binOp, src, dst as I.Direct _} =>
190 :     withTmp(fn tmpR => I.BINARY{binOp=binOp, src=operand(tmpR, src), dst=dst})
191 :     | I.BINARY{binOp, src, dst} =>
192 :     withTmp
193 :     (fn tmpR =>
194 :     I.BINARY{binOp=binOp, src=operand(tmpR, src), dst=operand(tmpR,dst)})
195 :     | I.MULTDIV{multDivOp, src} =>
196 :     withTmp(fn tmpR => I.MULTDIV{multDivOp=multDivOp, src=operand(tmpR, src)})
197 :     | I.MUL3{src1, src2, dst} =>
198 :     withTmp(fn tmpR =>
199 :     I.MUL3{src1=operand(tmpR, src1), src2=src2,
200 :     dst=if dst = reg then error "reload:MUL3" else dst})
201 :     | I.UNARY{unOp, opnd} =>
202 :     withTmp(fn tmpR => I.UNARY{unOp=unOp, opnd=operand(tmpR, opnd)})
203 :     | I.PUSH arg => withTmp(fn tmpR => I.PUSH(operand(tmpR, arg)))
204 :     | I.COPY _ => error "reload:COPY"
205 :     | I.FILD opnd => withTmp(fn tmpR => I.FILD(operand(tmpR, opnd)))
206 :     | I.FLD opnd =>
207 :     withTmp (fn tmpR => I.FLD(operand(tmpR, opnd)))
208 :     | I.FSTP opnd =>
209 :     withTmp(fn tmpR => I.FSTP(operand(tmpR, opnd)))
210 :     | I.FBINARY{binOp, src, dst} =>
211 :     withTmp(fn tmpR =>
212 :     I.FBINARY{binOp=binOp, src=operand(tmpR, src), dst=dst})
213 :    
214 : monnier 411 | I.ANNOTATION{i,a} => reloadIt i
215 : monnier 247 | _ => error "reload"
216 : monnier 411 in reloadIt instr
217 : monnier 247 end (*reload*)
218 :    
219 :     fun fspill(instr, reg, spillLoc) =
220 :     (case instr
221 :     of I.FSTP _ => {proh=[], instr=NONE, code=[I.FSTP spillLoc]}
222 : monnier 429 | I.CALL(opnd, defs, uses, mem) =>
223 :     {proh=[],
224 :     instr=SOME(I.CALL(opnd, C.rmvFreg(reg,defs), uses, mem)),
225 :     code=[] }
226 : monnier 411 | I.ANNOTATION{i,a} => fspill(i, reg, spillLoc)
227 : monnier 247 | _ => error "fspill"
228 :     (*esac*))
229 :    
230 :     fun freload(instr, reg, spillLoc) =
231 :     (case instr
232 :     of I.FLD opnd => {code=[I.FLD spillLoc], proh=[]}
233 :     | I.FBINARY{binOp, src=I.FDirect f, dst} =>
234 :     if f = reg then
235 :     {code=[I.FBINARY{binOp=binOp, src=spillLoc, dst=dst}],
236 :     proh=[]}
237 :     else error "freload:FBINARY"
238 : monnier 429 | I.CALL(opnd, defs, uses, mem) =>
239 :     {proh=[],
240 :     code=[I.CALL(opnd, C.rmvFreg(reg,defs), uses, mem)]}
241 : monnier 411 | I.ANNOTATION{i,a} => freload(i, reg, spillLoc)
242 : monnier 247 | _ => error "freload"
243 :     (*esac*))
244 : monnier 411 end

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