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 /MLRISC/trunk/amd64/ra/amd64SpillInstr.sml
ViewVC logotype

Diff of /MLRISC/trunk/amd64/ra/amd64SpillInstr.sml

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

revision 2785, Wed Sep 26 23:45:35 2007 UTC revision 2786, Thu Sep 27 23:40:35 2007 UTC
# Line 44  Line 44 
44        | isMemory(I.LabelEA _) = true        | isMemory(I.LabelEA _) = true
45        | isMemory _ = false        | isMemory _ = false
46    
47    (* We need mvInstr and mvInstr' at the moment for two reasons:      fun mvInstr instr = let
    * 1. Determining the operand size for reloading instructions  
    *    requires looking at the operand being spilled. I will do this  
    *    in the next fix.  For now, just reload a 64-bit value  
    * 2. Operands and their sizes leak out from the spill phase into other  
    *    code.  This means we need to use mvInstr' there to get operand  
    *    sizes right.  
    *)  
     fun mvInstr instr = (64, I.MOVQ)  
   
     fun mvInstr' instr = let  
48          fun mvOp 8 = I.MOVB          fun mvOp 8 = I.MOVB
49            | mvOp 16 = I.MOVW            | mvOp 16 = I.MOVW
50            | mvOp 32 = I.MOVL            | mvOp 32 = I.MOVL
# Line 98  Line 88 
88        | reloadFromEA CB.FP _ = error "reloadFromEA: FP"        | reloadFromEA CB.FP _ = error "reloadFromEA: FP"
89        | reloadFromEA _ _ = error "reloadFromEA"        | reloadFromEA _ _ = error "reloadFromEA"
90    
91        (* spill a general purpose register r at instruction i to spillLoc *)
92      fun spillR (i, r, spillLoc) = let      fun spillR (i, r, spillLoc) = let
93          fun spill (instr, an) = let          fun spill (instr, an) = let
94              fun done (instr, an) = {code=[mark (instr, an)], proh=[], newReg=NONE}              fun done (instr, an) = {code=[mark (instr, an)], proh=[], newReg=NONE}
95              val (sz, sMvOp) = mvInstr' instr              val (defaultSz, defaultMov) = (64, I.MOVQ)
96                (* freshTmp generates a fresh temporary register, an operand with the
97                 * instruction's operand size, and an operand with a 64-bit operand size. *)
98                fun freshTmp () = let
99                    val tmpR = newReg ()
100                    val sz = Props.szOfInstr instr
101                    val tmpOpnd = I.Direct (sz, tmpR)
102                    val tmpOpnd64 = I.Direct (64, tmpR)
103                    in
104                       (tmpR, tmpOpnd, tmpOpnd64)
105                    end
106              in              in
107                (case instr                (case instr
108                  of I.CALL {opnd=addr, defs, uses, return, cutsTo, mem, pops} =>                  of I.CALL {opnd=addr, defs, uses, return, cutsTo, mem, pops} =>
109                     done (I.CALL {opnd=addr, defs=C.rmvReg (r, defs),                     done (I.CALL {opnd=addr, defs=C.rmvReg (r, defs),
110                                  return=return, uses=uses,                                  return=return, uses=uses,
111                                  cutsTo=cutsTo, mem=mem, pops=pops}, an)                                  cutsTo=cutsTo, mem=mem, pops=pops}, an)
112                     (* With sign or zero extended spills we use different operand sizes
113                      * for copying to the tmp operand and for copying from the tmp operand. *)
114                   | I.MOVE {mvOp as (I.MOVZBQ|I.MOVSBQ|I.MOVZWQ|I.MOVSWQ|                   | I.MOVE {mvOp as (I.MOVZBQ|I.MOVSBQ|I.MOVZWQ|I.MOVSWQ|
115                                      I.MOVSLQ|I.MOVZBL|I.MOVSBL|I.MOVZWL|                                      I.MOVSLQ|I.MOVZBL|I.MOVSBL|I.MOVZWL|
116                                      I.MOVSWL), src, dst} => let                                      I.MOVSWL), src, dst} => let
117                     val tmpR = newReg ()                     val (tmpR, tmpOpnd, tmpOpnd64) = freshTmp ()
                    val tmp = I.Direct (sz, tmpR)  
118                     in                     in
119                       {proh=[tmpR], newReg=SOME tmpR,                       {proh=[tmpR], newReg=SOME tmpR,
120                        code=[mark (I.MOVE {mvOp=mvOp, src=src, dst=tmp}, an),                        code=[mark (I.MOVE {mvOp=mvOp, src=src, dst=tmpOpnd}, an),
121                              I.move {mvOp=sMvOp, src=tmp, dst=spillLoc}]}                              I.move {mvOp=defaultMov, src=tmpOpnd64, dst=spillLoc}]}
122                     end                     end
123                     (* spill is unnecessary *)
124                   | I.MOVE {mvOp, src as I.Direct (_, rs), dst} =>                   | I.MOVE {mvOp, src as I.Direct (_, rs), dst} =>
125                     if CB.sameColor (rs, r) then {code=[], proh=[], newReg=NONE}                     if CB.sameColor (rs, r) then {code=[], proh=[], newReg=NONE}
126                     else done (I.MOVE {mvOp=mvOp, src=src, dst=spillLoc}, an)                     else done (I.MOVE {mvOp=mvOp, src=src, dst=spillLoc}, an)
# Line 127  Line 130 
130                       else if immed src then                       else if immed src then
131                            done(I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}, an)                            done(I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}, an)
132                        else let                        else let
133                          val tmpR = newReg ()                          val (tmpR, tmpOpnd, tmpOpnd64) = freshTmp ()
                         val tmp  = I.Direct (sz, tmpR)  
134                          in                          in
135                            {proh=[tmpR],                            {proh=[tmpR],
136                             newReg=SOME tmpR,                             newReg=SOME tmpR,
137                             code=[mark(I.MOVE {mvOp=mvOp, src=src, dst=tmp}, an),                             code=[mark(I.MOVE {mvOp=mvOp, src=src, dst=tmpOpnd}, an),
138                                   I.move {mvOp=sMvOp, src=tmp, dst=spillLoc}]}                                   I.move {mvOp=defaultMov, src=tmpOpnd64, dst=spillLoc}]}
139                          end                          end
140                   | I.LEAL {addr, r32} => let                   | I.LEAL {addr, r32} => let
141                     val tmpR = newReg()                     val tmpR = newReg()
# Line 151  Line 153 
153                                   I.move{mvOp=I.MOVQ, src=I.Direct (64,tmpR),                                   I.move{mvOp=I.MOVQ, src=I.Direct (64,tmpR),
154                                          dst=spillLoc}]}                                          dst=spillLoc}]}
155                        end                        end
156                     (* handle xorl and xorq with the special case when both operands are the
157                      * same register *)
158                   | I.BINARY {binOp=I.XORL, src as I.Direct (_,rs),                   | I.BINARY {binOp=I.XORL, src as I.Direct (_,rs),
159                               dst=I.Direct (_,rd)} =>                               dst=I.Direct (_,rd)} =>
160                     if CB.sameColor (rs,rd)                     if CB.sameColor (rs,rd)
# Line 179  Line 183 
183                     in                     in
184                       if multBinOp binOp                       if multBinOp binOp
185                         then let (* destination must remain a register *)                         then let (* destination must remain a register *)
186                           val tmpR = newReg()                           val (tmpR, tmpOpnd, tmpOpnd64) = freshTmp ()
                          val tmp = I.Direct (sz,tmpR)  
