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 411, Fri Sep 3 00:25:03 1999 UTC sml/trunk/src/MLRISC/x86/ra/x86Spill.sml revision 545, Thu Feb 24 13:56:44 2000 UTC
# Line 1  Line 1 
1  (* X86Spill.sml  (* X86Spill.sml
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.
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
12    val spill :    val spill :
13      I.instruction * int * I.operand ->      I.instruction * (I.C.cell -> I.C.cell) * I.C.cell * I.operand ->
14        {code:I.instruction list, proh:int list, instr:I.instruction option}        {code:I.instruction list, proh:I.C.cell list, newReg:I.C.cell option}
15    
16    val reload :    val reload :
17      I.instruction * int * I.operand -> {code:I.instruction list, proh:int list}      I.instruction * (I.C.cell -> I.C.cell) * I.C.cell * I.operand ->
18          {code:I.instruction list, proh:I.C.cell list, newReg:I.C.cell option}
19    
20    val fspill :    val fspill :
21      I.instruction * int * I.operand ->      I.instruction * (I.C.cell -> I.C.cell) * I.C.cell * I.operand ->
22        {code:I.instruction list, proh:int list, instr:I.instruction option}        {code:I.instruction list, proh:I.C.cell list, newReg:I.C.cell option}
23    
24    val freload :    val freload :
25      I.instruction * int * I.operand -> {code:I.instruction list, proh:int list}      I.instruction * (I.C.cell -> I.C.cell) * I.C.cell * I.operand ->
26          {code:I.instruction list, proh:I.C.cell list, newReg:I.C.cell option}
27  end  end
28    
29    
30  functor X86Spill(structure Instr: X86INSTR  functor X86Spill(structure Instr: X86INSTR
31                   structure Asm : INSTRUCTION_EMITTER where I = Instr (* XXX *)                   structure Props: INSN_PROPERTIES where I = Instr
   
32                   ) : X86SPILL = struct                   ) : X86SPILL = struct
33    
   (* XXX: Looks like the wrong thing is done with CMPL.  
    * That is to say, does not recognize memory arguments.  
    *)  
34    structure I = Instr    structure I = Instr
35    structure C = I.C    structure C = I.C
36    
37    fun error msg = MLRiscErrorMsg.impossible("X86Spill: "^ msg)    fun error msg = MLRiscErrorMsg.impossible("X86Spill: "^ msg)
38    
   type s = I.instruction * int * I.operand ->  
              {code:I.instruction list, proh:int list, instr:I.instruction option}  
   type r = I.instruction * int * I.operand -> {code:I.instruction list, proh:int list}  
   
   val newReg = C.newReg  
   
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 opnd = immed opnd      | immedOrReg(I.Immed _) = true
45        | immedOrReg(I.ImmedLabel _) = true
46        | 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 *)
55      fun mark(instr,[]) = instr
56        | mark(instr,a::an) = mark(I.ANNOTATION{i=instr,a=a},an)
57    
58    fun eqEA(I.Displace{base=b1, disp=d1,...},I.Displace{base=b2, disp=d2,...}) =    val newReg = C.newReg
       b1=b2 andalso  
        (case (d1, d2)  
          of (I.Immed i1, I.Immed i2) => i1 = i2  
           | _ => false  
        (*esac*))  
     | eqEA _ = false  
59    
60    (* XXX:: Need to go through all the cases where 'done' is used    (* XXX:: Need to go through all the cases where 'done' is used
61     * to make sure that a the src cannot contain the register     * to make sure that a the src cannot contain the register
62     * being spilled.     * being spilled.
63     *)     *)
64    fun spill(instr, reg, spillLoc) = let    fun spill(instr, regmap, reg, spillLoc) =
65      fun done code = {code=code, proh=[], instr=NONE}    let fun done(instr, an) = {code=[mark(instr, an)], proh=[], newReg=NONE}
66      fun rewrite new old = if old=reg then new else old        fun spillIt(instr,an) =
67      fun spillIt instr =        case instr of
68      case instr          I.CALL(addr, defs, uses, mem) =>
69      of I.CALL(opnd, (r,f,c), uses, mem) => let            done(I.CALL(addr, C.rmvReg(reg,defs), uses, mem), an)
70           val tmpR = newReg()        | I.MOVE{mvOp as (I.MOVZBL|I.MOVSBL|I.MOVZWL|I.MOVSWL), src, dst} =>
71         in            let val tmpR = newReg() val tmp = I.Direct tmpR
72           {proh=[tmpR],            in  {proh=[tmpR], newReg=SOME tmpR,
73            instr=SOME(I.CALL(opnd, (map (rewrite tmpR) r,f,c), uses, mem)),                 code=[mark(I.MOVE{mvOp=mvOp, src=src, dst=tmp}, an),
74            code=[I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}] }                       I.MOVE{mvOp=I.MOVL, src=tmp, dst=spillLoc}]
75         end                }
      | I.MOVE{mvOp=I.MOVZX, src, dst} => let(* dst must always be a register *)  
          val tmpR = newReg()  
        in  
          {proh=[tmpR],  
           instr=SOME(I.MOVE{mvOp=I.MOVZX, src=src, dst=I.Direct tmpR}),  
           code=[I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]}  
