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 717, Sun Nov 5 15:07:51 2000 UTC revision 1722, Sun Dec 12 05:49:04 2004 UTC
# Line 1  Line 1 
1  (*  (* ppc.sml
2     *
3     * COPYRIGHT (c) 2002 Bell Labs, Lucent Technologies
4     *
5   * I've substantially modified this code generator to support the new MLTREE.   * I've substantially modified this code generator to support the new MLTREE.
6   * Please see the file README.hppa for the ugly details.   * Please see the file README.hppa for the ugly details.
7   *   *
# Line 7  Line 10 
10    
11  functor PPC  functor PPC
12    (structure PPCInstr : PPCINSTR    (structure PPCInstr : PPCINSTR
    structure PPCMLTree : MLTREE  
    structure ExtensionComp : MLTREE_EXTENSION_COMP  
       where I = PPCInstr and T = PPCMLTree  
13     structure PseudoInstrs : PPC_PSEUDO_INSTR     structure PseudoInstrs : PPC_PSEUDO_INSTR
14        sharing PPCMLTree.Region = PPCInstr.Region                          where I = PPCInstr
15        sharing PPCMLTree.LabelExp = PPCInstr.LabelExp     structure ExtensionComp : MLTREE_EXTENSION_COMP
16        sharing PseudoInstrs.I = PPCInstr                          where I = PPCInstr and T = PPCInstr.T
17    
18     (*     (*
19      * Support 64 bit mode?      * Support 64 bit mode?
# Line 25  Line 25 
25      * Cost of multiplication in cycles      * Cost of multiplication in cycles
26      *)      *)
27     val multCost : int ref     val multCost : int ref
28    ) : MLTREECOMP =    ) =
29  struct  struct
30    structure I   = PPCInstr    structure I   = PPCInstr
31    structure T   = PPCMLTree    structure T   = I.T
32    structure S   = T.Stream    structure TS  = ExtensionComp.TS
33    structure C   = PPCInstr.C    structure C   = PPCInstr.C
34    structure LE  = I.LabelExp    structure CB  = CellsBasis
35    structure W32 = Word32    structure W32 = Word32
36      structure A   = MLRiscAnnotations
37      structure CFG = ExtensionComp.CFG
38    
39    fun error msg = MLRiscErrorMsg.error("PPC",msg)    fun error msg = MLRiscErrorMsg.error("PPC",msg)
40    
41    type instrStream = (I.instruction,C.regmap,C.cellset) T.stream    type instrStream = (I.instruction, CB.CellSet.cellset, CFG.cfg) TS.stream
42    type mltreeStream = (T.stm,C.regmap,T.mlrisc list) T.stream    type mltreeStream = (T.stm, T.mlrisc list, CFG.cfg) TS.stream
43    
44    
45    val (intTy,naturalWidths) = if bit64mode then (64,[32,64]) else (32,[32])    val (intTy,naturalWidths) = if bit64mode then (64,[32,64]) else (32,[32])
46    structure Gen = MLTreeGen    structure Gen = MLTreeGen
47      (structure T = T      (structure T = T
48         structure Cells = C
49       val intTy = intTy       val intTy = intTy
50       val naturalWidths = naturalWidths       val naturalWidths = naturalWidths
51       datatype rep = SE | ZE | NEITHER       datatype rep = SE | ZE | NEITHER
# Line 53  Line 57 
57     *)     *)
58    fun MTLR r = I.MTSPR{rs=r, spr=C.lr}    fun MTLR r = I.MTSPR{rs=r, spr=C.lr}
59    fun MFLR r = I.MFSPR{rt=r, spr=C.lr}    fun MFLR r = I.MFSPR{rt=r, spr=C.lr}
60    val CR0 = C.Reg C.CC 0    val CR0 = C.Reg CB.CC 0
61    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=[]}
62    fun SLLI32{r,i,d} =    fun SLLI32{r,i,d} =
63        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)}
64    fun SRLI32{r,i,d} =    fun SRLI32{r,i,d} =
65        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(Int.mod(32-i,32)),mb=i,me=SOME(31)}
66      fun COPY{dst, src, tmp} =
67    val _ = if C.lr = 80 then () else error "LR must be encoded as 80!"        I.COPY{k=CB.GP, sz=32, dst=dst, src=src, tmp=tmp}
68      fun FCOPY{dst, src, tmp} =
69          I.COPY{k=CB.FP, sz=64, dst=dst, src=src, tmp=tmp}
70    
71    (*    (*
72     * Integer multiplication     * Integer multiplication
# Line 68  Line 74 
74    functor Multiply32 = MLTreeMult    functor Multiply32 = MLTreeMult
75      (structure I = I      (structure I = I
76       structure T = T       structure T = T
77         structure CB = CellsBasis
78       val intTy = 32       val intTy = 32
79       type arg  = {r1:C.cell,r2:C.cell,d:C.cell}       type arg  = {r1:CB.cell,r2:CB.cell,d:CB.cell}
80       type argi = {r:C.cell,i:int,d:C.cell}       type argi = {r:CB.cell,i:int,d:CB.cell}
81    
82       fun mov{r,d} = I.COPY{dst=[d],src=[r],tmp=NONE,impl=ref NONE}       fun mov{r,d} = COPY{dst=[d],src=[r],tmp=NONE}
83       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}
84       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})]
85       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})]
86       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}]
87      )      )
88    
89    structure Mulu32 = Multiply32    structure Mulu32 = Multiply32
90      (val trapping = false      (val trapping = false
91       val multCost = multCost       val multCost = multCost
92       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}]
93       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}]
94       val sh1addv = NONE       val sh1addv = NONE
95       val sh2addv = NONE       val sh2addv = NONE
96       val sh3addv = NONE       val sh3addv = NONE
97      )      )
98      (val signed = false)      (val signed = false)
99    
100      structure Muls32 = Multiply32
101        (val trapping = false
102         val multCost = multCost
103         fun addv{r1,r2,d}=[I.arith{oper=I.ADD,ra=r1,rb=r2,rt=d,Rc=false,OE=false}]
104         fun subv{r1,r2,d}=[I.arith{oper=I.SUBF,ra=r2,rb=r1,rt=d,Rc=false,OE=false}]
105         val sh1addv = NONE
106         val sh2addv = NONE
107         val sh3addv = NONE
108        )
109        (val signed = true)
110    
111    structure Mult32 = Multiply32    structure Mult32 = Multiply32
112      (val trapping = true      (val trapping = true
113       val multCost = multCost       val multCost = multCost
# Line 102  Line 120 
120      (val signed = true)      (val signed = true)
121    
122    fun selectInstructions    fun selectInstructions
123        (S.STREAM{emit,comment,        (instrStream as
124           TS.S.STREAM{emit=emitInstruction,comment,getAnnotations,
125                  defineLabel,entryLabel,pseudoOp,annotation,                  defineLabel,entryLabel,pseudoOp,annotation,
126                  beginCluster,endCluster,exitBlock,phi,alias,...}) =                  beginCluster,endCluster,exitBlock,...}) =
127    let (* mark an instruction with annotations *)    let
128        fun mark'(instr,[]) = instr        val emit = emitInstruction o I.INSTR
129          | mark'(instr,a::an) = mark'(I.ANNOTATION{i=instr,a=a},an)  
130        fun mark(instr,an) = emit(mark'(instr,an))        (* mark an instruction with annotations *)
131          fun annotate(instr,[]) = instr
132            | annotate(instr,a::an) = annotate(I.ANNOTATION{i=instr,a=a},an)
133          fun mark'(instr, an) = emitInstruction(annotate(instr, an))
134          fun mark(instr,an) = emitInstruction(annotate(I.INSTR instr,an))
135    
136        (* Label where trap is generated.        (* Label where trap is generated.
137         * For overflow trapping instructions, we generate a branch         * For overflow trapping instructions, we generate a branch
138         * to this label.         * to this label.
139         *)         *)
140        val trapLabel : Label.label option ref = ref NONE        val trapLabel : Label.label option ref = ref NONE
141          val zeroR = C.r0
142    
143        val newReg = C.newReg        val newReg = C.newReg
144        val newFreg = C.newFreg        val newFreg = C.newFreg
145        val newCCreg = C.newCell C.CC        val newCCreg = C.newCell CB.CC
146    
147    
148        fun signed16 i = ~32768 <= i andalso i < 32768        fun LT (x,y)    = T.I.LT(32, x, y)
149        fun signed12 i = ~2048 <= i andalso i < 2048        fun LE (x,y)    = T.I.LE(32, x, y)
150        fun unsigned16 i = 0 <= i andalso i < 65536        fun toInt mi = T.I.toInt(32, mi)
151        fun unsigned5  i = 0 <= i andalso i < 32        fun LI i = T.I.fromInt(32, i)
152        fun unsigned6  i = 0 <= i andalso i < 64  
153          fun signed16 mi   = LE(~0x8000, mi) andalso LT(mi, 0x8000)
154          fun signed12 mi   = LE(~0x800, mi) andalso LT(mi, 0x800)
155          fun unsigned16 mi = LE(0, mi) andalso LT(mi, 0x10000)
156          fun unsigned5 mi  = LE(0, mi) andalso LT(mi, 32)
157          fun unsigned6 mi  = LE(0, mi) andalso LT(mi, 64)
158    
159        fun move(rs,rd,an) =        fun move(rs,rd,an) =
160          if rs=rd then ()          if CB.sameColor(rs,rd) then ()
161          else mark(I.COPY{dst=[rd],src=[rs],impl=ref NONE,tmp=NONE},an)          else mark'(COPY{dst=[rd],src=[rs],tmp=NONE},an)
162    
163        fun fmove(fs,fd,an) =        fun fmove(fs,fd,an) =
164          if fs=fd then ()          if CB.sameColor(fs,fd) then ()
165          else mark(I.FCOPY{dst=[fd],src=[fs],impl=ref NONE,tmp=NONE},an)          else mark'(FCOPY{dst=[fd],src=[fs],tmp=NONE},an)
166    
167        fun ccmove(ccs,ccd,an) =        fun ccmove(ccs,ccd,an) =
168          if 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)
169    
170        fun copy(dst, src, an) =        fun copy(dst, src, an) =
171            mark(I.COPY{dst=dst, src=src, impl=ref NONE,            mark'(COPY{dst=dst, src=src,
172                        tmp=case dst of [_] => NONE                        tmp=case dst of [_] => NONE
173                                      | _ => SOME(I.Direct(newReg()))},an)                                      | _ => SOME(I.Direct(newReg()))},an)
174        fun fcopy(dst, src, an) =        fun fcopy(dst, src, an) =
175            mark(I.FCOPY{dst=dst, src=src, impl=ref NONE,            mark'(FCOPY{dst=dst, src=src,
176                         tmp=case dst of [_] => NONE                         tmp=case dst of [_] => NONE
177                                       | _ => SOME(I.FDirect(newFreg()))},an)                                       | _ => SOME(I.FDirect(newFreg()))},an)
178    
179        fun emitBranch{bo, bf, bit, addr, LK} =        fun emitBranch{bo, bf, bit, addr, LK} =
180        let val fallThrLab = Label.newLabel""        let val fallThrLab = Label.anon()
181            val fallThrOpnd = I.LabelOp(LE.LABEL fallThrLab)            val fallThrOpnd = I.LabelOp(T.LABEL fallThrLab)
182        in        in
183            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});
184            defineLabel fallThrLab            defineLabel fallThrLab
185        end        end
186    
187        fun split n =        fun split n = let
188        let val wtoi = Word.toIntX          val wtoi = Word32.toIntX
189            val w = Word.fromInt n          val w = T.I.toWord32(32, n)
190            val hi = Word.~>>(w, 0w16)          val hi = W32.~>>(w, 0w16)
191            val lo = Word.andb(w, 0w65535)          val lo = W32.andb(w, 0w65535)
192            val (high, low) = if lo < 0w32768 then (hi, lo)          val (high, low) =
193                              else (hi+0w1, lo-0w65536)            if W32.<(lo,0w32768) then (hi, lo) else (hi+0w1, lo-0w65536)
194        in (wtoi high, wtoi low) end        in
195            (wtoi high, wtoi low)
196          end
197    
198        fun loadImmedHiLo(0, lo, rt, an) =        fun loadImmedHiLo(0, lo, rt, an) =
199              mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=0, im=I.ImmedOp lo}, an)              mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=zeroR, im=I.ImmedOp lo}, an)
200          | loadImmedHiLo(hi, lo, rt, an) =          | loadImmedHiLo(hi, lo, rt, an) =
201             (mark(I.ARITHI{oper=I.ADDIS, rt=rt, ra=0, im=I.ImmedOp hi}, an);             (mark(I.ARITHI{oper=I.ADDIS, rt=rt, ra=zeroR, im=I.ImmedOp hi}, an);
202              if lo = 0 then ()              if lo = 0 then ()
203                 else emit(I.ARITHI{oper=I.ADDI, rt=rt, ra=rt, im=I.ImmedOp lo}))                 else emit(I.ARITHI{oper=I.ADDI, rt=rt, ra=rt, im=I.ImmedOp lo}))
204    
205        fun loadImmed(n, rt, an) =        fun loadImmed(n, rt, an) =
206          if signed16 n then          if signed16 n then
207             mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=0 , im=I.ImmedOp n}, an)             mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=zeroR, im=I.ImmedOp(toInt(n))}, an)
208          else let val (hi, lo) = split n          else let val (hi, lo) = split n
209               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=0,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)  
210                 end                 end
           end  
   
       fun loadLabel(lexp, rt, an) =  
           mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=0, im=I.LabelOp lexp}, an)  
