Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Diff of /sml/trunk/src/MLRISC/x86/ra/x86Spill.sml
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

sml/branches/SMLNJ/src/MLRISC/x86/ra/x86Spill.sml revision 498, Tue Dec 7 15:44:50 1999 UTC sml/trunk/src/MLRISC/x86/ra/x86Spill.sml revision 579, Wed Mar 22 06:33:08 2000 UTC
# Line 2  Line 2 
2   *   *
3   * X86 spilling is complicated business.   * X86 spilling is complicated business.
4   * Allen: and it just got more complicated; now we have to recognize the regmap.   * Allen: and it just got more complicated; now we have to recognize the regmap.
5     * I've also improved the spilling code so that more instructions are
6     * recognized.  Addressing modes are now folded into the existing instruction
7     * whenever possible.  This eliminates some redundant temporaries which were
8     * introduced before.
9   *)   *)
10  signature X86SPILL = sig  signature X86SPILL = sig
11    structure I : X86INSTR    structure I : X86INSTR
# Line 34  Line 38 
38    
39    fun immed(I.Immed _) = true    fun immed(I.Immed _) = true
40      | immed(I.ImmedLabel _) = true      | immed(I.ImmedLabel _) = true
     | immed(I.Const _) = true  
     | immed(I.LabelEA _) = true  
41      | immed _ = false      | immed _ = false
42    
43    fun immedOrReg(I.Direct r) = true    fun immedOrReg(I.Direct r) = true
44      | immedOrReg(I.Immed _) = true      | immedOrReg(I.Immed _) = true
45      | immedOrReg(I.ImmedLabel _) = true      | immedOrReg(I.ImmedLabel _) = true
     | immedOrReg(I.Const _) = true  
     | immedOrReg(I.LabelEA _) = true  
