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/branches/SMLNJ/src/compiler/CodeGen/ppc/ppcCG.sml
ViewVC logotype

Diff of /sml/branches/SMLNJ/src/compiler/CodeGen/ppc/ppcCG.sml

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

revision 247, Sat Apr 17 18:47:13 1999 UTC revision 469, Wed Nov 10 22:42:52 1999 UTC
# Line 1  Line 1 
1  functor PPCCG  (*
2    (structure Emitter : EMITTER_NEW   * PPC specific backend
3       where I = PPCInstr and P = PPCPseudoOps) : MACHINE_GEN =   *)
4  struct  structure PPCCG =
5    structure I = PPCInstr    MachineGen
6    structure C = PPCCells    ( structure MachSpec   = PPCSpec
7    structure R = PPCCpsRegs      structure PseudoOps  = PPCPseudoOps
8    structure B = PPCMLTree.BNames      structure CpsRegs    = PPCCpsRegs
9    structure F = PPCFlowGraph      structure InsnProps  = PPCProps(PPCInstr)
10    structure Asm      = PPCAsmEmitter    structure Asm      = PPCAsmEmitter
   structure MLTree   = PPCMLTree  
   structure MachSpec = PPCSpec  
   structure Ctrl = Control.MLRISC  
   
   fun error msg = ErrorMsg.impossible ("PPCCG." ^ msg)  
   
   val stack = PPCInstr.Region.stack  
   structure PPCRewrite = PPCRewrite(PPCInstr)  
11    
12    (* properties of instruction set *)      structure MLTreeComp=
13    structure P =         PPC(structure PPCInstr = PPCInstr
14      PPCProps(structure PPCInstr= I             structure PPCMLTree = PPCMLTree
15                   structure Shuffle=PPCShuffle)             structure PseudoInstrs=
16                   PPCPseudoInstr(structure Instr=PPCInstr)
17               val bit64mode=false
18               val multCost=ref 6 (* an estimate *)
19             )
20    
21    (* Label backpatching and basic block scheduling *)      structure PPCJumps =
   structure BBSched =  
     BBSched2(structure Flowgraph = F  
              structure Jumps =  
22                 PPCJumps(structure Instr=PPCInstr                 PPCJumps(structure Instr=PPCInstr
23                              structure Shuffle=PPCShuffle)                              structure Shuffle=PPCShuffle)
              structure Emitter = Emitter)  
   
   (* flow graph pretty printing routine *)  
   structure PrintFlowGraph =  
      PrintFlowGraphFn (structure FlowGraph = F  
                        structure Emitter   = Asm)  
   
   val intSpillCnt = Ctrl.getInt "ra-int-spills"  
   val floatSpillCnt = Ctrl.getInt "ra-float-spills"  
   val intReloadCnt = Ctrl.getInt "ra-int-reloads"  
   val floatReloadCnt = Ctrl.getInt "ra-float-reloads"  
   
   (* register allocation *)  
   structure RegAllocation :  
     sig  
       val ra : F.cluster -> F.cluster  
       val cp : F.cluster -> F.cluster  
     end =  
   struct  
   
    (* spill area management *)  
     val initialSpillOffset = 144  
     val spillOffset = ref initialSpillOffset  
     fun newOffset n =  
         if n > 4096  
         then error "newOffset - spill area is too small"  
         else spillOffset := n  
     exception RegSpills and FregSpills  
   
     val regSpills : int Intmap.intmap ref = ref(Intmap.new(0, RegSpills))  
     val fregSpills : int Intmap.intmap ref = ref(Intmap.new(0, FregSpills))  
   
     (* get spill location for general registers *)  
     fun getRegLoc reg = Intmap.map (!regSpills) reg  
       handle RegSpills => let  
           val offset = !spillOffset  
         in  
           newOffset(offset+4);  
           Intmap.add (!regSpills) (reg, offset);  
           offset  
         end  
   
     (* get spill location for floating registers *)  
     fun getFregLoc freg = Intmap.map (!fregSpills) freg  
       handle FregSpills => let  
           val offset = !spillOffset  
           val fromInt = Word.fromInt  
           val aligned = Word.toIntX(Word.andb(fromInt offset+0w7, fromInt ~8))  
         in  
           newOffset(aligned+8);  
           Intmap.add (!fregSpills) (freg, aligned);  
           aligned  
         end  
   
     fun spill {regmap,instr,reg,id:B.name} = let  
       val offset = I.ImmedOp (getRegLoc(reg))  
       fun spillInstr(src) =  
         [I.ST{sz=I.Word, rs=src, ra=C.stackptrR, d=offset, mem=stack}]  
     in  
       intSpillCnt := !intSpillCnt + 1;  
       case instr  
        of I.COPY{dst as [rd], src as [rs], tmp, impl} =>  
           if rd=reg then  
             {code=spillInstr(rs),  instr=NONE,   proh=[]:int list}  
           else (case tmp  
              of SOME(I.Direct r) => let  
                   val disp = I.ImmedOp(getRegLoc(r))  
                   val loc = I.Displace{base=C.stackptrR, disp=disp}  
                   val instr=I.COPY{dst=dst, src=src, tmp=SOME(loc), impl=impl}  
                 in {code=[], instr=SOME instr, proh=[]}  
                 end  
               | _ => error "spill: COPY"  
             (*esac*))  
        | _ => let  
             val newR = C.newReg()  
             val instr' = PPCRewrite.rewriteDef(regmap, instr, reg, newR)  
           in {code=spillInstr(newR),  instr=SOME instr',  proh=[newR]}  
           end  
     end  
   
     fun fspill {regmap,instr,reg,id:B.name} = let  
       val offset = I.ImmedOp (getFregLoc(reg))  
       fun spillInstr(src) =  
         [I.ST{sz=I.Double, rs=src, ra=C.stackptrR, d=offset, mem=stack}]  
     in  
       floatSpillCnt := !floatSpillCnt + 1;  
       case instr  
       of I.FCOPY{dst as [fd], src as [fs], tmp, impl} =>         (* reg = fd *)  
           if reg=fd then  
             {code=spillInstr(fs),   instr=NONE,   proh=[]}  
           else (case tmp  
              of SOME(I.FDirect r) => let  
                   val disp=I.ImmedOp(getFregLoc(r))  
                   val loc = I.Displace{base=C.stackptrR, disp=disp}  
                   val instr=I.FCOPY{dst=dst, src=src, tmp=SOME(loc), impl=impl}  
                 in {code=[], instr=SOME instr, proh=[]}  
                 end  
               | _ => error "spill: COPY"  
             (*esac*))  
        | _ => let  
             val newR = C.newFreg()  
             val instr' = PPCRewrite.frewriteDef(regmap, instr, reg, newR)  
           in {code=spillInstr(newR),  instr=SOME instr',  proh=[newR]}  
           end  
     end  
24    
25      fun reload{regmap,instr,reg,id:B.name} = let      structure BackPatch =
26        val offset = I.ImmedOp (getRegLoc(reg))         BBSched2(structure Flowgraph = PPCFlowGraph
27        fun reloadInstr(dst, rest) =                  structure Jumps = PPCJumps
28          I.L{sz=I.Word, rt=dst, ra=C.stackptrR, d=offset, mem=stack}::rest                  structure Emitter = PPCMCEmitter)
29      in  
30        intReloadCnt := !intReloadCnt + 1;      structure RA =
31        case instr         RegAlloc2
32        of I.COPY{dst=[rd], src=[rs], ...} =>     (* reg = rs *)           (structure I         = PPCInstr
33             {code=reloadInstr(rd, []),   proh=[]:int list}            structure MachSpec  = PPCSpec
34         | _ => let            structure Flowgraph = PPCFlowGraph
35               val newR = C.newReg()            structure CpsRegs   = PPCCpsRegs
36               val instr' = PPCRewrite.rewriteUse(regmap, instr, reg, newR)            structure InsnProps = InsnProps
37             in {code=reloadInstr(newR, [instr']), proh=[newR]}            structure Rewrite   = PPCRewrite(PPCInstr)
38             end            structure Asm       = PPCAsmEmitter
     end  
   
     fun freload {regmap, instr, reg, id:B.name} = let  
       val offset = I.ImmedOp (getFregLoc(reg))  
       fun reloadInstr(dst, rest) =  
         I.L{sz=I.Double, rt=dst, ra=C.stackptrR, d=offset, mem=stack}::rest  
     in  
       floatReloadCnt := !floatReloadCnt + 1;  
       case instr  
       of I.FCOPY{dst=[fd], src=[fs], ...} =>    (* reg = fs *)  
            {code=reloadInstr(fd, []), proh=[]}  
        | _ => let  
              val newR = C.newFreg()  
              val instr' = PPCRewrite.frewriteUse(regmap, instr, reg, newR)  
            in {code=reloadInstr(newR, [instr']), proh=[newR]}  
            end  
     end  
   
     fun spillInit () =  
       (spillOffset := initialSpillOffset;  
        regSpills := Intmap.new(8, RegSpills);  
        fregSpills := Intmap.new(8, FregSpills))  
   
     structure GR = GetReg(val nRegs=32 val available=R.availR)  
     structure FR = GetReg(val nRegs=32 val available=R.availF)  
39    
40      structure PPCRa =            val sp = I.C.stackptrR
41         PPCRegAlloc(structure P = P            val stack = I.Region.stack
                        structure I = PPCInstr  
                        structure F = F  
                        structure Asm = Asm)  
42    
43      (* register allocation for general purpose registers *)            fun pure _ = false
     structure IntRa =  
       PPCRa.IntRa  
         (structure RaUser = struct  
            structure I = PPCInstr  
            structure B = B  
44    
45             val getreg = GR.getreg            (* make copy *)
46             val spill = spill            fun copyR((rds as [_], rss as [_]), _) =
47             val reload = reload                I.COPY{dst=rds, src=rss, impl=ref NONE, tmp=NONE}
48             val nFreeRegs = length R.availR              | copyR((rds, rss), I.COPY{tmp, ...}) =
            val dedicated = R.dedicatedR  
            fun copyInstr((rds, rss), I.COPY{tmp, ...}) =  
49               I.COPY{dst=rds, src=rss, impl=ref NONE, tmp=tmp}               I.COPY{dst=rds, src=rss, impl=ref NONE, tmp=tmp}
50           end)            fun copyF((fds as [_], fss as [_]), _) =
51                  I.FCOPY{dst=fds, src=fss, impl=ref NONE, tmp=NONE}
52      (* register allocation for floating point registers *)              | copyF((fds, fss), I.FCOPY{tmp, ...}) =
     structure FloatRa =  
       PPCRa.FloatRa  
         (structure RaUser = struct  
            structure I = PPCInstr  
            structure B = B  
   
            val getreg = FR.getreg  
            val spill = fspill  
            val reload = freload  
            val nFreeRegs = length R.availF  
            val dedicated = R.dedicatedF  
            fun copyInstr((fds, fss), I.FCOPY{tmp, ...}) =  
53               I.FCOPY{dst=fds, src=fss, impl=ref NONE, tmp=tmp}               I.FCOPY{dst=fds, src=fss, impl=ref NONE, tmp=tmp}
          end)  
   
     val iRegAlloc = IntRa.ra IntRa.REGISTER_ALLOCATION []  
     val fRegAlloc = FloatRa.ra FloatRa.REGISTER_ALLOCATION []  
     val iCopyProp = IntRa.ra IntRa.COPY_PROPAGATION []  
     val fCopyProp = FloatRa.ra FloatRa.COPY_PROPAGATION []  
   
     fun ra cluster = let  
       val pg = PrintFlowGraph.printCluster TextIO.stdOut  
       fun intRa cluster = (GR.reset(); iRegAlloc cluster)  
       fun floatRa cluster = (FR.reset(); fRegAlloc cluster)  
     in spillInit(); (floatRa o intRa) cluster  
     end  
     val cp = fCopyProp o iCopyProp  
   end (* RegAllocation *)  
   
   val optimizerHook : (F.cluster->F.cluster) option ref = ref NONE  
   
  (* primitives for generation of DEC alpha instruction flowgraphs *)  
   structure FlowGraphGen =  
      FlowGraphGen(structure Flowgraph = F  
                   structure InsnProps = P  
                   structure MLTree = MLTree  
                   val optimize = optimizerHook  
                   val output = BBSched.bbsched o RegAllocation.ra)  
   
   (* compilation of CPS to MLRISC *)  
   structure MLTreeGen =  
      MLRiscGen(structure MachineSpec=PPCSpec  
                structure MLTreeComp=  
                   PPC(structure Flowgen=FlowGraphGen  
                       structure PPCInstr=PPCInstr  
                       structure PPCMLTree=PPCMLTree  
                       structure PseudoInstrs=  
                         PPCPseudoInstr(structure Instr=PPCInstr)  
                       val rs6000flag=false)  
                structure Cells=PPCCells  
                structure C=PPCCpsRegs  
                structure PseudoOp=PPCPseudoOps)  
   
   val copyProp = RegAllocation.cp  
   val codegen = MLTreeGen.codegen  
   val finish = BBSched.finish  
 end  
54    
55              (* spill copy temp *)
56              fun spillCopyTmp(I.COPY{dst,src,tmp,impl},offset) =
57                  I.COPY{dst=dst, src=src, impl=impl,
58                         tmp=SOME(I.Displace{base=sp, disp=I.ImmedOp offset})}
59              fun spillFcopyTmp(I.FCOPY{dst,src,tmp,impl},offset) =
60                  I.FCOPY{dst=dst, src=src, impl=impl,
61                         tmp=SOME(I.Displace{base=sp, disp=I.ImmedOp offset})}
62    
63              (* spill register *)
64              fun spillInstrR(rs,offset) =
65                  [I.ST{st=I.STW, ra=sp, d=I.ImmedOp offset, rs=rs, mem=stack}]
66              fun spillInstrF(fs,offset) =
67                  [I.STF{st=I.STFD, ra=sp, d=I.ImmedOp offset, fs=fs, mem=stack}]
68    
69              (* reload register *)
70              fun reloadInstrR(rt,offset,rest) =
71                  I.L{ld=I.LWZ, ra=sp, d=I.ImmedOp offset, rt=rt, mem=stack}::rest
72              fun reloadInstrF(ft,offset,rest) =
73                  I.LF{ld=I.LFD, ra=sp, d=I.ImmedOp offset, ft=ft, mem=stack}::rest
74             )
75      )

Legend:
Removed from v.247  
changed lines
  Added in v.469

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