211    
212        fun loadConst(c, rt, an) =        fun loadLabexp(lexp, rt, an) =
213            mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=0, im=I.LabelOp(LE.CONST c)}, an)            mark(I.ARITHI{oper=I.ADDI, rt=rt, ra=zeroR, im=I.LabelOp lexp}, an)
214    
215        fun immedOpnd range (e1, e2 as T.LI i) =        fun immedOpnd range (e1, e2 as T.LI i) =
216             (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))
217          | immedOpnd _ (e1, T.CONST c) = (expr e1, I.LabelOp(LE.CONST c))          | immedOpnd _ (e1, x as T.CONST _) = (expr e1, I.LabelOp x)
218          | immedOpnd _ (e1, T.LABEL lexp) = (expr e1, I.LabelOp lexp)          | immedOpnd _ (e1, x as T.LABEL _) = (expr e1, I.LabelOp x)
219          | 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  
220          | immedOpnd _ (e1, e2) = (expr e1, I.RegOp(expr e2))          | immedOpnd _ (e1, e2) = (expr e1, I.RegOp(expr e2))
221    
222        and commImmedOpnd range (e1 as T.LI _, e2) =        and commImmedOpnd range (e1 as T.LI _, e2) =
# Line 214  Line 225 
225             immedOpnd range (e2, e1)             immedOpnd range (e2, e1)
226          | commImmedOpnd range (e1 as T.LABEL _, e2) =          | commImmedOpnd range (e1 as T.LABEL _, e2) =
227             immedOpnd range (e2, e1)             immedOpnd range (e2, e1)
228            | commImmedOpnd range (e1 as T.LABEXP _, e2) =
229               immedOpnd range (e2, e1)
230          | commImmedOpnd range arg = immedOpnd range arg          | commImmedOpnd range arg = immedOpnd range arg
231    
232        and eCommImm range (oper, operi, e1, e2, rt, an) =        and eCommImm range (oper, operi, e1, e2, rt, an) =
# Line 229  Line 242 
242         *)         *)
243        and addr(size,T.ADD(_, e, T.LI i)) =        and addr(size,T.ADD(_, e, T.LI i)) =
244            let val ra = expr e            let val ra = expr e
245            in  if size i then (ra, I.ImmedOp i) else            in  if size i then (ra, I.ImmedOp(toInt i)) else
246                let val (hi, lo) = split i                let val (hi, lo) = split i
247                    val tmpR = newReg()                    val tmpR = newReg()
248                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 238  Line 251 
251            end            end
252          | 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))
253          | addr(size,exp as T.SUB(ty, e, T.LI i)) =          | addr(size,exp as T.SUB(ty, e, T.LI i)) =
254              (addr(size,T.ADD(ty, e, T.LI (~i)))              (addr(size,T.ADD(ty, e, T.LI (T.I.NEGT(32, i))))
255                 handle Overflow => (expr exp, I.ImmedOp 0))                 handle Overflow => (expr exp, I.ImmedOp 0))
256          | addr(size,T.ADD(_, e1, e2)) = (expr e1, I.RegOp (expr e2))          | addr(size,T.ADD(_, e1, e2)) = (expr e1, I.RegOp (expr e2))
257          | addr(size,e) = (expr e, I.ImmedOp 0)          | addr(size,e) = (expr e, I.ImmedOp 0)
258    
259         (* convert mlrisc to cellset: *)         (* convert mlrisc to cellset: *)
260         and cellset mlrisc =         and cellset mlrisc =
261             let val addCCReg = C.addCell C.CC             let val addCCReg = CB.CellSet.add
262                 fun g([],acc) = acc                 fun g([],acc) = acc
263                   | 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))
264                   | 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 262  Line 275 
275          | stmt(T.CCMV(ccd, ccexp), an) = doCCexpr(ccexp, ccd, an)          | stmt(T.CCMV(ccd, ccexp), an) = doCCexpr(ccexp, ccd, an)
276          | stmt(T.COPY(_, dst, src), an) = copy(dst, src, an)          | stmt(T.COPY(_, dst, src), an) = copy(dst, src, an)
277          | stmt(T.FCOPY(_, dst, src), an) = fcopy(dst, src, an)          | stmt(T.FCOPY(_, dst, src), an) = fcopy(dst, src, an)
278          | stmt(T.JMP(ctrl, T.LABEL lexp, labs),an) =          | stmt(T.JMP(T.LABEXP lexp, labs),an) =
279               mark(I.B{addr=I.LabelOp lexp, LK=false},an)               mark(I.B{addr=I.LabelOp lexp, LK=false},an)
280          | stmt(T.JMP(ctrl, rexp, labs),an) =          | stmt(T.JMP(x as (T.LABEL _ | T.CONST _), labs),an) =
281                 mark(I.B{addr=I.LabelOp x, LK=false},an)
282            | stmt(T.JMP(rexp, labs),an) =
283            let val rs = expr(rexp)            let val rs = expr(rexp)
284            in  emit(MTLR(rs));            in  emit(MTLR(rs));
285                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)
286            end            end
287          | stmt(T.CALL{funct, targets, defs, uses, cdefs, cuses, region}, an) =          | stmt(T.CALL{funct, targets, defs, uses, region, pops, ...}, an) =
288            let val defs=cellset(defs)              call(funct, targets, defs, uses, region, [], an, pops)
289                val uses=cellset(uses)          | stmt(T.FLOW_TO(T.CALL{funct, targets, defs, uses, region, pops,...},
290             in emit(MTLR(expr funct));                           cutTo), an) =
291                mark(I.CALL{def=defs, use=uses, mem=region}, an)              call(funct, targets, defs, uses, region, cutTo, an, pops)
            end  