76         end         end
77       | I.MOVE{mvOp, src as I.Direct rs, dst} =>       | I.MOVE{mvOp, src as I.Direct rs, dst} =>
78          if rs=reg then {code=[], proh=[], instr=NONE}            if regmap rs=reg then {code=[], proh=[], newReg=NONE}
79          else done [I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}]            else done(I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}, an)
80       | I.MOVE{mvOp, src, dst=I.Direct _} =>       | I.MOVE{mvOp, src, dst=I.Direct _} =>
81          if immed src then done [I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}]            if Props.eqOpn(src, spillLoc) then {code=[], proh=[], newReg=NONE}
82          else if eqEA(src, spillLoc) then {code=[], proh=[], instr=NONE}            else if immed src then
83          else let               done(I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}, an)
84              val tmpR = newReg()            else
85            in            let val tmpR = newReg()
86              {instr=SOME(I.MOVE{mvOp=mvOp, src=src, dst=I.Direct tmpR}),                val tmp  = I.Direct tmpR
87               proh=[tmpR],            in  {proh=[tmpR],
88               code=[I.MOVE{mvOp=mvOp, src=I.Direct tmpR, dst=spillLoc}]}                 newReg=SOME tmpR,
89                   code=[mark(I.MOVE{mvOp=mvOp, src=src, dst=tmp}, an),
90                         I.MOVE{mvOp=mvOp, src=tmp, dst=spillLoc}]
91                  }
92            end            end
93       | I.LEA{addr, r32} => let        | I.LEA{addr, r32} =>
94           val tmpR = newReg()            let val tmpR = newReg()
95         in {instr=SOME(I.LEA{addr=addr, r32=tmpR}),            in  {proh=[tmpR],
96             proh=[tmpR],                 newReg=SOME tmpR,
97             code=[I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]}                 code=[mark(I.LEA{addr=addr, r32=tmpR}, an),
98                         I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]
99                  }
100         end         end
101       | I.BINARY{binOp, src, dst} =>        | 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 *)
113         if immedOrReg src then         if immedOrReg src then
114           {instr=SOME(I.BINARY{binOp=binOp, src=src, dst=spillLoc}),               {proh=[],
115            proh=[],                code=[(* I.MOVE{mvOp=I.MOVL, src=dst, dst=spillLoc}, XXX *)
116            code=[]}                      mark(I.BINARY{binOp=binOp, src=src, dst=spillLoc}, an)
117         else let                     ],
118             val tmpR = newReg()                newReg=NONE
119           in               }
120             {instr=SOME(I.MOVE{mvOp=I.MOVL, src=src, dst=I.Direct tmpR}),            else
121              proh=[tmpR],            let val tmpR = newReg()
122              code=[I.BINARY{binOp=binOp, src=I.Direct tmpR, dst=spillLoc}]}                val tmp  = I.Direct tmpR
123              in  {proh=[tmpR],
124                   code=[(* I.MOVE{mvOp=I.MOVL, src=dst, dst=spillLoc}, XXX *)
125                         I.MOVE{mvOp=I.MOVL, src=src, dst=tmp},
126                         mark(I.BINARY{binOp=binOp, src=tmp, dst=spillLoc}, an)
127                        ],
128                   newReg=NONE
129                  }
130           end           end
131       | I.MULTDIV _ => error "spill: MULTDIV"       | I.MULTDIV _ => error "spill: MULTDIV"
132       | I.MUL3{src1, src2, dst} => let        | I.MUL3{src1, src2, dst} =>
133           val tmpR = newReg()            let val tmpR = newReg()
134         in            in  {proh=[tmpR], newReg=SOME tmpR,
135           {instr=SOME(I.MUL3{src1=src1, src2=src2, dst=tmpR}),                 code=[mark(I.MUL3{src1=src1, src2=src2, dst=tmpR}, an),
136            proh=[tmpR],                       I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]
137            code=[I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]}                }
138         end         end
139       | I.UNARY{unOp, opnd} => done [I.UNARY{unOp=unOp, opnd=spillLoc}]        | I.UNARY{unOp, opnd} => done(I.UNARY{unOp=unOp, opnd=spillLoc}, an)
140       | I.POP _ => done [I.POP spillLoc]        | I.SET{cond, opnd} => done(I.SET{cond=cond, opnd=spillLoc}, an)
141          | 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"
144       | I.ANNOTATION{i,a} => spillIt i        | I.ANNOTATION{i,a} => spillIt(i, a::an)
145       | _ => error "spill"       | _ => error "spill"
146    in spillIt instr    in  spillIt(instr, [])
147    end    end (* spill *)
148    
149    fun reload(instr, reg, spillLoc) = let    fun reload(instr, regmap, reg, spillLoc) =
150      fun operand(rt, opnd) =    let fun operand(rt, opnd) =
151        (case opnd        (case opnd
152         of I.Direct r => if r=reg then I.Direct rt else opnd         of I.Direct r => if regmap r=reg then I.Direct rt else opnd
153          | I.Displace{base, disp, mem} =>          | I.Displace{base, disp, mem} =>
154             if base=reg then I.Displace{base=rt, disp=disp, mem=mem} else opnd             if regmap base=reg then I.Displace{base=rt, disp=disp, mem=mem}
155               else opnd
156          | I.Indexed{base=NONE, index, scale, disp, mem=mem} =>          | I.Indexed{base=NONE, index, scale, disp, mem=mem} =>
157             if index=reg then             if regmap index=reg then
158               I.Indexed{base=NONE, index=rt, scale=scale, disp=disp, mem=mem}               I.Indexed{base=NONE, index=rt, scale=scale, disp=disp, mem=mem}
159             else opnd             else opnd
160          | I.Indexed{base as SOME b, index, scale, disp, mem=mem} =>          | I.Indexed{base as SOME b, index, scale, disp, mem=mem} =>
161             if b=reg then             if regmap b=reg then
162               operand(rt, I.Indexed{base=SOME rt, index=index,               operand(rt, I.Indexed{base=SOME rt, index=index,
163                                     scale=scale, disp=disp, mem=mem})                                     scale=scale, disp=disp, mem=mem})
164             else if index=reg then             else if regmap index=reg then
165               I.Indexed{base=base, index=rt, scale=scale, disp=disp, mem=mem}               I.Indexed{base=base, index=rt, scale=scale, disp=disp, mem=mem}
166                  else opnd                  else opnd
167          | opnd => opnd          | opnd => opnd
168        (*esac*))        (*esac*))
169    
170      fun uses(I.Direct r) = r = reg      (* XXX *)      fun done(instr, an) = {code=[mark(instr, an)], proh=[], newReg=NONE}
171        | uses(I.Displace{base, disp, mem}) = base=reg  
172        | uses(I.Indexed{base=NONE, index, scale, disp, mem}) = index=reg      (* This version assumes that the value of tmpR is killed *)
173        | uses(I.Indexed{base=SOME b, index, scale, disp, mem})=      fun withTmp(f, an) =
174            b=reg orelse index=reg      let val tmpR = newReg()
175        | uses _ = false      in  {newReg=NONE,
176      fun done c = {code=c, proh=[]}           proh=[tmpR],
177      fun rewrite rt r = if r=reg then rt else r           code=[I.MOVE{mvOp=I.MOVL, src=spillLoc, dst=I.Direct tmpR},
178      fun ldSpillLoc (tmpR) = I.MOVE{mvOp=I.MOVL, src=spillLoc, dst=I.Direct tmpR}                 mark(f tmpR, an)
179      fun withTmp f = let                ]
180        val tmpR = newReg()          }
181      in {code=[ldSpillLoc(tmpR), f tmpR], proh=[tmpR]}      end
182    
183        (* This version assumes that the value of tmpR is available afterwards *)
184        fun withTmp'(f, an) =
185        let val tmpR = newReg()
186            val tmp  = I.Direct tmpR
187        in  {newReg=SOME tmpR,
188             proh=[tmpR],
189             code=[I.MOVE{mvOp=I.MOVL, src=spillLoc, dst=I.Direct tmpR},
190                   mark(f tmpR, an)
191                  ]
192            }
193        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      end
241      fun reloadIt instr =  
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) =
251      case instr      case instr
252      of I.JMP(I.Direct _, labs) => {code=[I.JMP(spillLoc, labs)], proh=[]}      of I.JMP(I.Direct _, labs) => done(I.JMP(spillLoc, labs), an)
253       | I.JMP(opnd, labs) => withTmp(fn tmpR => I.JMP(operand(tmpR, opnd), labs))       | I.JMP(opnd, labs) => withTmp(fn t => I.JMP(operand(t, opnd), labs), an)
254       | I.JCC{opnd=I.Direct _, cond} => done[I.JCC{opnd=spillLoc, cond=cond}]       | I.JCC{opnd=I.Direct _, cond} => done(I.JCC{opnd=spillLoc, cond=cond}, an)
255       | I.JCC{opnd, cond} =>       | I.JCC{opnd, cond} =>
256          withTmp(fn tmpR => I.JCC{opnd=operand(tmpR, opnd), cond=cond})            withTmp(fn t => I.JCC{opnd=operand(t,opnd), cond=cond}, an)
257       | I.CALL(opnd, defs, uses as (r,f,c), mem) =>       | I.CALL(opnd, defs, uses, mem) =>
258          withTmp(fn tmpR =>         let val tmpR = newReg()
259                    I.CALL(operand(tmpR, opnd), defs,         in  {proh=[tmpR],
260                           (map (rewrite tmpR) r, f,c), mem))              newReg=NONE,
261                code=[mark(
262                       I.CALL(operand(tmpR, opnd), defs, C.rmvReg(reg,uses), mem),
263                      an)]
264               }
265           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 tmpR =>I.MOVE{mvOp=mvOp, src=operand(tmpR, src), dst=dst})          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} =>
271          if eqEA(dst, spillLoc) then {code=[], proh=[]}          if Props.eqOpn(dst, spillLoc) then {code=[], proh=[], newReg=NONE}
272          else withTmp          else withTmp
273            (fn tmpR =>            (fn t =>
274               I.MOVE{mvOp=mvOp, src=operand(tmpR, src), dst=operand(tmpR, dst)})               I.MOVE{mvOp=mvOp, src=operand(t, src), dst=operand(t, dst)}, an)
275       | I.MOVE{mvOp, src, dst} =>       | I.MOVE{mvOp, src, dst} =>
276          withTmp          withTmp
277           (fn tmpR =>           (fn t =>
278              I.MOVE{mvOp=mvOp, src=operand(tmpR, src), dst=operand(tmpR, dst)})              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)})          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.CMP{lsrc=operand(tmpR, lsrc), rsrc=operand(tmpR, rsrc)})       | I.CMPW{lsrc, rsrc} => reloadCmp(I.CMPW, lsrc, rsrc, an)
283         | 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 => I.BINARY{binOp=binOp, src=operand(tmpR, src), dst=dst})            (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)
293              )
294       | I.BINARY{binOp, src, dst} =>       | I.BINARY{binOp, src, dst} =>
295          withTmp          withTmp(fn tmpR => I.BINARY{binOp=binOp, src=operand(tmpR, src),
296           (fn tmpR =>                                                   dst=operand(tmpR, dst)}, an)
297              I.BINARY{binOp=binOp, src=operand(tmpR, src), dst=operand(tmpR,dst)})       | 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 => I.MULTDIV{multDivOp=multDivOp, src=operand(tmpR, src)})          withTmp(fn tmpR =>
301                I.MULTDIV{multDivOp=multDivOp, src=operand(tmpR, src)}, an)
302       | I.MUL3{src1, src2, dst} =>       | I.MUL3{src1, src2, dst} =>
303          withTmp(fn tmpR =>          withTmp(fn tmpR =>
304            I.MUL3{src1=operand(tmpR, src1), src2=src2,            I.MUL3{src1=operand(tmpR, src1), src2=src2,
305                   dst=if dst = reg then error "reload:MUL3" else dst})                   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)})          withTmp'(fn tmpR => I.UNARY{unOp=unOp, opnd=operand(tmpR, opnd)}, an)
308       | I.PUSH arg => withTmp(fn tmpR => I.PUSH(operand(tmpR, arg)))       | 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)))       | I.FILD opnd => reloadReal(I.FILD, opnd, an)
315       | I.FLD opnd =>       | I.FLDL opnd => reloadReal(I.FLDL, opnd, an)
316          withTmp (fn tmpR => I.FLD(operand(tmpR, opnd)))       | I.FLDS opnd => reloadReal(I.FLDS, opnd, an)
317       | I.FSTP opnd =>       | I.FSTPL opnd => reloadReal(I.FSTPL, opnd, an)
318          withTmp(fn tmpR => I.FSTP(operand(tmpR, opnd)))       | I.FSTPS opnd => reloadReal(I.FSTPS, opnd, an)
319         | I.FENV{fenvOp, opnd} => reloadReal(fn opnd =>
320                                     I.FENV{fenvOp=fenvOp,opnd=opnd}, opnd, an)
321       | I.FBINARY{binOp, src, dst} =>       | I.FBINARY{binOp, src, dst} =>
322          withTmp(fn tmpR =>          withTmp'(fn tmpR =>
323                    I.FBINARY{binOp=binOp, src=operand(tmpR, src), dst=dst})                   I.FBINARY{binOp=binOp, src=operand(tmpR, src), dst=dst}, an)
324         | I.ANNOTATION{i,a} => reloadIt(i, a::an)
      | I.ANNOTATION{i,a} => reloadIt i  