187                           in                           in
188                             {proh=[tmpR], newReg=SOME tmpR,                             {proh=[tmpR], newReg=SOME tmpR,
189                              code=[I.move{mvOp=sMvOp, src=spillLoc, dst=tmp},                              code=[I.move{mvOp=defaultMov, src=spillLoc, dst=tmpOpnd64},
190                                    I.binary{binOp=binOp, src=src, dst=tmp},                                    I.binary{binOp=binOp, src=src, dst=tmpOpnd},
191                                    I.move{mvOp=sMvOp, src=tmp, dst=spillLoc}]}                                    I.move{mvOp=defaultMov, src=tmpOpnd64, dst=spillLoc}]}
192                           end                           end
193                          else if immedOrReg src                          else if immedOrReg src
194                                then (* can replace the destination directly *)                                then (* can replace the destination directly *)
# Line 194  Line 197 
197                            else let (* a memory src and non multBinOp                            else let (* a memory src and non multBinOp
198                                     * --- cannot have two memory operands                                     * --- cannot have two memory operands
199                                     *)                                     *)
200                                  val tmpR = newReg()                                  val (tmpR, tmpOpnd, tmpOpnd64) = freshTmp ()
                                 val tmp = I.Direct (sz,tmpR)  
201                                  in                                  in
202                                    { proh=[tmpR], newReg=NONE,                                    { proh=[tmpR], newReg=NONE,
203                                      code=[I.move{mvOp=sMvOp, src=src, dst=tmp},                                      code=[I.move{mvOp=defaultMov, src=src, dst=tmpOpnd64},
204                                            I.binary{binOp=binOp, src=tmp,                                            I.binary{binOp=binOp, src=tmpOpnd,
205                                                     dst=spillLoc}]}                                                     dst=spillLoc}]}
206                                  end                                  end
207                          end                          end
# Line 210  Line 212 
212                       then done (I.SHIFT {shiftOp=shiftOp, src=src, dst=spillLoc,                       then done (I.SHIFT {shiftOp=shiftOp, src=src, dst=spillLoc,
213                               count=count}, an)                               count=count}, an)
214                       else let                       else let
215                         val tmpR = newReg ()                         val (tmpR, tmpOpnd, tmpOpnd64) = freshTmp ()
                        val tmp = I.Direct (sz, tmpR)  