292          | stmt(T.RET flow,an) = mark(RET,an)          | stmt(T.RET flow,an) = mark(RET,an)
293          | 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)
294          | 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)
295          | stmt(T.BCC(ctrl, cc, lab),an) =          | stmt(T.BCC(cc, lab),an) = branch(cc,lab,an)
               branch(cc,lab,an)  
296          | stmt(T.DEFINE l, _) = defineLabel l          | stmt(T.DEFINE l, _) = defineLabel l
297            | stmt(T.LIVE S, an) = mark'(I.LIVE{regs=cellset S,spilled=C.empty},an)
298            | stmt(T.KILL S, an) = mark'(I.KILL{regs=cellset S,spilled=C.empty},an)
299          | stmt(T.ANNOTATION(s,a),an) = stmt(s,a::an)          | stmt(T.ANNOTATION(s,a),an) = stmt(s,a::an)
300            | stmt(T.EXT s,an) = ExtensionComp.compileSext(reducer()) {stm=s, an=an}
301          | stmt(s, _) = doStmts(Gen.compileStm s)          | stmt(s, _) = doStmts(Gen.compileStm s)
302    
303        and branch(T.CMP(_, _, T.LI _, T.LI _), _, _) = error "branch"        and call(funct, targets, defs, uses, region, cutsTo, an, 0) =
304          | branch(T.CMP(ty, cc, T.ANDB(_, e1, e2), T.LI 0), lab, an) =            let val defs=cellset(defs)
305            (case commImmedOpnd unsigned16 (e1, e2)                val uses=cellset(uses)
306              of (ra, I.RegOp rb) =>            in  emit(MTLR(expr funct));
307                  emit(I.ARITH{oper=I.AND, ra=ra, rb=rb, rt=newReg(),                mark(I.CALL{def=defs, use=uses, cutsTo=cutsTo, mem=region}, an)
308                               Rc=true, OE=false})            end
309               | (ra, opnd) =>          | call _ = error "pops<>0 not implemented"
310                  emit(I.ARITHI{oper=I.ANDI_Rc, ra=ra, im=opnd, rt=newReg()})  
311             (*esac*);        and branch(T.CMP(_, _, T.LI _, T.LI _), _, _) = error "branch(LI,LI)"
             branch(T.CC(cc, CR0), lab, an)  
           )  