325       | _ => error "reload"       | _ => error "reload"
326    in reloadIt instr    in reloadIt(instr, [])
327    end (*reload*)    end (*reload*)
328    
329    fun fspill(instr, reg, spillLoc) =    fun fspill(instr, regmap, reg, spillLoc) =
330      (case instr    let fun spillIt(instr, an) =
331        of I.FSTP _ => {proh=[], instr=NONE, code=[I.FSTP spillLoc]}        (case instr of
332         | I.ANNOTATION{i,a} => fspill(i, reg, spillLoc)           I.FSTPL _ => {proh=[], code=[mark(I.FSTPL spillLoc, an)], newReg=NONE}
333           | I.FSTPS _ => {proh=[], code=[mark(I.FSTPS spillLoc, an)], newReg=NONE}
334           | I.CALL(opnd, defs, uses, mem) =>
335             {proh=[],
336              code=[mark(I.CALL(opnd, C.rmvFreg(reg,defs), uses, mem), an)],
337              newReg=NONE}
338           | I.ANNOTATION{i,a} => spillIt(i, a::an)
339         | _ => error "fspill"         | _ => error "fspill"
340      (*esac*))      (*esac*))
341      in  spillIt(instr, [])
342      end (* fspill *)
343    
344    fun freload(instr, reg, spillLoc) =    fun freload(instr, regmap, reg, spillLoc) =
345      (case instr    let fun reloadIt(instr, an) =
346        of I.FLD opnd => {code=[I.FLD spillLoc], proh=[]}        (case instr of
347             I.FLDL opnd => {code=[mark(I.FLDL spillLoc, an)], proh=[], newReg=NONE}
348           | I.FLDS opnd => {code=[mark(I.FLDS spillLoc, an)], proh=[], newReg=NONE}
349         | I.FBINARY{binOp, src=I.FDirect f, dst} =>         | I.FBINARY{binOp, src=I.FDirect f, dst} =>
350             if f = reg then             if regmap f = reg then
351               {code=[I.FBINARY{binOp=binOp, src=spillLoc, dst=dst}],               {code=[mark(I.FBINARY{binOp=binOp, src=spillLoc, dst=dst}, an)],
352                proh=[]}                proh=[],
353                  newReg=NONE}
354             else error "freload:FBINARY"             else error "freload:FBINARY"
355         | I.ANNOTATION{i,a} => freload(i, reg, spillLoc)         | I.CALL(opnd, defs, uses, mem) =>
356             {proh=[],
357              code=[mark(I.CALL(opnd, C.rmvFreg(reg,defs), uses, mem), an)],
358              newReg=NONE}
359           | I.ANNOTATION{i,a} => reloadIt(i, a::an)
360         | _  => error "freload"         | _  => error "freload"
361      (*esac*))      (*esac*))
362      in  reloadIt(instr, [])
363      end (* freload *)
364    
365  end  end

Legend:
Removed from v.411  
changed lines
  Added in v.545

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