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/ppc/mltree/ppc.sml
ViewVC logotype

Diff of /sml/trunk/src/MLRISC/ppc/mltree/ppc.sml

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

revision 744, Fri Dec 8 04:11:42 2000 UTC revision 1003, Fri Dec 7 02:45:32 2001 UTC
# Line 7  Line 7 
7    
8  functor PPC  functor PPC
9    (structure PPCInstr : PPCINSTR    (structure PPCInstr : PPCINSTR
    structure PPCMLTree : MLTREE  
    structure ExtensionComp : MLTREE_EXTENSION_COMP  
       where I = PPCInstr and T = PPCMLTree  
10     structure PseudoInstrs : PPC_PSEUDO_INSTR     structure PseudoInstrs : PPC_PSEUDO_INSTR
11        sharing PPCMLTree.Region = PPCInstr.Region                          where I = PPCInstr
12        sharing PPCMLTree.LabelExp = PPCInstr.LabelExp     structure ExtensionComp : MLTREE_EXTENSION_COMP
13        sharing PseudoInstrs.I = PPCInstr                          where I = PPCInstr and T = PPCInstr.T
14    
15     (*     (*
16      * Support 64 bit mode?      * Support 64 bit mode?
# Line 25  Line 22 
22      * Cost of multiplication in cycles      * Cost of multiplication in cycles
23      *)      *)
24     val multCost : int ref     val multCost : int ref
25    ) : MLTREECOMP =    ) =
26  struct  struct
27    structure I   = PPCInstr    structure I   = PPCInstr
28    structure T   = PPCMLTree    structure T   = I.T
29    structure S   = T.Stream    structure TS  = ExtensionComp.TS
30    structure C   = PPCInstr.C    structure C   = PPCInstr.C
31    structure LE  = I.LabelExp    structure CB  = CellsBasis
32    structure W32 = Word32    structure W32 = Word32
33    structure A   = MLRiscAnnotations    structure A   = MLRiscAnnotations
34      structure CFG = ExtensionComp.CFG
35    
36    fun error msg = MLRiscErrorMsg.error("PPC",msg)    fun error msg = MLRiscErrorMsg.error("PPC",msg)
37    
38    type instrStream = (I.instruction,C.cellset) T.stream    type instrStream = (I.instruction, CB.CellSet.cellset, CFG.cfg) TS.stream
39    type mltreeStream = (T.stm,T.mlrisc list) T.stream    type mltreeStream = (T.stm, T.mlrisc list, CFG.cfg) TS.stream
40    
41    
42    val (intTy,naturalWidths) = if bit64mode then (64,[32,64]) else (32,[32])    val (intTy,naturalWidths) = if bit64mode then (64,[32,64]) else (32,[32])
43    structure Gen = MLTreeGen    structure Gen = MLTreeGen
# Line 54  Line 53 
53     *)     *)
54    fun MTLR r = I.MTSPR{rs=r, spr=C.lr}    fun MTLR r = I.MTSPR{rs=r, spr=C.lr}
55    fun MFLR r = I.MFSPR{rt=r, spr=C.lr}    fun MFLR r = I.MFSPR{rt=r, spr=C.lr}
56    val CR0 = C.Reg C.CC 0    val CR0 = C.Reg CB.CC 0
57    val RET = I.BCLR{bo=I.ALWAYS, bf=CR0, bit=I.LT, LK=false, labels=[]}    val RET = I.BCLR{bo=I.ALWAYS, bf=CR0, bit=I.LT, LK=false, labels=[]}
58    fun SLLI32{r,i,d} =    fun SLLI32{r,i,d} =
59        I.ROTATEI{oper=I.RLWINM,ra=d,rs=r,sh=I.ImmedOp i,mb=0,me=SOME(31-i)}        I.ROTATEI{oper=I.RLWINM,ra=d,rs=r,sh=I.ImmedOp i,mb=0,me=SOME(31-i)}
# Line 62  Line 61 
61        I.ROTATEI{oper=I.RLWINM,ra=d,rs=r,sh=I.ImmedOp(32-i),mb=i,me=SOME(31)}        I.ROTATEI{oper=I.RLWINM,ra=d,rs=r,sh=I.ImmedOp(32-i),mb=i,me=SOME(31)}
62    
63    (*    (*
   val _ = if C.lr = 80 then () else error "LR must be encoded as 80!"  
    *)  
   
   (*  
64     * Integer multiplication     * Integer multiplication
65     *)     *)
66    functor Multiply32 = MLTreeMult    functor Multiply32 = MLTreeMult
67      (structure I = I      (structure I = I
68       structure T = T       structure T = T
69         structure CB = CellsBasis
70       val intTy = 32       val intTy = 32
71       type arg  = {r1:C.cell,r2:C.cell,d:C.cell}       type arg  = {r1:CB.cell,r2:CB.cell,d:CB.cell}
72       type argi = {r:C.cell,i:int,d:C.cell}       type argi = {r:CB.cell,i:int,d:CB.cell}
73    
74       fun mov{r,d} = I.COPY{dst=[d],src=[r],tmp=NONE,impl=ref NONE}       fun mov{r,d} = I.copy{dst=[d],src=[r],tmp=NONE,impl=ref NONE}
75       fun add{r1,r2,d}= I.ARITH{oper=I.ADD,ra=r1,rb=r2,rt=d,Rc=false,OE=false}       fun add{r1,r2,d}= I.arith{oper=I.ADD,ra=r1,rb=r2,rt=d,Rc=false,OE=false}
76       fun slli{r,i,d} = [SLLI32{r=r,i=i,d=d}]       fun slli{r,i,d} = [I.INSTR(SLLI32{r=r,i=i,d=d})]
77       fun srli{r,i,d} = [SRLI32{r=r,i=i,d=d}]       fun srli{r,i,d} = [I.INSTR(SRLI32{r=r,i=i,d=d})]
78       fun srai{r,i,d} = [I.ARITHI{oper=I.SRAWI,rt=d,ra=r,im=I.ImmedOp i}]       fun srai{r,i,d} = [I.arithi{oper=I.SRAWI,rt=d,ra=r,im=I.ImmedOp i}]
79      )      )
80    
81    structure Mulu32 = Multiply32    structure Mulu32 = Multiply32
82      (val trapping = false      (val trapping = false
83       val multCost = multCost       val multCost = multCost
84       fun addv{r1,r2,d}=[I.ARITH{oper=I.ADD,ra=r1,rb=r2,rt=d,Rc=false,OE=false}]       fun addv{r1,r2,d}=[I.arith{oper=I.ADD,ra=r1,rb=r2,rt=d,Rc=false,OE=false}]
85       fun subv{r1,r2,d}=[I.ARITH{oper=I.SUBF,ra=r2,rb=r1,rt=d,Rc=false,OE=false}]       fun subv{r1,r2,d}=[I.arith{oper=I.SUBF,ra=r2,rb=r1,rt=d,Rc=false,OE=false}]
86       val sh1addv = NONE       val sh1addv = NONE
87       val sh2addv = NONE       val sh2addv = NONE
88       val sh3addv = NONE       val sh3addv = NONE
# Line 105  Line 101 
101      (val signed = true)      (val signed = true)
102    
103    fun selectInstructions    fun selectInstructions
104        (S.STREAM{emit,comment,        (TS.S.STREAM{emit=emitInstruction,comment,getAnnotations,
105                  defineLabel,entryLabel,pseudoOp,annotation,                  defineLabel,entryLabel,pseudoOp,annotation,
106                  beginCluster,endCluster,exitBlock,...}) =                  beginCluster,endCluster,exitBlock,...}) =
107    let (* mark an instruction with annotations *)    let
108          val emit = emitInstruction o I.INSTR
109    
110          (* mark an instruction with annotations *)
111        fun mark'(instr,[]) = instr        fun mark'(instr,[]) = instr
112          | mark'(instr,a::an) = mark'(I.ANNOTATION{i=instr,a=a},an)          | mark'(instr,a::an) = mark'(I.ANNOTATION{i=instr,a=a},an)
113        fun mark(instr,an) = emit(mark'(instr,an))        fun mark(instr,an) = emitInstruction(mark'(I.INSTR instr,an))
114    
115        (* Label where trap is generated.        (* Label where trap is generated.
116         * For overflow trapping instructions, we generate a branch         * For overflow trapping instructions, we generate a branch
# Line 122  Line 121 
121    
122        val newReg = C.newReg        val newReg = C.newReg
123        val newFreg = C.newFreg        val newFreg = C.newFreg
124        val newCCreg = C.newCell C.CC        val newCCreg = C.newCell CB.CC
125    
126    
127        fun signed16 i = ~32768 <= i andalso i < 32768        val int_0       = T.I.int_0
128        fun signed12 i = ~2048 <= i andalso i < 2048        val int_m0x8000 = T.I.fromInt(32, ~32768)
129        fun unsigned16 i = 0 <= i andalso i < 65536        val int_0x8000  = T.I.fromInt(32,  32768)
130        fun unsigned5  i = 0 <= i andalso i < 32        val int_m0x800  = T.I.fromInt(32, ~2048)
131        fun unsigned6  i = 0 <= i andalso i < 64        val int_0x800   = T.I.fromInt(32,  2048)
132          fun LT (x,y)    = T.I.LT(32, x, y)
133          fun LE (x,y)    = T.I.LE(32, x, y)
134          fun toInt mi = T.I.toInt(32, mi)
135          fun LI i = T.I.fromInt(32, i)
136    
137          fun signed16 mi   = LE(int_m0x8000, mi) andalso LT(mi, int_0x8000)
138          fun signed12 mi   = LE(int_m0x800, mi) andalso LT(mi, int_0x800)
139          fun unsigned16 mi = LE(int_0, mi) andalso LT(mi, T.I.int_0x10000)
140          fun unsigned5 mi  = LE(int_0, mi) andalso LT(mi, T.I.int_32)
141          fun unsigned6 mi  = LE(int_0, mi) andalso LT(mi, T.I.int_64)
142    
143        fun move(rs,rd,an) =        fun move(rs,rd,an) =
144          if C.sameColor(rs,rd) then ()          if CB.sameColor(rs,rd) then ()
145          else mark(I.COPY{dst=[rd],src=[rs],impl=ref NONE,tmp=NONE},an)          else mark(I.COPY{dst=[rd],src=[rs],impl=ref NONE,tmp=NONE},an)
146    
147        fun fmove(fs,fd,an) =        fun fmove(fs,fd,an) =
148          if C.sameColor(fs,fd) then ()          if CB.sameColor(fs,fd) then ()
149          else mark(I.FCOPY{dst=[fd],src=[fs],impl=ref NONE,tmp=NONE},an)          else mark(I.FCOPY{dst=[fd],src=[fs],impl=ref NONE,tmp=NONE},an)
150    
151        fun ccmove(ccs,ccd,an) =        fun ccmove(ccs,ccd,an) =
152          if C.sameColor(ccd,ccs) then () else mark(I.MCRF{bf=ccd, bfa=ccs},an)          if CB.sameColor(ccd,ccs) then () else mark(I.MCRF{bf=ccd, bfa=ccs},an)
153    
154        fun copy(dst, src, an) =        fun copy(dst, src, an) =
155            mark(I.COPY{dst=dst, src=src, impl=ref NONE,            mark(I.COPY{dst=dst, src=src, impl=ref NONE,
# Line 151  Line 161 
161                                       | _ => SOME(I.FDirect(newFreg()))},an)                                       | _ => SOME(I.FDirect(newFreg()))},an)
162    
163        fun emitBranch{bo, bf, bit, addr, LK} =        fun emitBranch{bo, bf, bit, addr, LK} =
164        let val fallThrLab = Label.newLabel""        let val fallThrLab = Label.anon()
165            val fallThrOpnd = I.LabelOp(LE.LABEL fallThrLab)            val fallThrOpnd = I.LabelOp(T.LABEL fallThrLab)
166        in        in
167            emit(I.BC{bo=bo, bf=bf, bit=bit, addr=addr, LK=LK, fall=fallThrOpnd});            emit(I.BC{bo=bo, bf=bf, bit=bit, addr=addr, LK=LK, fall=fallThrOpnd});
168            defineLabel fallThrLab            defineLabel fallThrLab
169        end        end
170    
171        fun split n =        fun split n = let
172        let val wtoi = Word.toIntX          val wtoi = Word32.toIntX
173            val w = Word.fromInt n          val w = T.I.toWord32(32, n)
174            val hi = Word.~>>(w, 0w16)          val hi = W32.~>>(w, 0w16)
175            val lo = Word.andb(w, 0w65535)          val lo = W32.andb(w, 0w65535)
176            val (high, low) = if lo < 0w32768 then (hi, lo)          val (high, low) =
177                              else (hi+0w1, lo-0w65536)            if W32.<(lo,0w32768) then (hi, lo) else (hi+0w1, lo-0w65536)
178        in (wtoi high, wtoi low) end        in
179            (wtoi high, wtoi low)
180          end
181    
182        fun loadImmedHiLo(0, lo, rt, an) =        fun loadImmedHiLo(0, lo, rt, an) =
183              mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=zeroR, im=I.ImmedOp lo}, an)              mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=zeroR, im=I.ImmedOp lo}, an)
# Line 176  Line 188 
188    
189        fun loadImmed(n, rt, an) =        fun loadImmed(n, rt, an) =
190          if signed16 n then          if signed16 n then
191             mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=zeroR, im=I.ImmedOp n}, an)             mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=zeroR, im=I.ImmedOp(toInt(n))}, an)
192          else let val (hi, lo) = split n          else let val (hi, lo) = split n
193               in loadImmedHiLo(hi, lo, rt, an) end             in loadImmedHiLo(hi, lo, rt, an)
   
       fun loadImmedw(w, rt, an) =  
           let val wtoi = Word32.toIntX  
           in  if w < 0w32768 then  
                  mark(I.ARITHI{oper=I.ADDI,rt=rt,ra=zeroR,  
                                im=I.ImmedOp(wtoi w)}, an)  
               else  
                let val hi = Word32.~>>(w, 0w16)  
                    val lo = Word32.andb(w, 0w65535)  
                    val (high, low) =  
                     if lo < 0w32768 then (hi, lo) else (hi+0w1, lo-0w65536)  
                in loadImmedHiLo(wtoi high, wtoi low, rt, an)  
                end  