312          | branch(T.CMP(ty, cc, e1 as T.LI _, e2), lab, an) =          | branch(T.CMP(ty, cc, e1 as T.LI _, e2), lab, an) =
313            let val cc' = T.Basis.swapCond cc            let val cc' = T.Basis.swapCond cc
314            in  branch(T.CMP(ty, cc', e2, e1), lab, an)            in  branch(T.CMP(ty, cc', e2, e1), lab, an)
315            end            end
316          | 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 *)  
317                val (bo, cf) =                val (bo, cf) =
318                  (case cond of                (case cond
319                     T.LT =>  (I.TRUE,  I.LT)                 of T.LT  => (I.TRUE,  I.LT)
320                   | T.LE =>  (I.FALSE, I.GT)                   | T.LE =>  (I.FALSE, I.GT)
321                   | T.EQ =>  (I.TRUE,  I.EQ)                   | T.EQ =>  (I.TRUE,  I.EQ)
322                   | T.NE =>  (I.FALSE, I.EQ)                   | T.NE =>  (I.FALSE, I.EQ)
# Line 313  Line 326 
326                   | T.LEU => (I.FALSE, I.GT)                   | T.LEU => (I.FALSE, I.GT)
327                   | T.GTU => (I.TRUE,  I.GT)                   | T.GTU => (I.TRUE,  I.GT)
328                   | T.GEU => (I.FALSE, I.LT)                   | T.GEU => (I.FALSE, I.LT)
329                    | (T.SETCC | T.MISC_COND _) => error "branch(CMP)"
330                 (*esac*))                 (*esac*))
331               val addr = I.LabelOp(LE.LABEL lab)              val ccreg = if true then CR0 else newCCreg() (* XXX *)
332            in doCCexpr(cmp, ccreg, []);              val addr = I.LabelOp(T.LABEL lab)
333               emitBranch{bo=bo, bf=ccreg, bit=cf, addr=addr, LK=false}              fun default() =
334                  (doCCexpr(cmp, ccreg, []);
335                   emitBranch{bo=bo, bf=ccreg, bit=cf, addr=addr, LK=false})
336              in
337                case (e1, e2)
338                of (T.ANDB(_, a1, a2), T.LI z) =>
339                    if z = 0 then
340                      (case commImmedOpnd unsigned16 (a1, a2)
341                       of (ra, I.RegOp rb) =>
342                            emit(I.ARITH{oper=I.AND, ra=ra, rb=rb, rt=newReg(), Rc=true, OE=false})
343                        | (ra, opnd) =>
344                            emit(I.ARITHI{oper=I.ANDI_Rc, ra=ra, im=opnd, rt=newReg()})
345                       (*esac*);
346                       branch(T.CC(cond, CR0), lab, an))
347                    else
348                      default()
349                 | _ =>
350                      default()
351            end            end
352          | branch(T.CC(cc, cr), lab, an) =          | branch(T.CC(cc, cr), lab, an) =
353            let val addr=I.LabelOp(LE.LABEL lab)            let val addr=I.LabelOp(T.LABEL lab)
354                fun branch(bo, bit) =                fun branch(bo, bit) =
355                   emitBranch{bo=bo, bf=cr, bit=bit, addr=addr, LK=false}                   emitBranch{bo=bo, bf=cr, bit=bit, addr=addr, LK=false}
356            in  case cc of            in  case cc of
# Line 329  Line 360 
360                | (T.LE | T.LEU) => branch(I.FALSE, I.GT)                | (T.LE | T.LEU) => branch(I.FALSE, I.GT)
361                | (T.GE | T.GEU) => branch(I.FALSE, I.LT)                | (T.GE | T.GEU) => branch(I.FALSE, I.LT)
362                | (T.GT | T.GTU) => branch(I.TRUE, I.GT)                | (T.GT | T.GTU) => branch(I.TRUE, I.GT)
363                  | (T.SETCC | T.MISC_COND _) => error "branch(CC)"
364            end            end
365          | branch(cmp as T.FCMP(fty, cond, _, _), lab, an) =          | branch(cmp as T.FCMP(fty, cond, _, _), lab, an) =
366            let val ccreg = if true then CR0 else newCCreg() (* XXX *)            let val ccreg = if true then CR0 else newCCreg() (* XXX *)
367                val labOp = I.LabelOp(LE.LABEL lab)                val labOp = I.LabelOp(T.LABEL lab)
368                fun branch(bo, bf, bit) =                fun branch(bo, bf, bit) =
369                    emitBranch{bo=bo, bf=bf, bit=bit, addr=labOp, LK=false}                    emitBranch{bo=bo, bf=bf, bit=bit, addr=labOp, LK=false}
370                fun test2bits(bit1, bit2) =                fun test2bits(bit1, bit2) =
# Line 358  Line 390 
390                | T.?<= => branch(I.FALSE,  ccreg, I.FG)                | T.?<= => branch(I.FALSE,  ccreg, I.FG)
391                | T.<>  => test2bits(I.FL, I.FG)                | T.<>  => test2bits(I.FL, I.FG)
392                | T.?=  => test2bits(I.FU, I.FE)                | T.?=  => test2bits(I.FU, I.FE)
393                  | (T.SETFCC | T.MISC_FCOND _) => error "branch(FCMP)"
394               (*esac*)               (*esac*)
395            end            end
396          | branch _ = error "branch"          | branch _ = error "branch"
# Line 393  Line 426 
426    
427        and subfImmed(i, ra, rt, an) =        and subfImmed(i, ra, rt, an) =
428            if signed16 i then            if signed16 i then
429               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)
430            else            else
431               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),
432                            Rc=false, OE=false}, an)                            Rc=false, OE=false}, an)
# Line 413  Line 446 
446        (*  Generate an overflow trap *)        (*  Generate an overflow trap *)
447        and overflowTrap() =        and overflowTrap() =
448            let val label = case !trapLabel of            let val label = case !trapLabel of
449                              NONE => let val l = Label.newLabel ""                              NONE => let val l = Label.anon()
450                                      in  trapLabel := SOME l; l end                                      in  trapLabel := SOME l; l end
451                            | SOME l => l                            | SOME l => l
452            in  emitBranch{bo=I.TRUE, bf=CR0, bit=I.SO, LK=false,            in  emitBranch{bo=I.TRUE, bf=CR0, bit=I.SO, LK=false,
453                           addr=I.LabelOp(LE.LABEL label)}                           addr=I.LabelOp(T.LABEL label)}
454            end            end
455    
456        (* Generate a load and annotate the instruction *)        (* Generate a load and annotate the instruction *)
# Line 457  Line 490 
490    
491        (* Generate a subtract operation *)        (* Generate a subtract operation *)
492        and subtract(ty, e1, e2 as T.LI i, rt, an) =        and subtract(ty, e1, e2 as T.LI i, rt, an) =
493              (doExpr(T.ADD(ty, e1, T.LI (~i)), rt, an)              (doExpr(T.ADD(ty, e1, T.LI (T.I.NEGT(32, i))), rt, an)
494                handle Overflow =>                handle Overflow =>
495                mark(I.ARITH{oper=I.SUBF, rt=rt, ra=expr e2,                mark(I.ARITH{oper=I.SUBF, rt=rt, ra=expr e2,
496                             rb=expr e1, OE=false, Rc=false}, an)                             rb=expr e1, OE=false, Rc=false}, an)
497              )              )
498          | 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)
499          | subtract(ty, T.CONST c, e2, rt, an) =          | subtract(ty, x as (T.CONST _ | T.LABEL _), e2, rt, an) =
500               mark(I.ARITHI{oper=I.SUBFIC,rt=rt,ra=expr e2,               mark(I.ARITHI{oper=I.SUBFIC,rt=rt,ra=expr e2,
501                             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)  
502          | subtract(ty, e1, e2, rt, an) =          | subtract(ty, e1, e2, rt, an) =
503            let val rb = expr e1 val ra = expr e2            let val rb = expr e1 val ra = expr e2
504            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 476  Line 507 
507            (* Generate optimized multiplication code *)            (* Generate optimized multiplication code *)
508        and multiply(ty,oper,operi,genMult,e1,e2,rt,an) =        and multiply(ty,oper,operi,genMult,e1,e2,rt,an) =
509            let fun nonconst(e1,e2) =            let fun nonconst(e1,e2) =
510                    [mark'(                    [annotate(
511                       case commImmedOpnd signed16 (e1,e2) of                       case commImmedOpnd signed16 (e1,e2) of
512                         (ra,I.RegOp rb) =>                         (ra,I.RegOp rb) =>
513                           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}
514                       | (ra,im) => I.ARITHI{oper=operi,ra=ra,im=im,rt=rt},                       | (ra,im) => I.arithi{oper=operi,ra=ra,im=im,rt=rt},
515                       an)]                       an)]
516                fun const(e,i) =                fun const(e,i) =
517                    let val r = expr e                    let val r = expr e
518                    in  genMult{r=r,i=i,d=rt}                    in  genMult{r=r,i=toInt(i),d=rt}
519                        handle _ => nonconst(T.REG(ty,r),T.LI i)                        handle _ => nonconst(T.REG(ty,r),T.LI i)
520                    end                    end
               fun constw(e,i) = const(e,Word32.toInt i)  
                                  handle _ => nonconst(e,T.LI32 i)  