46      | immedOrReg _ = false      | immedOrReg _ = false
47    
48      fun isMemory(I.MemReg _) = true
49        | isMemory(I.Displace _) = true
50        | isMemory(I.Indexed _) = true
51        | isMemory(I.LabelEA _) = true
52        | isMemory _ = false
53    
54    (* Annotate instruction *)    (* Annotate instruction *)
55    fun mark(instr,[]) = instr    fun mark(instr,[]) = instr
56      | mark(instr,a::an) = mark(I.ANNOTATION{i=instr,a=a},an)      | mark(instr,a::an) = mark(I.ANNOTATION{i=instr,a=a},an)
# Line 61  Line 67 
67        case instr of        case instr of
68          I.CALL(addr, defs, uses, mem) =>          I.CALL(addr, defs, uses, mem) =>
69            done(I.CALL(addr, C.rmvReg(reg,defs), uses, mem), an)            done(I.CALL(addr, C.rmvReg(reg,defs), uses, mem), an)
70        | I.MOVE{mvOp=I.MOVZX, src, dst} =>        | I.MOVE{mvOp as (I.MOVZBL|I.MOVSBL|I.MOVZWL|I.MOVSWL), src, dst} =>
71            let val tmpR = newReg() val tmp = I.Direct tmpR            let val tmpR = newReg() val tmp = I.Direct tmpR
72            in  {proh=[tmpR], newReg=SOME tmpR,            in  {proh=[tmpR], newReg=SOME tmpR,
73                 code=[mark(I.MOVE{mvOp=I.MOVZX, src=src, dst=tmp}, an),                 code=[mark(I.MOVE{mvOp=mvOp, src=src, dst=tmp}, an),
74                       I.MOVE{mvOp=I.MOVL, src=tmp, dst=spillLoc}]                       I.MOVE{mvOp=I.MOVL, src=tmp, dst=spillLoc}]
75                }                }
76            end            end
# Line 92  Line 98 
98                       I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]                       I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]
99                }                }
100            end            end
101          | I.BINARY{binOp=I.XORL, src as I.Direct rs, dst=I.Direct rd} =>
102              if rs=rd then
103                 {proh=[],
104                  code=[mark(I.MOVE{mvOp=I.MOVL, src=I.Immed 0, dst=spillLoc}, an)],
105                  newReg=NONE
106                 }
107              else
108                 {proh=[],
109                  code=[mark(I.BINARY{binOp=I.XORL, src=src, dst=spillLoc}, an)],
110                  newReg=NONE
111                 }
112        | I.BINARY{binOp, src, dst} => (* note: dst = reg *)        | I.BINARY{binOp, src, dst} => (* note: dst = reg *)
113            if immedOrReg src then            if immedOrReg src then
114               {proh=[],               {proh=[],
# Line 120  Line 137 
137                }                }
138            end            end
139        | I.UNARY{unOp, opnd} => done(I.UNARY{unOp=unOp, opnd=spillLoc}, an)        | I.UNARY{unOp, opnd} => done(I.UNARY{unOp=unOp, opnd=spillLoc}, an)
140          | I.SET{cond, opnd} => done(I.SET{cond=cond, opnd=spillLoc}, an)
141        | I.POP _ => done(I.POP spillLoc, an)        | I.POP _ => done(I.POP spillLoc, an)
142        | I.COPY _ => error "spill: COPY"        | I.COPY _ => error "spill: COPY"
143        | I.FNSTSW  => error "spill: FNSTSW"        | I.FNSTSW  => error "spill: FNSTSW"
# Line 174  Line 192 
192          }          }
193      end      end
194    
195        fun replace(opn as I.Direct r) = if regmap r = reg then spillLoc else opn
196          | replace opn         = opn
197    
198        (* Fold in a memory operand if possible.  Makes sure that both operands
199         * are not in memory.  lsrc cannot be immediate.
200         *)
201        fun reloadCmp(cmp, lsrc, rsrc, an) =
202            let fun reloadIt() =
203                  withTmp(fn tmpR =>
204                    cmp{lsrc=operand(tmpR, lsrc), rsrc=operand(tmpR, rsrc)}, an)
205            in  if immedOrReg lsrc andalso immedOrReg rsrc then
206                let val lsrc' = replace lsrc
207                    val rsrc' = replace rsrc
208                in  if isMemory lsrc' andalso isMemory rsrc' then
209                       reloadIt()
210                    else
211                       done(cmp{lsrc=lsrc', rsrc=rsrc'}, an)
212                end
213                else reloadIt()
214            end
215    
216        (* Fold in a memory operand if possible.  Makes sure that the right
217         * operand is not in memory and left operand is not an immediate.
218         *  lsrc   rsrc
219         *   AL,   imm8  opc1 A8
220         *  EAX,   imm32 opc1 A9
221         *  r/m8,  imm8  opc2 F6/0 ib
222         *  r/m32, imm32 opc2 F7/0 id
223         *  r/m32, r32   opc3 85/r
224         *)
225        fun reloadTest(test, lsrc, rsrc, an) =
226            let fun reloadIt() =
227                   withTmp(fn tmpR =>
228                     test{lsrc=operand(tmpR, lsrc), rsrc=operand(tmpR, rsrc)}, an)
229            in  if immedOrReg lsrc andalso immedOrReg rsrc then
230                let val lsrc = replace lsrc
231                    val rsrc = replace rsrc
232                in  if isMemory rsrc then
233                       if isMemory lsrc then reloadIt()
234                       else (* it is commutative! *)
235                          done(test{lsrc=rsrc, rsrc=lsrc}, an)
236                    else
237                       done(test{lsrc=lsrc, rsrc=rsrc}, an)
238                end
239                else reloadIt()
240            end
241    
242        fun reloadPush(push, arg as I.Direct _, an) =
243              done(push(replace arg), an)
244          | reloadPush(push, arg, an) =
245              withTmp(fn tmpR => push(operand(tmpR, arg)), an)
246    
247        fun reloadReal(realOp, opnd, an) =
248              withTmp'(fn tmpR => realOp(operand(tmpR, opnd)), an)
249    
250      fun reloadIt(instr, an) =      fun reloadIt(instr, an) =
251      case instr      case instr
252      of I.JMP(I.Direct _, labs) => done(I.JMP(spillLoc, labs), an)      of I.JMP(I.Direct _, labs) => done(I.JMP(spillLoc, labs), an)
# Line 190  Line 263 
263                    an)]                    an)]
264             }             }
265         end         end
266         | I.MOVE{mvOp, src as I.Direct _, dst as I.Direct _} =>
267            done(I.MOVE{mvOp=mvOp, src=replace src, dst=dst},an)
268       | I.MOVE{mvOp, src, dst as I.Direct _} =>       | I.MOVE{mvOp, src, dst as I.Direct _} =>
269          withTmp'(fn t =>I.MOVE{mvOp=mvOp, src=operand(t, src), dst=dst},an)          withTmp'(fn t =>I.MOVE{mvOp=mvOp, src=operand(t, src), dst=dst},an)
270       | I.MOVE{mvOp, src as I.Direct _, dst} =>       | I.MOVE{mvOp, src as I.Direct _, dst} =>
# Line 203  Line 278 
278              I.MOVE{mvOp=mvOp, src=operand(t, src), dst=operand(t, dst)}, an)              I.MOVE{mvOp=mvOp, src=operand(t, src), dst=operand(t, dst)}, an)
279       | I.LEA{r32, addr} =>       | I.LEA{r32, addr} =>
280          withTmp'(fn tmpR => I.LEA{r32=r32, addr=operand(tmpR, addr)}, an)          withTmp'(fn tmpR => I.LEA{r32=r32, addr=operand(tmpR, addr)}, an)
281       | I.CMP{lsrc, rsrc} =>       | I.CMPL{lsrc, rsrc} => reloadCmp(I.CMPL, lsrc, rsrc, an)
282          withTmp(fn tmpR =>       | I.CMPW{lsrc, rsrc} => reloadCmp(I.CMPW, lsrc, rsrc, an)
283            I.CMP{lsrc=operand(tmpR, lsrc), rsrc=operand(tmpR, rsrc)}, an)       | I.CMPB{lsrc, rsrc} => reloadCmp(I.CMPB, lsrc, rsrc, an)
284         | I.TESTL{lsrc, rsrc} => reloadTest(I.TESTL, lsrc, rsrc, an)
285         | I.TESTW{lsrc, rsrc} => reloadTest(I.TESTW, lsrc, rsrc, an)
286         | I.TESTB{lsrc, rsrc} => reloadTest(I.TESTB, lsrc, rsrc, an)
287       | I.BINARY{binOp, src, dst as I.Direct _} =>       | I.BINARY{binOp, src, dst as I.Direct _} =>
288          withTmp(fn tmpR =>            (case src of
289                I.Direct _ =>
290                  done(I.BINARY{binOp=binOp, src=replace src, dst=dst},an)
291              | _ => withTmp(fn tmpR =>
292              I.BINARY{binOp=binOp, src=operand(tmpR, src), dst=dst}, an)              I.BINARY{binOp=binOp, src=operand(tmpR, src), dst=dst}, an)
293              )
294       | I.BINARY{binOp, src, dst} =>       | I.BINARY{binOp, src, dst} =>
295          withTmp(fn tmpR => I.BINARY{binOp=binOp, src=operand(tmpR, src),          withTmp(fn tmpR => I.BINARY{binOp=binOp, src=operand(tmpR, src),
296                                                   dst=operand(tmpR, dst)}, an)                                                   dst=operand(tmpR, dst)}, an)
297         | I.MULTDIV{multDivOp, src as I.Direct _} =>
298            done(I.MULTDIV{multDivOp=multDivOp, src=replace src}, an)
299       | I.MULTDIV{multDivOp, src} =>       | I.MULTDIV{multDivOp, src} =>
300          withTmp(fn tmpR =>          withTmp(fn tmpR =>
301              I.MULTDIV{multDivOp=multDivOp, src=operand(tmpR, src)}, an)              I.MULTDIV{multDivOp=multDivOp, src=operand(tmpR, src)}, an)
# Line 221  Line 305 
305                   dst=if regmap dst = reg then error "reload:MUL3" else dst}, an)                   dst=if regmap dst = reg then error "reload:MUL3" else dst}, an)
306       | I.UNARY{unOp, opnd} =>       | I.UNARY{unOp, opnd} =>
307          withTmp'(fn tmpR => I.UNARY{unOp=unOp, opnd=operand(tmpR, opnd)}, an)          withTmp'(fn tmpR => I.UNARY{unOp=unOp, opnd=operand(tmpR, opnd)}, an)
308       | I.PUSH arg => withTmp(fn tmpR => I.PUSH(operand(tmpR, arg)), an)       | I.SET{cond, opnd} =>
309            withTmp'(fn tmpR => I.SET{cond=cond, opnd=operand(tmpR, opnd)}, an)
310         | I.PUSHL arg => reloadPush(I.PUSHL, arg, an)
311         | I.PUSHW arg => reloadPush(I.PUSHW, arg, an)
312         | I.PUSHB arg => reloadPush(I.PUSHB, arg, an)
313       | I.COPY _ => error "reload:COPY"       | I.COPY _ => error "reload:COPY"
314       | I.FILD opnd => withTmp'(fn tmpR => I.FILD(operand(tmpR, opnd)), an)       | I.FILD opnd => reloadReal(I.FILD, opnd, an)
315       | I.FLD opnd => withTmp'(fn tmpR => I.FLD(operand(tmpR, opnd)), an)       | I.FILDL opnd => reloadReal(I.FILDL, opnd, an)
316       | I.FSTP opnd => withTmp'(fn tmpR => I.FSTP(operand(tmpR, opnd)), an)       | I.FILDLL opnd => reloadReal(I.FILDLL, opnd, an)
317         | I.FLDT opnd => reloadReal(I.FLDT, opnd, an)
318         | I.FLDL opnd => reloadReal(I.FLDL, opnd, an)
319         | I.FLDS opnd => reloadReal(I.FLDS, opnd, an)
320         | I.FSTPT opnd => reloadReal(I.FSTPT, opnd, an)
321         | I.FSTPL opnd => reloadReal(I.FSTPL, opnd, an)
322         | I.FSTPS opnd => reloadReal(I.FSTPS, opnd, an)
323         | I.FSTL opnd => reloadReal(I.FSTL, opnd, an)
324         | I.FSTS opnd => reloadReal(I.FSTS, opnd, an)
325         | I.FENV{fenvOp, opnd} => reloadReal(fn opnd =>
326                                     I.FENV{fenvOp=fenvOp,opnd=opnd}, opnd, an)
327       | I.FBINARY{binOp, src, dst} =>       | I.FBINARY{binOp, src, dst} =>
328          withTmp'(fn tmpR =>          withTmp'(fn tmpR =>
329                   I.FBINARY{binOp=binOp, src=operand(tmpR, src), dst=dst}, an)                   I.FBINARY{binOp=binOp, src=operand(tmpR, src), dst=dst}, an)
330         | I.FIBINARY{binOp, src} =>
331            withTmp'(fn tmpR => I.FIBINARY{binOp=binOp, src=operand(tmpR, src)}, an)
332       | I.ANNOTATION{i,a} => reloadIt(i, a::an)       | I.ANNOTATION{i,a} => reloadIt(i, a::an)
333       | _ => error "reload"       | _ => error "reload"
334    in reloadIt(instr, [])    in reloadIt(instr, [])
# Line 238  Line 337 
337    fun fspill(instr, regmap, reg, spillLoc) =    fun fspill(instr, regmap, reg, spillLoc) =
338    let fun spillIt(instr, an) =    let fun spillIt(instr, an) =
339        (case instr of        (case instr of
340           I.FSTP _ => {proh=[], code=[mark(I.FSTP spillLoc, an)], newReg=NONE}           I.FSTPL _ => {proh=[], code=[mark(I.FSTPL spillLoc, an)], newReg=NONE}
341           | I.FSTPS _ => {proh=[], code=[mark(I.FSTPS spillLoc, an)], newReg=NONE}
342           | I.FSTL _ => {proh=[], code=[mark(I.FSTL spillLoc, an)], newReg=NONE}
343           | I.FSTS _ => {proh=[], code=[mark(I.FSTS spillLoc, an)], newReg=NONE}
344         | I.CALL(opnd, defs, uses, mem) =>         | I.CALL(opnd, defs, uses, mem) =>
345           {proh=[],           {proh=[],
346            code=[mark(I.CALL(opnd, C.rmvFreg(reg,defs), uses, mem), an)],            code=[mark(I.CALL(opnd, C.rmvFreg(reg,defs), uses, mem), an)],
# Line 252  Line 354 
354    fun freload(instr, regmap, reg, spillLoc) =    fun freload(instr, regmap, reg, spillLoc) =
355    let fun reloadIt(instr, an) =    let fun reloadIt(instr, an) =
356        (case instr of        (case instr of
357           I.FLD opnd => {code=[mark(I.FLD spillLoc, an)], proh=[], newReg=NONE}           I.FLDT opnd => {code=[mark(I.FLDT spillLoc, an)], proh=[], newReg=NONE}
358           | I.FLDL opnd => {code=[mark(I.FLDL spillLoc, an)], proh=[], newReg=NONE}
359           | I.FLDS opnd => {code=[mark(I.FLDS spillLoc, an)], proh=[], newReg=NONE}
360         | I.FBINARY{binOp, src=I.FDirect f, dst} =>         | I.FBINARY{binOp, src=I.FDirect f, dst} =>
361             if regmap f = reg then             if regmap f = reg then
362               {code=[mark(I.FBINARY{binOp=binOp, src=spillLoc, dst=dst}, an)],               {code=[mark(I.FBINARY{binOp=binOp, src=spillLoc, dst=dst}, an)],

Legend:
Removed from v.498  
changed lines
  Added in v.579

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