194            end            end
195    
196        fun loadLabel(lexp, rt, an) =        fun loadLabexp(lexp, rt, an) =
197            mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=zeroR, im=I.LabelOp lexp}, an)            mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=zeroR, im=I.LabelOp lexp}, an)
198    
       fun loadConst(c, rt, an) =  
           mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=zeroR,  
                         im=I.LabelOp(LE.CONST c)}, an)  
   
199        fun immedOpnd range (e1, e2 as T.LI i) =        fun immedOpnd range (e1, e2 as T.LI i) =
200             (expr e1, if range i then I.ImmedOp i else I.RegOp(expr e2))             (expr e1, if range i then I.ImmedOp(toInt i) else I.RegOp(expr e2))
201          | immedOpnd _ (e1, T.CONST c) = (expr e1, I.LabelOp(LE.CONST c))          | immedOpnd _ (e1, x as T.CONST _) = (expr e1, I.LabelOp x)
202          | immedOpnd _ (e1, T.LABEL lexp) = (expr e1, I.LabelOp lexp)          | immedOpnd _ (e1, x as T.LABEL _) = (expr e1, I.LabelOp x)
203          | immedOpnd range (e1, e2 as T.LI32 w) =          | immedOpnd _ (e1, T.LABEXP lexp) = (expr e1, I.LabelOp lexp)
           let fun opnd2() = I.RegOp(expr e2)  
           in (expr e1,  
               let val i = Word32.toIntX w  
               in if range i then I.ImmedOp i else opnd2()  
               end handle Overflow => opnd2())  
           end  