521                val instrs =                val instrs =
522                   case (e1,e2) of                   case (e1,e2) of
523                     (_,T.LI i)   => const(e1,i)                     (_,T.LI i)   => const(e1,i)
                  | (_,T.LI32 i) => constw(e1,i)  
524                   | (T.LI i,_)   => const(e2,i)                   | (T.LI i,_)   => const(e2,i)
                  | (T.LI32 i,_) => constw(e2,i)  
525                   | _            => nonconst(e1,e2)                   | _            => nonconst(e1,e2)
526            in  app emit instrs end            in  app emitInstruction instrs end
527    
528        and divu32 x = Mulu32.divide{mode=T.TO_ZERO,stm=doStmt} x        and divu32 x = Mulu32.divide{mode=T.TO_ZERO,stm=doStmt} x
529    
530        and divt32 x = Mult32.divide{mode=T.TO_ZERO,stm=doStmt} x        and divs32 x = Muls32.divide{mode=T.TO_ZERO,stm=doStmt} x
   
       (*  
       and GOTO lab = T.JMP(T.LABEL(LE.LABEL lab), [], [])  
531    
532        and roundToZero{ty,r,i,d} =        and divt32 x = Mult32.divide{mode=T.TO_ZERO,stm=doStmt} x
       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  
        *)  