216                         in                         in
217                           {proh=[tmpR], newReg=NONE,                           {proh=[tmpR], newReg=NONE,
218                            code=[I.move {mvOp=sMvOp, src=src, dst=tmp},                            code=[I.move {mvOp=defaultMov, src=src, dst=tmpOpnd64},
219                                  I.shift {shiftOp=shiftOp, src=tmp, dst=spillLoc,                                  I.shift {shiftOp=shiftOp, src=tmpOpnd, dst=spillLoc,
220                                     count=count}]}                                     count=count}]}
221                         end                         end
222                   | I.CMOV {cond, src, dst} =>                   | I.CMOV {cond, src, dst} =>
# Line 226  Line 227 
227                              code=[mark(I.CMOV{cond=cond,src=src,dst=r},an)]                              code=[mark(I.CMOV{cond=cond,src=src,dst=r},an)]
228                             }                             }
229                         | _ => let                         | _ => let
230                           val tmpR = newReg()                           val (tmpR, _, tmpOpnd64) = freshTmp ()
                          val tmp  = I.Direct (64, tmpR)  
231                           in                           in
232                             {proh=[tmpR], newReg=SOME tmpR,                             {proh=[tmpR], newReg=SOME tmpR,
233                              code=[I.move{mvOp=I.MOVQ, src=spillLoc, dst=tmp},                              code=[I.move{mvOp=I.MOVQ, src=spillLoc, dst=tmpOpnd64},
234                                    mark(I.CMOV{cond=cond,src=src,dst=tmpR},an),                                    mark(I.CMOV{cond=cond,src=src,dst=tmpR},an),
235                                    I.move{mvOp=I.MOVQ, src=tmp, dst=spillLoc}]}                                    I.move{mvOp=I.MOVQ, src=tmpOpnd64, dst=spillLoc}]}
236                             end                             end
237                      (* end case *))                      (* end case *))
238                   | I.CMPXCHG{lock,sz=isz,src,dst} =>                   | I.CMPXCHG{lock,sz=isz,src,dst} =>
# Line 241  Line 241 
241                             code=[mark(I.CMPXCHG{lock=lock,sz=isz,src=src,                             code=[mark(I.CMPXCHG{lock=lock,sz=isz,src=src,
242                                  dst=spillLoc},an)]}                                  dst=spillLoc},an)]}
243                        else let                        else let
244                          val tmpR = newReg()                          val (tmpR, tmpOpnd, tmpOpnd64) = freshTmp ()
                         val tmp  = I.Direct (sz, tmpR)  
245                          in                          in
246                            {proh=[], newReg=NONE,                            {proh=[], newReg=NONE,
247                            code=[I.move{mvOp=I.MOVQ, src=src, dst=tmp},                            code=[I.move{mvOp=I.MOVQ, src=src, dst=tmpOpnd64},
248                                  mark(I.CMPXCHG{lock=lock,sz=isz,src=tmp,                                  mark(I.CMPXCHG{lock=lock,sz=isz,src=tmpOpnd,
249                                       dst=spillLoc},an)]}                                       dst=spillLoc},an)]}
250                          end                          end
251                   | I.MULTDIV _ => error "spill: MULTDIV"                   | I.MULTDIV _ => error "spill: MULTDIV"
# Line 349  Line 348 
348        | spill CB.FP = spillF        | spill CB.FP = spillF
349        | spill _ = error "spill"        | spill _ = error "spill"
350    
351        (* reload a general purpose register r at instruction i from spillLoc*)
352      fun reloadR (i, r, spillLoc) = let      fun reloadR (i, r, spillLoc) = let
353          fun reload (instr, an) = let          fun reload (instr, an) = let
             val (sz, rMvOp) = mvInstr instr  
354              fun done (instr, an) = {code=[mark (instr, an)], proh=[], newReg=NONE}              fun done (instr, an) = {code=[mark (instr, an)], proh=[], newReg=NONE}
355              fun replace (opnd as I.Direct (_, r')) = if CB.sameColor (r, r')              fun replace (opnd as I.Direct (_, r')) = if CB.sameColor (r, r')
356                  then spillLoc                  then spillLoc
# Line 389  Line 388 
388                   | _ => let                   | _ => let
389                     val tmpR = newReg ()                     val tmpR = newReg ()
390                     in                     in
391                       {code=[I.move {mvOp=rMvOp, src=spillLoc,                       {code=[I.move {mvOp=I.MOVQ, src=spillLoc,
392                                      dst=I.Direct (sz, tmpR)},                                      dst=I.Direct (64, tmpR)},
393                              mark (f tmpR, an)],                              mark (f tmpR, an)],
394                        proh=[tmpR], newReg=SOME tmpR}                        proh=[tmpR], newReg=SOME tmpR}
395                     end                     end

Legend:
Removed from v.2785  
changed lines
  Added in v.2786

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