204          | immedOpnd _ (e1, e2) = (expr e1, I.RegOp(expr e2))          | immedOpnd _ (e1, e2) = (expr e1, I.RegOp(expr e2))
205    
206        and commImmedOpnd range (e1 as T.LI _, e2) =        and commImmedOpnd range (e1 as T.LI _, e2) =
# Line 220  Line 209 
209             immedOpnd range (e2, e1)             immedOpnd range (e2, e1)
210          | commImmedOpnd range (e1 as T.LABEL _, e2) =          | commImmedOpnd range (e1 as T.LABEL _, e2) =
211             immedOpnd range (e2, e1)             immedOpnd range (e2, e1)
212            | commImmedOpnd range (e1 as T.LABEXP _, e2) =
213               immedOpnd range (e2, e1)
214          | commImmedOpnd range arg = immedOpnd range arg          | commImmedOpnd range arg = immedOpnd range arg
215    
216        and eCommImm range (oper, operi, e1, e2, rt, an) =        and eCommImm range (oper, operi, e1, e2, rt, an) =
# Line 235  Line 226 
226         *)         *)
227        and addr(size,T.ADD(_, e, T.LI i)) =        and addr(size,T.ADD(_, e, T.LI i)) =
228            let val ra = expr e            let val ra = expr e
229            in  if size i then (ra, I.ImmedOp i) else            in  if size i then (ra, I.ImmedOp(toInt i)) else
230                let val (hi, lo) = split i                let val (hi, lo) = split i
231                    val tmpR = newReg()                    val tmpR = newReg()
232                in  emit(I.ARITHI{oper=I.ADDIS, rt=tmpR, ra=ra, im=I.ImmedOp hi});                in  emit(I.ARITHI{oper=I.ADDIS, rt=tmpR, ra=ra, im=I.ImmedOp hi});
# Line 244  Line 235 
235            end            end
236          | addr(size,T.ADD(ty, T.LI i, e)) = addr(size,T.ADD(ty, e, T.LI i))          | addr(size,T.ADD(ty, T.LI i, e)) = addr(size,T.ADD(ty, e, T.LI i))
237          | addr(size,exp as T.SUB(ty, e, T.LI i)) =          | addr(size,exp as T.SUB(ty, e, T.LI i)) =
238              (addr(size,T.ADD(ty, e, T.LI (~i)))              (addr(size,T.ADD(ty, e, T.LI (T.I.NEGT(32, i))))
239                 handle Overflow => (expr exp, I.ImmedOp 0))                 handle Overflow => (expr exp, I.ImmedOp 0))
240          | addr(size,T.ADD(_, e1, e2)) = (expr e1, I.RegOp (expr e2))          | addr(size,T.ADD(_, e1, e2)) = (expr e1, I.RegOp (expr e2))
241          | addr(size,e) = (expr e, I.ImmedOp 0)          | addr(size,e) = (expr e, I.ImmedOp 0)
242    
243         (* convert mlrisc to cellset: *)         (* convert mlrisc to cellset: *)
244         and cellset mlrisc =         and cellset mlrisc =
245             let val addCCReg = C.CellSet.add             let val addCCReg = CB.CellSet.add
246                 fun g([],acc) = acc                 fun g([],acc) = acc
247                   | g(T.GPR(T.REG(_,r))::regs,acc)  = g(regs,C.addReg(r,acc))                   | g(T.GPR(T.REG(_,r))::regs,acc)  = g(regs,C.addReg(r,acc))
248                   | g(T.FPR(T.FREG(_,f))::regs,acc) = g(regs,C.addFreg(f,acc))                   | g(T.FPR(T.FREG(_,f))::regs,acc) = g(regs,C.addFreg(f,acc))
# Line 268  Line 259 
259          | stmt(T.CCMV(ccd, ccexp), an) = doCCexpr(ccexp, ccd, an)          | stmt(T.CCMV(ccd, ccexp), an) = doCCexpr(ccexp, ccd, an)
260          | stmt(T.COPY(_, dst, src), an) = copy(dst, src, an)          | stmt(T.COPY(_, dst, src), an) = copy(dst, src, an)
261          | stmt(T.FCOPY(_, dst, src), an) = fcopy(dst, src, an)          | stmt(T.FCOPY(_, dst, src), an) = fcopy(dst, src, an)
262          | stmt(T.JMP(T.LABEL lexp, labs),an) =          | stmt(T.JMP(T.LABEXP lexp, labs),an) =
263               mark(I.B{addr=I.LabelOp lexp, LK=false},an)               mark(I.B{addr=I.LabelOp lexp, LK=false},an)
264            | stmt(T.JMP(x as (T.LABEL _ | T.CONST _), labs),an) =
265                 mark(I.B{addr=I.LabelOp x, LK=false},an)
266          | stmt(T.JMP(rexp, labs),an) =          | stmt(T.JMP(rexp, labs),an) =
267            let val rs = expr(rexp)            let val rs = expr(rexp)
268            in  emit(MTLR(rs));            in  emit(MTLR(rs));
269                mark(I.BCLR{bo=I.ALWAYS,bf=CR0,bit=I.LT,LK=false,labels=labs},an)                mark(I.BCLR{bo=I.ALWAYS,bf=CR0,bit=I.LT,LK=false,labels=labs},an)
270            end            end
271          | stmt(T.CALL{funct, targets, defs, uses, region, ...}, an) =          | stmt(T.CALL{funct, targets, defs, uses, region, pops, ...}, an) =
272            let val defs=cellset(defs)              call(funct, targets, defs, uses, region, [], an, pops)
273                val uses=cellset(uses)          | stmt(T.FLOW_TO(T.CALL{funct, targets, defs, uses, region, pops,...},
274             in emit(MTLR(expr funct));                           cutTo), an) =
275                mark(I.CALL{def=defs, use=uses, mem=region}, an)              call(funct, targets, defs, uses, region, cutTo, an, pops)
            end  