533    
534            (* Generate optimized division code *)            (* Generate optimized division code *)
535        and divide(ty,oper,genDiv,e1,e2,rt,overflow,an) =        and divide(ty,oper,genDiv,e1,e2,rt,overflow,an) =
# Line 524  Line 540 
540                    )                    )
541                fun const(e,i) =                fun const(e,i) =
542                    let val r = expr e                    let val r = expr e
543                    in  app emit (genDiv{r=r,i=i,d=rt})                    in  app emitInstruction (genDiv{r=r,i=toInt(i),d=rt})
544                        handle _ => nonconst(T.REG(ty,r),T.LI i)                        handle _ => nonconst(T.REG(ty,r),T.LI i)
545                    end                    end
               fun constw(e,i) = const(e,Word32.toInt i)  
                                 handle _ => nonconst(e,T.LI32 i)  
546            in  case (e1,e2) of            in  case (e1,e2) of
547                  (_,T.LI i)   => const(e1,i)                  (_,T.LI i)   => const(e1,i)
               | (_,T.LI32 i) => constw(e1,i)  
548                | _            => nonconst(e1,e2)                | _            => nonconst(e1,e2)
549            end            end
550    
# Line 539  Line 552 
552        and reduceOpn(I.RegOp r) = r        and reduceOpn(I.RegOp r) = r
553          | reduceOpn opn =          | reduceOpn opn =
554            let val rt = newReg()            let val rt = newReg()
555            in  emit(I.ARITHI{oper=I.ADDI, rt=rt, ra=0, im=opn});            in  emit(I.ARITHI{oper=I.ADDI, rt=rt, ra=zeroR, im=opn});
556                rt                rt
557            end            end
558    
559        (* Reduce an expression, and returns the register that holds        (* Reduce an expression, and returns the register that holds
560         * the value.         * the value.
561         *)         *)
562        and expr(rexp as T.REG(_,80)) =        and expr(rexp as T.REG(_,r)) =
563              if CB.sameColor(C.lr, r) then
564            let val rt = newReg()            let val rt = newReg()
565            in  doExpr(rexp, rt, []); rt end            in  doExpr(rexp, rt, []); rt end
566          | expr(T.REG(_,r)) = r            else r
567          | expr(rexp) =          | expr(rexp) =
568            let val rt = newReg()            let val rt = newReg()
569            in  doExpr(rexp, rt, []); rt end            in  doExpr(rexp, rt, []); rt end
# Line 558  Line 572 
572         *    reduce the expression e, assigns it to rd,         *    reduce the expression e, assigns it to rd,
573         *    and annotate the expression with an         *    and annotate the expression with an
574         *)         *)
575        and doExpr(e, 80, an) =        and doExpr(e, rt, an) =
576               if CB.sameColor(rt,C.lr) then
577             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
578          | doExpr(e, rt, an) =             else
579             case e of             case e of
580               T.REG(_,80)  => mark(MFLR rt,an)               T.REG(_,rs)  => if CB.sameColor(rs,C.lr) then mark(MFLR rt,an)
581             | T.REG(_,rs)  => move(rs,rt,an)                               else move(rs,rt,an)
582             | T.LI i       => loadImmed(i, rt, an)             | T.LI i       => loadImmed(i, rt, an)
583             | T.LI32 w     => loadImmedw(w, rt, an)             | T.LABEXP lexp => loadLabexp(lexp, rt, an)
584             | T.LABEL lexp => loadLabel(lexp, rt, an)             | T.CONST _     => loadLabexp(e, rt, an)
585             | T.CONST c    => loadConst(c, rt, an)             | T.LABEL _     => loadLabexp(e, rt, an)
586    
587               (* All data widths *)               (* All data widths *)
588             | 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 577  Line 592 
592             | T.ANDB(_,e1,T.NOTB(_,e2)) => arith(I.ANDC,e1,e2,rt,an)             | T.ANDB(_,e1,T.NOTB(_,e2)) => arith(I.ANDC,e1,e2,rt,an)
593             | T.ORB(_,e1,T.NOTB(_,e2))  => arith(I.ORC,e1,e2,rt,an)             | T.ORB(_,e1,T.NOTB(_,e2))  => arith(I.ORC,e1,e2,rt,an)
594             | T.XORB(_,e1,T.NOTB(_,e2)) => arith(I.EQV,e1,e2,rt,an)             | T.XORB(_,e1,T.NOTB(_,e2)) => arith(I.EQV,e1,e2,rt,an)
595               | T.EQVB(_,e1,e2)           => arith(I.EQV,e1,e2,rt,an)
596             | T.ANDB(_,T.NOTB(_,e1),e2) => arith(I.ANDC,e2,e1,rt,an)             | T.ANDB(_,T.NOTB(_,e1),e2) => arith(I.ANDC,e2,e1,rt,an)
597             | T.ORB(_,T.NOTB(_,e1),e2)  => arith(I.ORC,e2,e1,rt,an)             | T.ORB(_,T.NOTB(_,e1),e2)  => arith(I.ORC,e2,e1,rt,an)
598             | T.XORB(_,T.NOTB(_,e1),e2) => arith(I.EQV,e2,e1,rt,an)             | T.XORB(_,T.NOTB(_,e1),e2) => arith(I.EQV,e2,e1,rt,an)
# Line 593  Line 609 
609             | T.MULU(32, e1, e2) => multiply(32,I.MULLW,I.MULLI,             | T.MULU(32, e1, e2) => multiply(32,I.MULLW,I.MULLI,
610                                              Mulu32.multiply,e1,e2,rt,an)                                              Mulu32.multiply,e1,e2,rt,an)
611             | T.DIVU(32, e1, e2) => divide(32,I.DIVWU,divu32,e1,e2,rt,false,an)             | T.DIVU(32, e1, e2) => divide(32,I.DIVWU,divu32,e1,e2,rt,false,an)
612    
613               | T.MULS(32, e1, e2) => multiply(32,I.MULLW,I.MULLI,
614                                                Muls32.multiply,e1,e2,rt,an)
615               | T.DIVS(T.DIV_TO_ZERO, 32, e1, e2) =>
616                   (* On the PPC we turn overflow checking on despite this
617                    * being DIVS.  That's because divide-by-zero is also
618                    * indicated through "overflow" instead of causing a trap. *)
619                                       divide(32,I.DIVW,divs32,e1,e2,rt,
620                                              true (* !! *),
621                                              an)
622    
623             | T.ADDT(32, e1, e2) => arithTrapping(I.ADD, e1, e2, rt, an)             | T.ADDT(32, e1, e2) => arithTrapping(I.ADD, e1, e2, rt, an)
624             | T.SUBT(32, e1, e2) => arithTrapping(I.SUBF, e2, e1, rt, an)             | T.SUBT(32, e1, e2) => arithTrapping(I.SUBF, e2, e1, rt, an)
625             | T.MULT(32, e1, e2) => arithTrapping(I.MULLW, e1, e2, rt, an)             | T.MULT(32, e1, e2) => arithTrapping(I.MULLW, e1, e2, rt, an)
626             | T.DIVT(32, e1, e2) => divide(32,I.DIVW,divt32,e1,e2,rt,true,an)             | T.DIVT(T.DIV_TO_ZERO, 32, e1, e2) =>
627                                       divide(32,I.DIVW,divt32,e1,e2,rt,true,an)
628    
629             | T.SRA(32, e1, e2)  => sra(I.SRAW, I.SRAWI, e1, e2, rt, an)             | T.SRA(32, e1, e2)  => sra(I.SRAW, I.SRAWI, e1, e2, rt, an)
630             | T.SRL(32, e1, e2)  => srl32(e1, e2, rt, an)             | T.SRL(32, e1, e2)  => srl32(e1, e2, rt, an)
# Line 619  Line 647 
647    
648                (* Misc *)                (* Misc *)
649             | T.LET(s,e) => (doStmt s; doExpr(e, rt, an))             | T.LET(s,e) => (doStmt s; doExpr(e, rt, an))
650             | T.MARK(e, a) =>             | T.MARK(e, A.MARKREG f) => (f rt; doExpr(e,rt,an))
651               (case #peek MLRiscAnnotations.MARK_REG a of             | T.MARK(e, a) => doExpr(e,rt,a::an)
652                 SOME f => (f rt; doExpr(e,rt,an))             | T.REXT e => ExtensionComp.compileRext (reducer()) {e=e,rd=rt,an=an}
              | NONE => doExpr(e,rt,a::an)  
              )  
