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 411 - (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 :     structure I = Instr
32 :     structure C = I.C
33 :    
34 : monnier 411 fun error msg = MLRiscErrorMsg.impossible("X86Spill: "^ msg)
35 : monnier 247
36 :     type s = I.instruction * int * I.operand ->
37 :     {code:I.instruction list, proh:int list, instr:I.instruction option}
38 :     type r = I.instruction * int * I.operand -> {code:I.instruction list, proh:int list}
39 :    
40 :     val newReg = C.newReg
41 :    
42 :     fun immed(I.Immed _) = true
43 :     | immed(I.ImmedLabel _) = true
44 :     | immed(I.Const _) = true
45 :     | immed(I.LabelEA _) = true
46 :     | immed _ = false
47 :    
48 :     fun immedOrReg(I.Direct r) = true
49 :     | immedOrReg opnd = immed opnd
50 :    
51 : monnier 411 fun eqEA(I.Displace{base=b1, disp=d1,...},I.Displace{base=b2, disp=d2,...}) =
52 : monnier 247 b1=b2 andalso
53 :     (case (d1, d2)
54 :     of (I.Immed i1, I.Immed i2) => i1 = i2
55 :     | _ => false
56 :     (*esac*))
57 :     | eqEA _ = false
58 :    
59 :     (* XXX:: Need to go through all the cases where 'done' is used
60 :     * to make sure that a the src cannot contain the register
61 :     * being spilled.
62 :     *)
63 :     fun spill(instr, reg, spillLoc) = let
64 :     fun done code = {code=code, proh=[], instr=NONE}
65 :     fun rewrite new old = if old=reg then new else old
66 : monnier 411 fun spillIt instr =
67 : monnier 247 case instr
68 : monnier 411 of I.CALL(opnd, (r,f,c), uses, mem) => let
69 : monnier 247 val tmpR = newReg()
70 :     in
71 :     {proh=[tmpR],
72 : monnier 411 instr=SOME(I.CALL(opnd, (map (rewrite tmpR) r,f,c), uses, mem)),
73 : monnier 247 code=[I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}] }
74 :     end
75 :     | I.MOVE{mvOp=I.MOVZX, src, dst} => let(* dst must always be a register *)
76 :     val tmpR = newReg()
77 :     in
78 :     {proh=[tmpR],
79 :     instr=SOME(I.MOVE{mvOp=I.MOVZX, src=src, dst=I.Direct tmpR}),
80 :     code=[I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]}
81 :     end
82 :     | I.MOVE{mvOp, src as I.Direct rs, dst} =>
83 :     if rs=reg then {code=[], proh=[], instr=NONE}
84 :     else done [I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}]
85 :     | I.MOVE{mvOp, src, dst=I.Direct _} =>
86 :     if immed src then done [I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}]
87 :     else if eqEA(src, spillLoc) then {code=[], proh=[], instr=NONE}
88 :     else let
89 :     val tmpR = newReg()
90 :     in
91 :     {instr=SOME(I.MOVE{mvOp=mvOp, src=src, dst=I.Direct tmpR}),
92 :     proh=[tmpR],
93 :     code=[I.MOVE{mvOp=mvOp, src=I.Direct tmpR, dst=spillLoc}]}
94 :     end
95 :     | I.LEA{addr, r32} => let
96 :     val tmpR = newReg()
97 :     in {instr=SOME(I.LEA{addr=addr, r32=tmpR}),
98 :     proh=[tmpR],
99 :     code=[I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]}
100 :     end
101 :     | I.BINARY{binOp, src, dst} =>
102 :     if immedOrReg src then
103 :     {instr=SOME(I.BINARY{binOp=binOp, src=src, dst=spillLoc}),
104 :     proh=[],
105 :     code=[]}
106 :     else let
107 :     val tmpR = newReg()
108 :     in
109 :     {instr=SOME(I.MOVE{mvOp=I.MOVL, src=src, dst=I.Direct tmpR}),
110 :     proh=[tmpR],
111 :     code=[I.BINARY{binOp=binOp, src=I.Direct tmpR, dst=spillLoc}]}
112 :     end
113 :     | I.MULTDIV _ => error "spill: MULTDIV"
114 :     | I.MUL3{src1, src2, dst} => let
115 :     val tmpR = newReg()
116 :     in
117 :     {instr=SOME(I.MUL3{src1=src1, src2=src2, dst=tmpR}),
118 :     proh=[tmpR],
119 :     code=[I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]}
120 :     end
121 :     | I.UNARY{unOp, opnd} => done [I.UNARY{unOp=unOp, opnd=spillLoc}]
122 :     | I.POP _ => done [I.POP spillLoc]
123 :     | I.COPY _ => error "spill: COPY"
124 :     | I.FNSTSW => error "spill: FNSTSW"
125 : monnier 411 | I.ANNOTATION{i,a} => spillIt i
126 : monnier 247 | _ => error "spill"
127 : monnier 411 in spillIt instr
128 : monnier 247 end
129 :    
130 :     fun reload(instr, reg, spillLoc) = let
131 :     fun operand(rt, opnd) =
132 :     (case opnd
133 :     of I.Direct r => if r=reg then I.Direct rt else opnd
134 : monnier 411 | I.Displace{base, disp, mem} =>
135 :     if base=reg then I.Displace{base=rt, disp=disp, mem=mem} else opnd
136 :     | I.Indexed{base=NONE, index, scale, disp, mem=mem} =>
137 : monnier 247 if index=reg then
138 : monnier 411 I.Indexed{base=NONE, index=rt, scale=scale, disp=disp, mem=mem}
139 : monnier 247 else opnd
140 : monnier 411 | I.Indexed{base as SOME b, index, scale, disp, mem=mem} =>
141 : monnier 247 if b=reg then
142 :     operand(rt, I.Indexed{base=SOME rt, index=index,
143 : monnier 411 scale=scale, disp=disp, mem=mem})
144 : monnier 247 else if index=reg then
145 : monnier 411 I.Indexed{base=base, index=rt, scale=scale, disp=disp, mem=mem}
146 : monnier 247 else opnd
147 :     | opnd => opnd
148 :     (*esac*))
149 :    
150 :     fun uses(I.Direct r) = r = reg (* XXX *)
151 : monnier 411 | uses(I.Displace{base, disp, mem}) = base=reg
152 :     | uses(I.Indexed{base=NONE, index, scale, disp, mem}) = index=reg
153 :     | uses(I.Indexed{base=SOME b, index, scale, disp, mem})=
154 :     b=reg orelse index=reg
155 : monnier 247 | uses _ = false
156 :     fun done c = {code=c, proh=[]}
157 :     fun rewrite rt r = if r=reg then rt else r
158 :     fun ldSpillLoc (tmpR) = I.MOVE{mvOp=I.MOVL, src=spillLoc, dst=I.Direct tmpR}
159 :     fun withTmp f = let
160 :     val tmpR = newReg()
161 :     in {code=[ldSpillLoc(tmpR), f tmpR], proh=[tmpR]}
162 :     end
163 : monnier 411 fun reloadIt instr =
164 : monnier 247 case instr
165 :     of I.JMP(I.Direct _, labs) => {code=[I.JMP(spillLoc, labs)], proh=[]}
166 :     | I.JMP(opnd, labs) => withTmp(fn tmpR => I.JMP(operand(tmpR, opnd), labs))
167 :     | I.JCC{opnd=I.Direct _, cond} => done[I.JCC{opnd=spillLoc, cond=cond}]
168 :     | I.JCC{opnd, cond} =>
169 :     withTmp(fn tmpR => I.JCC{opnd=operand(tmpR, opnd), cond=cond})
170 : monnier 411 | I.CALL(opnd, defs, uses as (r,f,c), mem) =>
171 : monnier 247 withTmp(fn tmpR =>
172 : monnier 411 I.CALL(operand(tmpR, opnd), defs,
173 :     (map (rewrite tmpR) r, f,c), mem))
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 411 | I.ANNOTATION{i,a} => fspill(i, reg, spillLoc)
223 : monnier 247 | _ => error "fspill"
224 :     (*esac*))
225 :    
226 :     fun freload(instr, reg, spillLoc) =
227 :     (case instr
228 :     of I.FLD opnd => {code=[I.FLD spillLoc], proh=[]}
229 :     | I.FBINARY{binOp, src=I.FDirect f, dst} =>
230 :     if f = reg then
231 :     {code=[I.FBINARY{binOp=binOp, src=spillLoc, dst=dst}],
232 :     proh=[]}
233 :     else error "freload:FBINARY"
234 : monnier 411 | I.ANNOTATION{i,a} => freload(i, reg, spillLoc)
235 : monnier 247 | _ => error "freload"
236 :     (*esac*))
237 : monnier 411 end

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