276          | stmt(T.RET flow,an) = mark(RET,an)          | stmt(T.RET flow,an) = mark(RET,an)
277          | stmt(T.STORE(ty,ea,data,mem),an) = store(ty,ea,data,mem,an)          | stmt(T.STORE(ty,ea,data,mem),an) = store(ty,ea,data,mem,an)
278          | stmt(T.FSTORE(ty,ea,data,mem),an) = fstore(ty,ea,data,mem,an)          | stmt(T.FSTORE(ty,ea,data,mem),an) = fstore(ty,ea,data,mem,an)
# Line 289  Line 281 
281          | stmt(T.ANNOTATION(s,a),an) = stmt(s,a::an)          | stmt(T.ANNOTATION(s,a),an) = stmt(s,a::an)
282          | stmt(s, _) = doStmts(Gen.compileStm s)          | stmt(s, _) = doStmts(Gen.compileStm s)
283    
284          and call(funct, targets, defs, uses, region, cutsTo, an, 0) =
285              let val defs=cellset(defs)
286                  val uses=cellset(uses)
287              in  emit(MTLR(expr funct));
288                  mark(I.CALL{def=defs, use=uses, cutsTo=cutsTo, mem=region}, an)
289              end
290            | call _ = error "pops<>0 not implemented"
291    
292        and branch(T.CMP(_, _, T.LI _, T.LI _), _, _) = error "branch"        and branch(T.CMP(_, _, T.LI _, T.LI _), _, _) = error "branch"
         | branch(T.CMP(ty, cc, T.ANDB(_, e1, e2), T.LI 0), lab, an) =  
           (case commImmedOpnd unsigned16 (e1, e2)  
             of (ra, I.RegOp rb) =>  
                 emit(I.ARITH{oper=I.AND, ra=ra, rb=rb, rt=newReg(),  
                              Rc=true, OE=false})  
              | (ra, opnd) =>  
                 emit(I.ARITHI{oper=I.ANDI_Rc, ra=ra, im=opnd, rt=newReg()})  
            (*esac*);  
             branch(T.CC(cc, CR0), lab, an)  
           )  