653             | e => doExpr(Gen.compileRexp e,rt,an)             | e => doExpr(Gen.compileRexp e,rt,an)
654    
655        (* Generate a floating point load *)        (* Generate a floating point load *)
# Line 673  Line 699 
699            | 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)
700            | 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)
701            | 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)
702            | 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)
703            | 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)
704            | 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)
705            | 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)
706    
707            | T.FADD(32, e1, e2) => fbinary(I.FADDS, e1, e2, ft, an)            | T.FADD(32, e1, e2) => fbinary(I.FADDS, e1, e2, ft, an)
708            | 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 690  Line 716 
716            | 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)
717            | 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)
718            | 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)
719            | 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)
720            | 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)
721            | 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)
722            | 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)
723    
724            | T.FADD(64, e1, e2) => fbinary(I.FADD, e1, e2, ft, an)            | T.FADD(64, e1, e2) => fbinary(I.FADD, e1, e2, ft, an)
725            | T.FSUB(64, e1, e2) => fbinary(I.FSUB, e1, e2, ft, an)            | T.FSUB(64, e1, e2) => fbinary(I.FSUB, e1, e2, ft, an)
726            | T.FMUL(64, e1, e2) => fbinary(I.FMUL, e1, e2, ft, an)            | T.FMUL(64, e1, e2) => fbinary(I.FMUL, e1, e2, ft, an)
727            | T.FDIV(64, e1, e2) => fbinary(I.FDIV, e1, e2, ft, an)            | T.FDIV(64, e1, e2) => fbinary(I.FDIV, e1, e2, ft, an)
728            | T.CVTI2F(64,_,e) =>            | T.CVTI2F(64,_,e) =>
729                 app emit (PseudoInstrs.cvti2d{reg=expr e,fd=ft})                 app emitInstruction (PseudoInstrs.cvti2d{reg=expr e,fd=ft})
730    
731              (* Single/double precision support *)              (* Single/double precision support *)
732            | T.FABS((32|64), e) => funary(I.FABS, e, ft, an)            | T.FABS((32|64), e) => funary(I.FABS, e, ft, an)
# Line 708  Line 734 
734            | T.FSQRT(32, e)     => funary(I.FSQRTS, e, ft, an)            | T.FSQRT(32, e)     => funary(I.FSQRTS, e, ft, an)
735            | T.FSQRT(64, e)     => funary(I.FSQRT, e, ft, an)            | T.FSQRT(64, e)     => funary(I.FSQRT, e, ft, an)
736    
737              | T.CVTF2F(64,32,e)  => doFexpr(e,ft,an) (* 32->64 is a no-op *)
738              | T.CVTF2F(32,32,e)  => doFexpr(e,ft,an)
739              | T.CVTF2F(64,64,e)  => doFexpr(e,ft,an)
740              | T.CVTF2F(32,64,e)  => funary(I.FRSP,e,ft,an)
741    
742              (* Misc *)              (* Misc *)
743            | T.FMARK(e, a) =>            | T.FMARK(e, A.MARKREG f) => (f ft; doFexpr(e,ft,an))
744              (case #peek MLRiscAnnotations.MARK_REG a of            | T.FMARK(e, a) => doFexpr(e,ft,a::an)
745                SOME f => (f ft; doFexpr(e,ft,an))            | T.FEXT e => ExtensionComp.compileFext (reducer()) {e=e,fd=ft,an=an}
             | NONE => doFexpr(e,ft,a::an)  
             )  