293          | branch(T.CMP(ty, cc, e1 as T.LI _, e2), lab, an) =          | branch(T.CMP(ty, cc, e1 as T.LI _, e2), lab, an) =
294            let val cc' = T.Basis.swapCond cc            let val cc' = T.Basis.swapCond cc
295            in  branch(T.CMP(ty, cc', e2, e1), lab, an)            in  branch(T.CMP(ty, cc', e2, e1), lab, an)
296            end            end
297          | branch(cmp as T.CMP(ty, cond, _, _), lab, an) =          | branch(cmp as T.CMP(ty, cond, e1, e2), lab, an) = let
           let val ccreg = if true then CR0 else newCCreg() (* XXX *)  
298                val (bo, cf) =                val (bo, cf) =
299                  (case cond of                (case cond
300                     T.LT =>  (I.TRUE,  I.LT)                 of T.LT  => (I.TRUE,  I.LT)
301                   | T.LE =>  (I.FALSE, I.GT)                   | T.LE =>  (I.FALSE, I.GT)
302                   | T.EQ =>  (I.TRUE,  I.EQ)                   | T.EQ =>  (I.TRUE,  I.EQ)
303                   | T.NE =>  (I.FALSE, I.EQ)                   | T.NE =>  (I.FALSE, I.EQ)
# Line 319  Line 308 
308                   | T.GTU => (I.TRUE,  I.GT)                   | T.GTU => (I.TRUE,  I.GT)
309                   | T.GEU => (I.FALSE, I.LT)                   | T.GEU => (I.FALSE, I.LT)
310                 (*esac*))                 (*esac*))
311               val addr = I.LabelOp(LE.LABEL lab)              val ccreg = if true then CR0 else newCCreg() (* XXX *)
312            in doCCexpr(cmp, ccreg, []);              val addr = I.LabelOp(T.LABEL lab)
313               emitBranch{bo=bo, bf=ccreg, bit=cf, addr=addr, LK=false}              fun default() =
314                  (doCCexpr(cmp, ccreg, []);
315                   emitBranch{bo=bo, bf=ccreg, bit=cf, addr=addr, LK=false})
316              in
317                case (e1, e2)
318                of (T.ANDB(_, a1, a2), T.LI z) =>
319                    if T.I.isZero(z) then
320                      (case commImmedOpnd unsigned16 (a1, a2)
321                       of (ra, I.RegOp rb) =>
322                            emit(I.ARITH{oper=I.AND, ra=ra, rb=rb, rt=newReg(), Rc=true, OE=false})
323                        | (ra, opnd) =>
324                            emit(I.ARITHI{oper=I.ANDI_Rc, ra=ra, im=opnd, rt=newReg()})
325                       (*esac*);
326                       branch(T.CC(cond, CR0), lab, an))
327                    else
328                      default()
329                 | _ =>
330                      default()
331            end            end
332          | branch(T.CC(cc, cr), lab, an) =          | branch(T.CC(cc, cr), lab, an) =
333            let val addr=I.LabelOp(LE.LABEL lab)            let val addr=I.LabelOp(T.LABEL lab)
334                fun branch(bo, bit) =                fun branch(bo, bit) =
335                   emitBranch{bo=bo, bf=cr, bit=bit, addr=addr, LK=false}                   emitBranch{bo=bo, bf=cr, bit=bit, addr=addr, LK=false}
336            in  case cc of            in  case cc of
# Line 337  Line 343 
343            end            end
344          | branch(cmp as T.FCMP(fty, cond, _, _), lab, an) =          | branch(cmp as T.FCMP(fty, cond, _, _), lab, an) =
345            let val ccreg = if true then CR0 else newCCreg() (* XXX *)            let val ccreg = if true then CR0 else newCCreg() (* XXX *)
346                val labOp = I.LabelOp(LE.LABEL lab)                val labOp = I.LabelOp(T.LABEL lab)
347                fun branch(bo, bf, bit) =                fun branch(bo, bf, bit) =
348                    emitBranch{bo=bo, bf=bf, bit=bit, addr=labOp, LK=false}                    emitBranch{bo=bo, bf=bf, bit=bit, addr=labOp, LK=false}
349                fun test2bits(bit1, bit2) =                fun test2bits(bit1, bit2) =
# Line 398  Line 404 
404    
405        and subfImmed(i, ra, rt, an) =        and subfImmed(i, ra, rt, an) =
406            if signed16 i then            if signed16 i then
407               mark(I.ARITHI{oper=I.SUBFIC, rt=rt, ra=ra, im=I.ImmedOp i}, an)               mark(I.ARITHI{oper=I.SUBFIC, rt=rt, ra=ra, im=I.ImmedOp(toInt i)}, an)
408            else            else
409               mark(I.ARITH{oper=I.SUBF, rt=rt, ra=ra, rb=expr(T.LI i),               mark(I.ARITH{oper=I.SUBF, rt=rt, ra=ra, rb=expr(T.LI i),
410                            Rc=false, OE=false}, an)                            Rc=false, OE=false}, an)
# Line 418  Line 424 
424        (*  Generate an overflow trap *)        (*  Generate an overflow trap *)
425        and overflowTrap() =        and overflowTrap() =
426            let val label = case !trapLabel of            let val label = case !trapLabel of
427                              NONE => let val l = Label.newLabel ""                              NONE => let val l = Label.anon()
428                                      in  trapLabel := SOME l; l end                                      in  trapLabel := SOME l; l end
429                            | SOME l => l                            | SOME l => l
430            in  emitBranch{bo=I.TRUE, bf=CR0, bit=I.SO, LK=false,            in  emitBranch{bo=I.TRUE, bf=CR0, bit=I.SO, LK=false,
431                           addr=I.LabelOp(LE.LABEL label)}                           addr=I.LabelOp(T.LABEL label)}
432            end            end
433    
434        (* Generate a load and annotate the instruction *)        (* Generate a load and annotate the instruction *)
# Line 462  Line 468 
468    
469        (* Generate a subtract operation *)        (* Generate a subtract operation *)
470        and subtract(ty, e1, e2 as T.LI i, rt, an) =        and subtract(ty, e1, e2 as T.LI i, rt, an) =
471              (doExpr(T.ADD(ty, e1, T.LI (~i)), rt, an)              (doExpr(T.ADD(ty, e1, T.LI (T.I.NEGT(32, i))), rt, an)
472                handle Overflow =>                handle Overflow =>
473                mark(I.ARITH{oper=I.SUBF, rt=rt, ra=expr e2,                mark(I.ARITH{oper=I.SUBF, rt=rt, ra=expr e2,
474                             rb=expr e1, OE=false, Rc=false}, an)                             rb=expr e1, OE=false, Rc=false}, an)
475              )              )
476          | subtract(ty, T.LI i, e2, rt, an) = subfImmed(i, expr e2, rt, an)          | subtract(ty, T.LI i, e2, rt, an) = subfImmed(i, expr e2, rt, an)
477          | subtract(ty, T.CONST c, e2, rt, an) =          | subtract(ty, x as (T.CONST _ | T.LABEL _), e2, rt, an) =
478               mark(I.ARITHI{oper=I.SUBFIC,rt=rt,ra=expr e2,               mark(I.ARITHI{oper=I.SUBFIC,rt=rt,ra=expr e2,
479                             im=I.LabelOp(LE.CONST c)},an)                             im=I.LabelOp x},an)
         | subtract(ty, T.LI32 w, e2, rt, an) =  
              subfImmed(Word32.toIntX w, expr e2, rt, an)  