746            | _ => error "doFexpr"            | _ => error "doFexpr"
747    
748         and ccExpr(T.CC(_,cc)) = cc         and ccExpr(T.CC(_,cc)) = cc
# Line 741  Line 770 
770            | T.FCMP(fty, fcc, e1, e2) =>            | T.FCMP(fty, fcc, e1, e2) =>
771               mark(I.FCOMPARE{cmp=I.FCMPU, bf=ccd, fa=fexpr e1, fb=fexpr e2},an)               mark(I.FCOMPARE{cmp=I.FCMPU, bf=ccd, fa=fexpr e1, fb=fexpr e2},an)
772            | T.CC(_,cc) => ccmove(cc,ccd,an)            | T.CC(_,cc) => ccmove(cc,ccd,an)
773            | T.CCMARK(cc,a) =>            | T.CCMARK(cc,A.MARKREG f) => (f ccd; doCCexpr(cc,ccd,an))
774              (case #peek MLRiscAnnotations.MARK_REG a of            | T.CCMARK(cc,a) => doCCexpr(cc,ccd,a::an)
775                SOME f => (f ccd; doCCexpr(cc,ccd,an))            | T.CCEXT e =>
776              | NONE => doCCexpr(cc,ccd,a::an)              ExtensionComp.compileCCext (reducer()) {e=e, ccd=ccd, an=an}
             )  
777            | _ => error "doCCexpr: Not implemented"            | _ => error "doCCexpr: Not implemented"
778    
779        and emitTrap() = emit(I.TW{to=31,ra=0,si=I.ImmedOp 0})        and emitTrap() = emit(I.TW{to=31,ra=zeroR,si=I.ImmedOp 0})
780    
781          val beginCluster = fn _ => (trapLabel := NONE; beginCluster(0))        and beginCluster _ =
782          val endCluster = fn a =>             (trapLabel := NONE; beginCluster 0)
783    
784          and endCluster a =
785             (case !trapLabel of             (case !trapLabel of
786                SOME label =>                SOME label =>
787                (defineLabel label; emitTrap(); trapLabel := NONE)                (defineLabel label; emitTrap(); trapLabel := NONE)
788              | NONE => ();              | NONE => ();
789             endCluster a)             endCluster a)
790    
791     in  S.STREAM        and reducer() =
792              TS.REDUCER{reduceRexp    = expr,
793                         reduceFexp    = fexpr,
794                         reduceCCexp   = ccExpr,
795                         reduceStm     = stmt,
796                         operand       = (fn _ => error "operand"),
797                         reduceOperand = reduceOpn,
798                         addressOf     = (fn _ => error "addressOf"),
799                         emit          = emitInstruction o annotate,
800                         instrStream   = instrStream,
801                         mltreeStream  = self()
802              }
803           and self() =
804           TS.S.STREAM
805         { beginCluster = beginCluster,         { beginCluster = beginCluster,
806           endCluster   = endCluster,           endCluster   = endCluster,
807           emit         = doStmt,           emit         = doStmt,
# Line 767  Line 810 
810           entryLabel   = entryLabel,           entryLabel   = entryLabel,
811           comment      = comment,           comment      = comment,
812           annotation   = annotation,           annotation   = annotation,
813           exitBlock    = fn mlrisc => exitBlock(cellset mlrisc),           getAnnotations=getAnnotations,
814           alias        = alias,           exitBlock     = fn mlrisc => exitBlock(cellset mlrisc)
          phi          = phi  
815         }         }
816       in  self()
817     end     end
818    
819  end  end

Legend:
Removed from v.717  
changed lines
  Added in v.1722

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