480          | subtract(ty, e1, e2, rt, an) =          | subtract(ty, e1, e2, rt, an) =
481            let val rb = expr e1 val ra = expr e2            let val rb = expr e1 val ra = expr e2
482            in  mark(I.ARITH{oper=I.SUBF,rt=rt,ra=ra,rb=rb,Rc=false,OE=false},an)            in  mark(I.ARITH{oper=I.SUBF,rt=rt,ra=ra,rb=rb,Rc=false,OE=false},an)
# Line 484  Line 488 
488                    [mark'(                    [mark'(
489                       case commImmedOpnd signed16 (e1,e2) of                       case commImmedOpnd signed16 (e1,e2) of
490                         (ra,I.RegOp rb) =>                         (ra,I.RegOp rb) =>
491                           I.ARITH{oper=oper,ra=ra,rb=rb,rt=rt,OE=false,Rc=false}                           I.arith{oper=oper,ra=ra,rb=rb,rt=rt,OE=false,Rc=false}
492                       | (ra,im) => I.ARITHI{oper=operi,ra=ra,im=im,rt=rt},                       | (ra,im) => I.arithi{oper=operi,ra=ra,im=im,rt=rt},
493                       an)]                       an)]
494                fun const(e,i) =                fun const(e,i) =
495                    let val r = expr e                    let val r = expr e
496                    in  genMult{r=r,i=i,d=rt}                    in  genMult{r=r,i=toInt(i),d=rt}
497                        handle _ => nonconst(T.REG(ty,r),T.LI i)                        handle _ => nonconst(T.REG(ty,r),T.LI i)
498                    end                    end
               fun constw(e,i) = const(e,Word32.toInt i)  
                                  handle _ => nonconst(e,T.LI32 i)  
499                val instrs =                val instrs =
500                   case (e1,e2) of                   case (e1,e2) of
501                     (_,T.LI i)   => const(e1,i)                     (_,T.LI i)   => const(e1,i)
                  | (_,T.LI32 i) => constw(e1,i)  
502                   | (T.LI i,_)   => const(e2,i)                   | (T.LI i,_)   => const(e2,i)
                  | (T.LI32 i,_) => constw(e2,i)  
503                   | _            => nonconst(e1,e2)                   | _            => nonconst(e1,e2)
504            in  app emit instrs end            in  app emitInstruction instrs end
505    
506        and divu32 x = Mulu32.divide{mode=T.TO_ZERO,stm=doStmt} x        and divu32 x = Mulu32.divide{mode=T.TO_ZERO,stm=doStmt} x
507    
508        and divt32 x = Mult32.divide{mode=T.TO_ZERO,stm=doStmt} x        and divt32 x = Mult32.divide{mode=T.TO_ZERO,stm=doStmt} x
509    
       (*  
       and GOTO lab = T.JMP(T.LABEL(LE.LABEL lab), [], [])  
   
       and roundToZero{ty,r,i,d} =  
       let val L = Label.newLabel ""  
           val dReg = T.REG(ty,d)  
       in  doStmt(T.MV(ty,d,T.REG(ty,r)));  
           doStmt(T.IF(T.CMP(ty,T.GE,dReg,T.LI 0),GOTO L,T.SEQ []));  
           doStmt(T.MV(ty,d,T.ADD(ty,dReg,T.LI i)));  
           defineLabel L  
       end  
        *)  
   
510            (* Generate optimized division code *)            (* Generate optimized division code *)
511        and divide(ty,oper,genDiv,e1,e2,rt,overflow,an) =        and divide(ty,oper,genDiv,e1,e2,rt,overflow,an) =
512            let fun nonconst(e1,e2) =            let fun nonconst(e1,e2) =
# Line 529  Line 516 
516                    )                    )
517                fun const(e,i) =                fun const(e,i) =
518                    let val r = expr e                    let val r = expr e
519                    in  app emit (genDiv{r=r,i=i,d=rt})                    in  app emitInstruction (genDiv{r=r,i=toInt(i),d=rt})
520                        handle _ => nonconst(T.REG(ty,r),T.LI i)                        handle _ => nonconst(T.REG(ty,r),T.LI i)
521                    end                    end
               fun constw(e,i) = const(e,Word32.toInt i)  
                                 handle _ => nonconst(e,T.LI32 i)  
522            in  case (e1,e2) of            in  case (e1,e2) of
523                  (_,T.LI i)   => const(e1,i)                  (_,T.LI i)   => const(e1,i)
               | (_,T.LI32 i) => constw(e1,i)  
524                | _            => nonconst(e1,e2)                | _            => nonconst(e1,e2)
525            end            end
526    
# Line 552  Line 536 
536         * the value.         * the value.
537         *)         *)
538        and expr(rexp as T.REG(_,r)) =        and expr(rexp as T.REG(_,r)) =
539            if C.sameColor(C.lr, r) then            if CB.sameColor(C.lr, r) then
540            let val rt = newReg()            let val rt = newReg()
541            in  doExpr(rexp, rt, []); rt end            in  doExpr(rexp, rt, []); rt end
542            else r            else r
# Line 565  Line 549 
549         *    and annotate the expression with an         *    and annotate the expression with an
550         *)         *)
551        and doExpr(e, rt, an) =        and doExpr(e, rt, an) =
552             if C.sameColor(rt,C.lr) then             if CB.sameColor(rt,C.lr) then
553             let val rt = newReg() in doExpr(e,rt,[]); mark(MTLR rt,an) end             let val rt = newReg() in doExpr(e,rt,[]); mark(MTLR rt,an) end
554             else             else
555             case e of             case e of
556               T.REG(_,rs)  => if C.sameColor(rs,C.lr) then mark(MFLR rt,an)               T.REG(_,rs)  => if CB.sameColor(rs,C.lr) then mark(MFLR rt,an)
557                               else move(rs,rt,an)                               else move(rs,rt,an)
558             | T.LI i       => loadImmed(i, rt, an)             | T.LI i       => loadImmed(i, rt, an)
559             | T.LI32 w     => loadImmedw(w, rt, an)             | T.LABEXP lexp => loadLabexp(lexp, rt, an)
560             | T.LABEL lexp => loadLabel(lexp, rt, an)             | T.CONST _     => loadLabexp(e, rt, an)
561             | T.CONST c    => loadConst(c, rt, an)             | T.LABEL _     => loadLabexp(e, rt, an)
562    
563               (* All data widths *)               (* All data widths *)
564             | T.ADD(_, e1, e2) => eCommImm signed16 (I.ADD,I.ADDI,e1,e2,rt,an)             | T.ADD(_, e1, e2) => eCommImm signed16 (I.ADD,I.ADDI,e1,e2,rt,an)
# Line 678  Line 662 
662            | T.FADD(32,T.FMUL(32,a,c),b) => f3(I.FMADDS,a,b,c,ft,an)            | T.FADD(32,T.FMUL(32,a,c),b) => f3(I.FMADDS,a,b,c,ft,an)
663            | T.FADD(32,b,T.FMUL(32,a,c)) => f3(I.FMADDS,a,b,c,ft,an)            | T.FADD(32,b,T.FMUL(32,a,c)) => f3(I.FMADDS,a,b,c,ft,an)
664            | T.FSUB(32,T.FMUL(32,a,c),b) => f3(I.FMSUBS,a,b,c,ft,an)            | T.FSUB(32,T.FMUL(32,a,c),b) => f3(I.FMSUBS,a,b,c,ft,an)
665            | T.FSUB(32,b,T.FMUL(32,a,c)) => f3(I.FNMADDS,a,b,c,ft,an)            | T.FSUB(32,b,T.FMUL(32,a,c)) => f3(I.FNMSUBS,a,b,c,ft,an)
666            | T.FNEG(32,T.FADD(32,T.FMUL(32,a,c),b)) => f3(I.FNMSUBS,a,b,c,ft,an)            | T.FNEG(32,T.FADD(32,T.FMUL(32,a,c),b)) => f3(I.FNMADDS,a,b,c,ft,an)
667            | T.FNEG(32,T.FADD(32,b,T.FMUL(32,a,c))) => f3(I.FNMSUBS,a,b,c,ft,an)            | T.FNEG(32,T.FADD(32,b,T.FMUL(32,a,c))) => f3(I.FNMADDS,a,b,c,ft,an)
668            | T.FSUB(32,T.FNEG(32,T.FMUL(32,a,c)),b) => f3(I.FNMSUBS,a,b,c,ft,an)            | T.FSUB(32,T.FNEG(32,T.FMUL(32,a,c)),b) => f3(I.FNMADDS,a,b,c,ft,an)
669    
670            | T.FADD(32, e1, e2) => fbinary(I.FADDS, e1, e2, ft, an)            | T.FADD(32, e1, e2) => fbinary(I.FADDS, e1, e2, ft, an)
671            | T.FSUB(32, e1, e2) => fbinary(I.FSUBS, e1, e2, ft, an)            | T.FSUB(32, e1, e2) => fbinary(I.FSUBS, e1, e2, ft, an)
# Line 695  Line 679 
679            | T.FADD(64,T.FMUL(64,a,c),b) => f3(I.FMADD,a,b,c,ft,an)            | T.FADD(64,T.FMUL(64,a,c),b) => f3(I.FMADD,a,b,c,ft,an)
680            | T.FADD(64,b,T.FMUL(64,a,c)) => f3(I.FMADD,a,b,c,ft,an)            | T.FADD(64,b,T.FMUL(64,a,c)) => f3(I.FMADD,a,b,c,ft,an)
681            | T.FSUB(64,T.FMUL(64,a,c),b) => f3(I.FMSUB,a,b,c,ft,an)            | T.FSUB(64,T.FMUL(64,a,c),b) => f3(I.FMSUB,a,b,c,ft,an)
682            | T.FSUB(64,b,T.FMUL(64,a,c)) => f3(I.FNMADD,a,b,c,ft,an)            | T.FSUB(64,b,T.FMUL(64,a,c)) => f3(I.FNMSUB,a,b,c,ft,an)
683            | T.FNEG(64,T.FADD(64,T.FMUL(64,a,c),b)) => f3(I.FNMSUB,a,b,c,ft,an)            | T.FNEG(64,T.FADD(64,T.FMUL(64,a,c),b)) => f3(I.FNMADD,a,b,c,ft,an)
684            | T.FNEG(64,T.FADD(64,b,T.FMUL(64,a,c))) => f3(I.FNMSUB,a,b,c,ft,an)            | T.FNEG(64,T.FADD(64,b,T.FMUL(64,a,c))) => f3(I.FNMADD,a,b,c,ft,an)
685            | T.FSUB(64,T.FNEG(64,T.FMUL(64,a,c)),b) => f3(I.FNMSUB,a,b,c,ft,an)            | T.FSUB(64,T.FNEG(64,T.FMUL(64,a,c)),b) => f3(I.FNMADD,a,b,c,ft,an)
686    
687            | T.FADD(64, e1, e2) => fbinary(I.FADD, e1, e2, ft, an)            | T.FADD(64, e1, e2) => fbinary(I.FADD, e1, e2, ft, an)
688            | T.FSUB(64, e1, e2) => fbinary(I.FSUB, e1, e2, ft, an)            | T.FSUB(64, e1, e2) => fbinary(I.FSUB, e1, e2, ft, an)
689            | T.FMUL(64, e1, e2) => fbinary(I.FMUL, e1, e2, ft, an)            | T.FMUL(64, e1, e2) => fbinary(I.FMUL, e1, e2, ft, an)
690            | T.FDIV(64, e1, e2) => fbinary(I.FDIV, e1, e2, ft, an)            | T.FDIV(64, e1, e2) => fbinary(I.FDIV, e1, e2, ft, an)
691            | T.CVTI2F(64,_,e) =>            | T.CVTI2F(64,_,e) =>
692                 app emit (PseudoInstrs.cvti2d{reg=expr e,fd=ft})                 app emitInstruction (PseudoInstrs.cvti2d{reg=expr e,fd=ft})
693    
694              (* Single/double precision support *)              (* Single/double precision support *)
695            | T.FABS((32|64), e) => funary(I.FABS, e, ft, an)            | T.FABS((32|64), e) => funary(I.FABS, e, ft, an)
# Line 749  Line 733 
733    
734        and emitTrap() = emit(I.TW{to=31,ra=zeroR,si=I.ImmedOp 0})        and emitTrap() = emit(I.TW{to=31,ra=zeroR,si=I.ImmedOp 0})
735    
736          val beginCluster = fn _ => (trapLabel := NONE; beginCluster(0))          val beginCluster = fn _ =>
737               (trapLabel := NONE; beginCluster 0)
738          val endCluster = fn a =>          val endCluster = fn a =>
739             (case !trapLabel of             (case !trapLabel of
740                SOME label =>                SOME label =>
# Line 757  Line 742 
742              | NONE => ();              | NONE => ();
743             endCluster a)             endCluster a)
744    
745     in  S.STREAM     in  TS.S.STREAM
746         { beginCluster = beginCluster,         { beginCluster = beginCluster,
747           endCluster   = endCluster,           endCluster   = endCluster,
748           emit         = doStmt,           emit         = doStmt,
# Line 766  Line 751 
751           entryLabel   = entryLabel,           entryLabel   = entryLabel,
752           comment      = comment,           comment      = comment,
753           annotation   = annotation,           annotation   = annotation,
754             getAnnotations=getAnnotations,
755           exitBlock    = fn mlrisc => exitBlock(cellset mlrisc)           exitBlock    = fn mlrisc => exitBlock(cellset mlrisc)
756         }         }
757     end     end

Legend:
Removed from v.744  
changed lines
  Added in v.1003

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