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

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

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

revision 410, Fri Sep 3 00:25:03 1999 UTC revision 429, Wed Sep 8 09:47:00 1999 UTC
# Line 16  Line 16 
16         where type cond = MLTreeBasis.cond         where type cond = MLTreeBasis.cond
17         and   type fcond = MLTreeBasis.fcond         and   type fcond = MLTreeBasis.fcond
18         and   type rounding_mode = MLTreeBasis.rounding_mode         and   type rounding_mode = MLTreeBasis.rounding_mode
     structure Stream : INSTRUCTION_STREAM  
        where B = AlphaMLTree.BNames  
        and   P = AlphaMLTree.PseudoOp  
19      structure PseudoInstrs : ALPHA_PSEUDO_INSTR      structure PseudoInstrs : ALPHA_PSEUDO_INSTR
20         where I = AlphaInstr         where I = AlphaInstr
21    
       (* When this flag is set:  
        * (1) 32 bit loads are always sign extended.  
        *)  
     val mode32bit : bool  
   
       (*  
        * Floating point rounding mode.  
        * When this is set to true, we use the /SU rounding mode  
        * (chopped towards zero) for floating point arithmetic.  
        * This flag is only used to support the old alpha32x backend.  
        *  
        * Otherwise, we use /SUD.  This is the default for SML/NJ.  
        *  
        *)  
     val useSU : bool (* use false for SML/NJ *)  
   
22        (* Cost of multiplication in cycles *)        (* Cost of multiplication in cycles *)
23      val multCost : int ref      val multCost : int ref
24    
# Line 46  Line 27 
27     ) : MLTREECOMP =     ) : MLTREECOMP =
28  struct  struct
29    
   structure S   = Stream  
30    structure T   = AlphaMLTree    structure T   = AlphaMLTree
31      structure S   = T.Stream
32    structure R   = AlphaMLTree.Region    structure R   = AlphaMLTree.Region
33    structure I   = AlphaInstr    structure I   = AlphaInstr
34    structure C   = AlphaInstr.C    structure C   = AlphaInstr.C
35    structure LE  = LabelExp    structure LE  = LabelExp
36    structure W32 = Word32    structure W32 = Word32
37    structure U   = MLTreeUtil    structure U   = MLTreeUtil
38      structure P   = PseudoInstrs
39    
40   (*********************************************************   (*********************************************************
41    
# Line 161  Line 143 
143    structure Gen = MLTreeGen(structure T = T    structure Gen = MLTreeGen(structure T = T
144                              val intTy = 64                              val intTy = 64
145                              val naturalWidths = [32,64]                              val naturalWidths = [32,64]
146                                datatype rep = SE | ZE | NEITHER
147                                val rep = SE
148                             )                             )
149    
150    val zeroR   = C.GPReg 31    val zeroR   = C.GPReg 31
# Line 177  Line 161 
161    
162       val intTy = 32       val intTy = 32
163    
164       type arg  = {r1:C.register,r2:C.register,d:C.register}       type arg  = {r1:C.cell,r2:C.cell,d:C.cell}
165       type argi = {r:C.register,i:int,d:C.register}       type argi = {r:C.cell,i:int,d:C.cell}
166    
167       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}
168       fun add{r1,r2,d} = I.OPERATE{oper=I.ADDL,ra=r1,rb=I.REGop r2,rc=d}       fun add{r1,r2,d} = I.OPERATE{oper=I.ADDL,ra=r1,rb=I.REGop r2,rc=d}
# Line 219  Line 203 
203    
204       val intTy = 64       val intTy = 64
205    
206       type arg  = {r1:C.register,r2:C.register,d:C.register}       type arg  = {r1:C.cell,r2:C.cell,d:C.cell}
207       type argi = {r:C.register,i:int,d:C.register}       type argi = {r:C.cell,i:int,d:C.cell}
208    
209       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}
210       fun add{r1,r2,d}= I.OPERATE{oper=I.ADDQ,ra=r1,rb=I.REGop r2,rc=d}       fun add{r1,r2,d}= I.OPERATE{oper=I.ADDQ,ra=r1,rb=I.REGop r2,rc=d}
# Line 232  Line 216 
216    (* signed, trapping version of multiply and divide *)    (* signed, trapping version of multiply and divide *)
217    structure Mult32 = Multiply32    structure Mult32 = Multiply32
218      (val trapping = true      (val trapping = true
      val signed = true  
219       val multCost = multCost       val multCost = multCost
220       fun addv{r1,r2,d} = [I.OPERATEV{oper=I.ADDLV,ra=r1,rb=I.REGop r2,rc=d}]       fun addv{r1,r2,d} = [I.OPERATEV{oper=I.ADDLV,ra=r1,rb=I.REGop r2,rc=d}]
221       fun subv{r1,r2,d} = [I.OPERATEV{oper=I.SUBLV,ra=r1,rb=I.REGop r2,rc=d}]       fun subv{r1,r2,d} = [I.OPERATEV{oper=I.SUBLV,ra=r1,rb=I.REGop r2,rc=d}]
# Line 240  Line 223 
223       val sh2addv = NONE       val sh2addv = NONE
224       val sh3addv = NONE       val sh3addv = NONE
225      )      )
226        (val signed = true)
227    
228    (* unsigned, non-trapping version of multiply and divide *)    (* non-trapping version of multiply and divide *)
229    structure Mulu32 = Multiply32    functor Mul32 = Multiply32
230      (val trapping = false      (val trapping = false
      val signed = false  
231       val multCost = multCost       val multCost = multCost
232       fun addv{r1,r2,d} = [I.OPERATE{oper=I.ADDL,ra=r1,rb=I.REGop r2,rc=d}]       fun addv{r1,r2,d} = [I.OPERATE{oper=I.ADDL,ra=r1,rb=I.REGop r2,rc=d}]
233       fun subv{r1,r2,d} = [I.OPERATE{oper=I.SUBL,ra=r1,rb=I.REGop r2,rc=d}]       fun subv{r1,r2,d} = [I.OPERATE{oper=I.SUBL,ra=r1,rb=I.REGop r2,rc=d}]
# Line 254  Line 237 
237       val sh3addv = SOME(fn {r1,r2,d} =>       val sh3addv = SOME(fn {r1,r2,d} =>
238                      [I.OPERATE{oper=I.S8ADDL,ra=r1,rb=I.REGop r2,rc=d}])                      [I.OPERATE{oper=I.S8ADDL,ra=r1,rb=I.REGop r2,rc=d}])
239      )      )
240      structure Mulu32 = Mul32(val signed = false)
241      structure Muls32 = Mul32(val signed = true)
242    
243    (* signed, trapping version of multiply and divide *)    (* signed, trapping version of multiply and divide *)
244    structure Mult64 = Multiply64    structure Mult64 = Multiply64
245      (val trapping = true      (val trapping = true
      val signed = true  
246       val multCost = multCost       val multCost = multCost
247       fun addv{r1,r2,d} = [I.OPERATEV{oper=I.ADDQV,ra=r1,rb=I.REGop r2,rc=d}]       fun addv{r1,r2,d} = [I.OPERATEV{oper=I.ADDQV,ra=r1,rb=I.REGop r2,rc=d}]
248       fun subv{r1,r2,d} = [I.OPERATEV{oper=I.SUBQV,ra=r1,rb=I.REGop r2,rc=d}]       fun subv{r1,r2,d} = [I.OPERATEV{oper=I.SUBQV,ra=r1,rb=I.REGop r2,rc=d}]
# Line 266  Line 250 
250       val sh2addv = NONE       val sh2addv = NONE
251       val sh3addv = NONE       val sh3addv = NONE
252      )      )
253        (val signed = true)
254    
255    (* unsigned, non-trapping version of multiply and divide *)    (* unsigned, non-trapping version of multiply and divide *)
256    structure Mulu64 = Multiply64    functor Mul64 = Multiply64
257      (val trapping = false      (val trapping = false
      val signed = false  
258       val multCost = multCost       val multCost = multCost
259       fun addv{r1,r2,d} = [I.OPERATE{oper=I.ADDQ,ra=r1,rb=I.REGop r2,rc=d}]       fun addv{r1,r2,d} = [I.OPERATE{oper=I.ADDQ,ra=r1,rb=I.REGop r2,rc=d}]
260       fun subv{r1,r2,d} = [I.OPERATE{oper=I.SUBQ,ra=r1,rb=I.REGop r2,rc=d}]       fun subv{r1,r2,d} = [I.OPERATE{oper=I.SUBQ,ra=r1,rb=I.REGop r2,rc=d}]
# Line 280  Line 264 
264       val sh3addv = SOME(fn {r1,r2,d} =>       val sh3addv = SOME(fn {r1,r2,d} =>
265                      [I.OPERATE{oper=I.S8ADDQ,ra=r1,rb=I.REGop r2,rc=d}])                      [I.OPERATE{oper=I.S8ADDQ,ra=r1,rb=I.REGop r2,rc=d}])
266      )      )
267      structure Mulu64 = Mul64(val signed = false)
268      structure Muls64 = Mul64(val signed = true)
269    
270    (*    (*
271     * The main stuff     * The main stuff
# Line 292  Line 278 
278    datatype commutative = COMMUTE | NOCOMMUTE    datatype commutative = COMMUTE | NOCOMMUTE
279    
280    fun selectInstructions    fun selectInstructions
281          (S.STREAM{emit,init,finish,defineLabel,entryLabel,pseudoOp,annotation,          (S.STREAM{emit,beginCluster,endCluster,
282                    blockName,exitBlock,...}) =                    defineLabel,entryLabel,pseudoOp,annotation,
283                      blockName,exitBlock,phi,alias,comment,...}) =
284    let    let
285        infix || && << >> ~>>        infix || && << >> ~>>
286    
# Line 312  Line 299 
299    
300        val newReg = C.newReg        val newReg = C.newReg
301        val newFreg = C.newFreg        val newFreg = C.newFreg
       val emit = emit (fn _ => 0)  
302    
303        val trapb = [I.TRAPB]        val trapb = [I.TRAPB]
304    
305        (* Choose the appropriate rounding mode to generate.        (* Choose the appropriate rounding mode to generate.
306         * This stuff is used to support the alpha32x SML/NJ backend.         * This stuff is used to support the alpha32x SML/NJ backend.
307           *
308           *
309           * Floating point rounding mode.
310           * When this is set to true, we use the /SU rounding mode
311           * (chopped towards zero) for floating point arithmetic.
312           * This flag is only used to support the old alpha32x backend.
313           *
314           * Otherwise, we use /SUD.  This is the default for SML/NJ.
315           *
316         *)         *)
317          val useSU = false
318        val (ADDT,SUBT,MULT,DIVT) =        val (ADDT,SUBT,MULT,DIVT) =
319             if useSU then (I.ADDTSU,I.SUBTSU,I.MULTSU,I.DIVTSU)             if useSU then (I.ADDTSU,I.SUBTSU,I.MULTSU,I.DIVTSU)
320             else          (I.ADDTSUD,I.SUBTSUD,I.MULTSUD,I.DIVTSUD)             else          (I.ADDTSUD,I.SUBTSUD,I.MULTSUD,I.DIVTSUD)
# Line 571  Line 567 
567                (TIMES4,a) => arith(s4sub,a,b,d,an)                (TIMES4,a) => arith(s4sub,a,b,d,an)
568             |  (TIMES8,a) => arith(s8sub,a,b,d,an)             |  (TIMES8,a) => arith(s8sub,a,b,d,an)
569             |  _          =>             |  _          =>
570                  if ty = 64 then
571                (case b of                (case b of
572                   (* use LDA to handle subtraction when possible                   (* use LDA to handle subtraction when possible
573                    * Note: this may have sign extension problems later.                    * Note: this may have sign extension problems later.
# Line 578  Line 575 
575                   T.LI i => (loadImmed(~i,expr a,d,an) handle Overflow =>                   T.LI i => (loadImmed(~i,expr a,d,an) handle Overflow =>
576                                arith(sub,a,b,d,an))                                arith(sub,a,b,d,an))
577                |  _ => arith(sub,a,b,d,an)                |  _ => arith(sub,a,b,d,an)
578                )                ) else arith(sub,a,b,d,an)
579            )            )
580    
581        (* look for special constants *)        (* look for special constants *)
# Line 586  Line 583 
583          | wordOpn(T.LI32 w) = SOME w          | wordOpn(T.LI32 w) = SOME w
584          | wordOpn e = NONE          | wordOpn e = NONE
585    
586        (* look for special byte mask constants *)        (* look for special byte mask constants
587        and byteMask(_,SOME 0wx00000000) = SOME 0xff         * IMPORTANT: we must ALWAYS keep the sign bit!
588          | byteMask(_,SOME 0wx000000ff) = SOME 0xfe         *)
589          | byteMask(_,SOME 0wx0000ff00) = SOME 0xfd        and byteMask(_,SOME 0wx00000000) = 0xff
590          | byteMask(_,SOME 0wx0000ffff) = SOME 0xfc          | byteMask(_,SOME 0wx000000ff) = 0xfe
591          | byteMask(_,SOME 0wx00ff0000) = SOME 0xfb          | byteMask(_,SOME 0wx0000ff00) = 0xfd
592          | byteMask(_,SOME 0wx00ff00ff) = SOME 0xfa          | byteMask(_,SOME 0wx0000ffff) = 0xfc
593          | byteMask(_,SOME 0wx00ffff00) = SOME 0xf9          | byteMask(_,SOME 0wx00ff0000) = 0xfb
594          | byteMask(_,SOME 0wx00ffffff) = SOME 0xf8          | byteMask(_,SOME 0wx00ff00ff) = 0xfa
595            (* IMPORTANT:          | byteMask(_,SOME 0wx00ffff00) = 0xf9
596             * When ty is 64 then we assume the top 32 bits are all zeros.          | byteMask(_,SOME 0wx00ffffff) = 0xf8
597             * Otherwise, we must keep the sign bit!!!!          | byteMask(ty,SOME 0wxff000000) = if ty = 64 then 0xf7 else 0x07
598             *)          | byteMask(ty,SOME 0wxff0000ff) = if ty = 64 then 0xf6 else 0x06
599          | byteMask(ty,SOME 0wxff000000) = SOME(if ty = 64 then 0xf7 else 0x07)          | byteMask(ty,SOME 0wxff00ff00) = if ty = 64 then 0xf5 else 0x05
600          | byteMask(ty,SOME 0wxff0000ff) = SOME(if ty = 64 then 0xf6 else 0x06)          | byteMask(ty,SOME 0wxff00ffff) = if ty = 64 then 0xf4 else 0x04
601          | byteMask(ty,SOME 0wxff00ff00) = SOME(if ty = 64 then 0xf5 else 0x05)          | byteMask(ty,SOME 0wxffff0000) = if ty = 64 then 0xf3 else 0x03
602          | byteMask(ty,SOME 0wxff00ffff) = SOME(if ty = 64 then 0xf4 else 0x04)          | byteMask(ty,SOME 0wxffff00ff) = if ty = 64 then 0xf2 else 0x02
603          | byteMask(ty,SOME 0wxffff0000) = SOME(if ty = 64 then 0xf3 else 0x03)          | byteMask(ty,SOME 0wxffffff00) = if ty = 64 then 0xf1 else 0x01
604          | byteMask(ty,SOME 0wxffff00ff) = SOME(if ty = 64 then 0xf2 else 0x02)          | byteMask(ty,SOME 0wxffffffff) = if ty = 64 then 0xf0 else 0x00
605          | byteMask(ty,SOME 0wxffffff00) = SOME(if ty = 64 then 0xf1 else 0x01)          | byteMask _ = ~1
         | byteMask(ty,SOME 0wxffffffff) = SOME(if ty = 64 then 0xf0 else 0x00)  
         | byteMask _ = NONE  
606    
607        (* generate an and instruction        (* generate an and instruction
608         * look for special masks.         * look for special masks.
609         *)         *)
610        and andb(ty,a,b,d,an) =        and andb(ty,a,b,d,an) =
611            case byteMask(ty,wordOpn a) of            case byteMask(ty,wordOpn a) of
612               SOME mask => arith(I.ZAP,b,T.LI mask,d,an)              ~1 => (case byteMask(ty,wordOpn b) of
613            |  _ =>                      ~1 => commArith(I.AND,a,b,d,an)
614            case byteMask(ty,wordOpn b) of                    | mask => arith(I.ZAP,a,T.LI mask,d,an)
615               SOME mask => arith(I.ZAP,a,T.LI mask,d,an)                    )
616            | _ => commArith(I.AND,a,b,d,an)            | mask => arith(I.ZAP,b,T.LI mask,d,an)
617    
618        (* generate sll/sra/srl *)        (* generate sll/sra/srl *)
619        and sll32(a,b,d,an) =        and sll32(a,b,d,an) =
# Line 822  Line 817 
817        (* generate a load 16 bit with sign extension *)        (* generate a load 16 bit with sign extension *)
818        and load16s(ea,rd,mem,an) = loadSext(ea,rd,mem,2,I.EXTQH,48,an)        and load16s(ea,rd,mem,an) = loadSext(ea,rd,mem,2,I.EXTQH,48,an)
819    
       (* generate a load 32 bit with zero extension *)  
       and load32(ea,rd,mem,an) =  
           if mode32bit then load(I.LDL,ea,rd,mem,an)  
           else let val (base,disp) = addr ea  
                    val tmp   = newReg()  
                in  mark(I.LOAD{ldOp=I.LDL,r=tmp,b=base,d=disp,mem=mem},an);  
                    emit(I.OPERATE{oper=I.ZAP,ra=tmp,rb=I.IMMop 0xf0,rc=rd})  
                end  
   
820        (* generate a load 32 bit with sign extension *)        (* generate a load 32 bit with sign extension *)
821        and load32s(ea,rd,mem,an) = load(I.LDL,ea,rd,mem,an)        and load32s(ea,rd,mem,an) = load(I.LDL,ea,rd,mem,an)
822    
# Line 868  Line 854 
854        and store16(ea,data,mem,an) =        and store16(ea,data,mem,an) =
855            storeUnaligned(ea,data,mem,I.INSWL,I.MSKWL,an)            storeUnaligned(ea,data,mem,I.INSWL,I.MSKWL,an)
856    
857          (* generate conversion from floating point to integer *)
858          and cvtf2i(pseudo,rounding,e,rd,an) =
859              app emit (pseudo{mode=rounding, fs=fexpr e, rd=rd})
860    
861        (* generate an expression and return the register that holds the result *)        (* generate an expression and return the register that holds the result *)
862        and expr(T.REG(_,r)) = r        and expr(T.REG(_,r)) = r
863          | expr(T.LI 0) = zeroR          | expr(T.LI 0) = zeroR
# Line 876  Line 866 
866                     in  doExpr(e,r,[]); r end                     in  doExpr(e,r,[]); r end
867    
868        (* generate an expression that targets register d *)        (* generate an expression that targets register d *)
869        and doExpr(e,d,an) =        and doExpr(exp,d,an) =
870            case e of            case exp of
871              T.REG(_,r) => move(r,d,an)              T.REG(_,r) => move(r,d,an)
872            | T.LI n     => loadImmed(n,zeroR,d,an)            | T.LI n     => loadImmed(n,zeroR,d,an)
873            | T.LI32 w   => loadImmed32(w,zeroR,d,an)            | T.LI32 w   => loadImmed32(w,zeroR,d,an)
# Line 888  Line 878 
878               * Question: using LDA for all widths is not really correct               * Question: using LDA for all widths is not really correct
879               * since the result may not fit into the sign extension scheme.               * since the result may not fit into the sign extension scheme.
880               *)               *)
881            | T.ADD(_,e,T.LABEL le) => mark(I.LDA{r=d,b=expr e,d=I.LABop le},an)            | T.ADD(64,e,T.LABEL le) => mark(I.LDA{r=d,b=expr e,d=I.LABop le},an)
882            | T.ADD(_,T.LABEL le,e) => mark(I.LDA{r=d,b=expr e,d=I.LABop le},an)            | T.ADD(64,T.LABEL le,e) => mark(I.LDA{r=d,b=expr e,d=I.LABop le},an)
883            | T.ADD(_,e,T.CONST c)  => mark(I.LDA{r=d,b=expr e,d=I.CONSTop c},an)            | T.ADD(64,e,T.CONST c)  => mark(I.LDA{r=d,b=expr e,d=I.CONSTop c},an)
884            | T.ADD(_,T.CONST c,e)  => mark(I.LDA{r=d,b=expr e,d=I.CONSTop c},an)            | T.ADD(64,T.CONST c,e)  => mark(I.LDA{r=d,b=expr e,d=I.CONSTop c},an)
885            | T.ADD(_,e,T.LI i)     => loadImmed(i, expr e, d, an)            | T.ADD(64,e,T.LI i)     => loadImmed(i, expr e, d, an)
886            | T.ADD(_,T.LI i,e)     => loadImmed(i, expr e, d, an)            | T.ADD(64,T.LI i,e)     => loadImmed(i, expr e, d, an)
887            | T.ADD(_,e,T.LI32 i)   => loadImmed32(i, expr e, d, an)            | T.ADD(64,e,T.LI32 i)   => loadImmed32(i, expr e, d, an)
888            | T.ADD(_,T.LI32 i,e)   => loadImmed32(i, expr e, d, an)            | T.ADD(64,T.LI32 i,e)   => loadImmed32(i, expr e, d, an)
889            | T.SUB(_,a,(T.LI 0 | T.LI32 0w0)) => doExpr(a,d,an)            | T.SUB(_,a,(T.LI 0 | T.LI32 0w0)) => doExpr(a,d,an)
890    
891              (* 32-bit support *)              (* 32-bit support *)
# Line 903  Line 893 
893            | T.SUB(32,a,b) => minus(32,I.SUBL,I.S4SUBL,I.S8SUBL,a,b,d,an)            | T.SUB(32,a,b) => minus(32,I.SUBL,I.S4SUBL,I.S8SUBL,a,b,d,an)
894            | T.ADDT(32,a,b) => commArithTrap(I.ADDLV,a,b,d,an)            | T.ADDT(32,a,b) => commArithTrap(I.ADDLV,a,b,d,an)
895            | T.SUBT(32,a,b) => arithTrap(I.SUBLV,a,b,d,an)            | T.SUBT(32,a,b) => arithTrap(I.SUBLV,a,b,d,an)
896            | T.MULT(32,a,b) => (* multTrap(I.MULLV,I.ADDL,I.ADDLV,a,b,d,an) *)            | T.MULT(32,a,b) =>
897                 multiply(32,                 multiply(32,
898                   fn{ra,rb,rc} => I.OPERATEV{oper=I.MULLV,ra=ra,rb=rb,rc=rc},                   fn{ra,rb,rc} => I.OPERATEV{oper=I.MULLV,ra=ra,rb=rb,rc=rc},
899                   Mult32.multiply,a,b,d,trapb,an)                   Mult32.multiply,a,b,d,trapb,an)
900            | T.MULU(32,a,b) => (* mulu(I.MULL,I.ADDL,a,b,d,an) *)            | T.MULU(32,a,b) =>
901                 multiply(32,                 multiply(32,
902                   fn{ra,rb,rc} => I.OPERATE{oper=I.MULL,ra=ra,rb=rb,rc=rc},                   fn{ra,rb,rc} => I.OPERATE{oper=I.MULL,ra=ra,rb=rb,rc=rc},
903                   Mulu32.multiply,a,b,d,[],an)                   Mulu32.multiply,a,b,d,[],an)
904            | T.DIVT(32,a,b) => (* pseudo(PseudoInstrs.divl,a,b,d) *)            | T.MULS(32,a,b) =>
905                 divide(32,PseudoInstrs.divl,Mult32.divide,a,b,d,an)                 multiply(32,
906            | T.DIVU(32,a,b) => (* pseudo(PseudoInstrs.divlu,a,b,d) *)                   fn{ra,rb,rc} => I.OPERATE{oper=I.MULL,ra=ra,rb=rb,rc=rc},
907                 divide(32,PseudoInstrs.divlu,Mulu32.divide,a,b,d,an)                   Muls32.multiply,a,b,d,[],an)
908              | T.DIVT(32,a,b) => divide(32,P.divlv,Mult32.divide,a,b,d,an)
909              | T.DIVU(32,a,b) => divide(32,P.divlu,Mulu32.divide,a,b,d,an)
910              | T.DIVS(32,a,b) => divide(32,P.divl,Muls32.divide,a,b,d,an)
911              | T.REMT(32,a,b) => pseudo(P.remlv,a,b,d)
912              | T.REMU(32,a,b) => pseudo(P.remlu,a,b,d)
913              | T.REMS(32,a,b) => pseudo(P.reml,a,b,d)
914    
915            | T.SLL(32,a,b) => sll32(a,b,d,an)            | T.SLL(32,a,b) => sll32(a,b,d,an)
916            | T.SRA(32,a,b) => sra32(a,b,d,an)            | T.SRA(32,a,b) => sra32(a,b,d,an)
917            | T.SRL(32,a,b) => srl32(a,b,d,an)            | T.SRL(32,a,b) => srl32(a,b,d,an)
# Line 924  Line 921 
921            | T.SUB(64,a,b) => minus(64,I.SUBQ,I.S4SUBQ,I.S8SUBQ,a,b,d,an)            | T.SUB(64,a,b) => minus(64,I.SUBQ,I.S4SUBQ,I.S8SUBQ,a,b,d,an)
922            | T.ADDT(64,a,b) => commArithTrap(I.ADDQV,a,b,d,an)            | T.ADDT(64,a,b) => commArithTrap(I.ADDQV,a,b,d,an)
923            | T.SUBT(64,a,b) => arithTrap(I.SUBQV,a,b,d,an)            | T.SUBT(64,a,b) => arithTrap(I.SUBQV,a,b,d,an)
924            | T.MULT(64,a,b) => (* multTrap(I.MULQV,I.ADDQ,I.ADDQV,a,b,d,an) *)            | T.MULT(64,a,b) =>
925                 multiply(64,                 multiply(64,
926                   fn{ra,rb,rc} => I.OPERATEV{oper=I.MULQV,ra=ra,rb=rb,rc=rc},                   fn{ra,rb,rc} => I.OPERATEV{oper=I.MULQV,ra=ra,rb=rb,rc=rc},
927                   Mult64.multiply,a,b,d,trapb,an)                   Mult64.multiply,a,b,d,trapb,an)
928            | T.MULU(64,a,b) => (* mulu(I.MULQ,I.ADDQ,a,b,d,an) *)            | T.MULU(64,a,b) =>
929                 multiply(64,                 multiply(64,
930                   fn{ra,rb,rc} => I.OPERATE{oper=I.MULQ,ra=ra,rb=rb,rc=rc},                   fn{ra,rb,rc} => I.OPERATE{oper=I.MULQ,ra=ra,rb=rb,rc=rc},
931                   Mulu64.multiply,a,b,d,[],an)                   Mulu64.multiply,a,b,d,[],an)
932            | T.DIVT(64,a,b) => (* pseudo(PseudoInstrs.divq,a,b,d) *)            | T.MULS(64,a,b) =>
933                 divide(64,PseudoInstrs.divq,Mult64.divide,a,b,d,an)                 multiply(64,
934            | T.DIVU(64,a,b) => (* pseudo(PseudoInstrs.divqu,a,b,d) *)                   fn{ra,rb,rc} => I.OPERATE{oper=I.MULQ,ra=ra,rb=rb,rc=rc},
935                 divide(64,PseudoInstrs.divqu,Mulu64.divide,a,b,d,an)                   Muls64.multiply,a,b,d,[],an)
936              | T.DIVT(64,a,b) => divide(64,P.divqv,Mult64.divide,a,b,d,an)
937              | T.DIVU(64,a,b) => divide(64,P.divqu,Mulu64.divide,a,b,d,an)
938              | T.DIVS(64,a,b) => divide(64,P.divq,Muls64.divide,a,b,d,an)
939              | T.REMT(64,a,b) => pseudo(P.remqv,a,b,d)
940              | T.REMU(64,a,b) => pseudo(P.remqu,a,b,d)
941              | T.REMS(64,a,b) => pseudo(P.remq,a,b,d)
942    
943            | T.SLL(64,a,b) => sll64(a,b,d,an)            | T.SLL(64,a,b) => sll64(a,b,d,an)
944            | T.SRA(64,a,b) => sra64(a,b,d,an)            | T.SRA(64,a,b) => sra64(a,b,d,an)
945            | T.SRL(64,a,b) => srl64(a,b,d,an)            | T.SRL(64,a,b) => srl64(a,b,d,an)
# Line 955  Line 959 
959            | T.ORB(_,a,b) => commArith(I.BIS,a,b,d,an)            | T.ORB(_,a,b) => commArith(I.BIS,a,b,d,an)
960            | T.NOTB(_,e) => arith(I.ORNOT,zeroT,e,d,an)            | T.NOTB(_,e) => arith(I.ORNOT,zeroT,e,d,an)
961    
           | T.CVTI2I(_,T.ZERO_EXTEND,e) => doExpr(e,d,an)  
   
962              (* loads *)              (* loads *)
963            | T.CVTI2I(_,T.SIGN_EXTEND,T.LOAD(8,ea,mem)) => load8s(ea,d,mem,an)            | T.CVTI2I(_,T.SIGN_EXTEND,T.LOAD(8,ea,mem)) => load8s(ea,d,mem,an)
964            | T.CVTI2I(_,T.SIGN_EXTEND,T.LOAD(16,ea,mem)) => load16s(ea,d,mem,an)            | T.CVTI2I(_,T.SIGN_EXTEND,T.LOAD(16,ea,mem)) => load16s(ea,d,mem,an)
965            | T.CVTI2I(_,T.SIGN_EXTEND,T.LOAD(32,ea,mem)) => load32s(ea,d,mem,an)            | T.CVTI2I(_,T.SIGN_EXTEND,T.LOAD(32,ea,mem)) => load32s(ea,d,mem,an)
966            | T.LOAD(8,ea,mem) => load8(ea,d,mem,an)            | T.LOAD(8,ea,mem) => load8(ea,d,mem,an)
967            | T.LOAD(16,ea,mem) => load16(ea,d,mem,an)            | T.LOAD(16,ea,mem) => load16(ea,d,mem,an)
968            | T.LOAD(32,ea,mem) => load32(ea,d,mem,an)            | T.LOAD(32,ea,mem) => load32s(ea,d,mem,an)
969            | T.LOAD(64,ea,mem) => load(I.LDQ,ea,d,mem,an)            | T.LOAD(64,ea,mem) => load(I.LDQ,ea,d,mem,an)
970    
971               (* floating -> int conversion *)
972              | T.CVTF2I(ty,rounding,e) =>
973                (case (Gen.fsize e,ty) of
974                   (32,32) => cvtf2i(P.cvtsl,rounding,e,d,an)
975                 | (32,64) => cvtf2i(P.cvtsq,rounding,e,d,an)
976                 | (64,32) => cvtf2i(P.cvttl,rounding,e,d,an)
977                 | (64,64) => cvtf2i(P.cvttq,rounding,e,d,an)
978                 | _       => doExpr(Gen.compile exp,d,an) (* other cases *)
979                )
980    
981             (* conversion to boolean *)             (* conversion to boolean *)
982            | T.COND(_,T.CMP(ty,cond,e1,e2),T.LI 1,T.LI 0) =>            | T.COND(_,T.CMP(ty,cond,e1,e2),T.LI 1,T.LI 0) =>
983                 compare(ty,cond,e1,e2,d,an)                 compare(ty,cond,e1,e2,d,an)
# Line 976  Line 988 
988    
989            | T.SEQ(s,e) => (doStmt s; doExpr(e,d,an))            | T.SEQ(s,e) => (doStmt s; doExpr(e,d,an))
990            | T.MARK(e,a) => doExpr(e,d,a::an)            | T.MARK(e,a) => doExpr(e,d,a::an)
991    
992               (* Defaults *)
993            | e => doExpr(Gen.compile e,d,an)            | e => doExpr(Gen.compile e,d,an)
994    
995         (* Hmmm...  this is the funky thing described in the comments         (* Hmmm...  this is the funky thing described in the comments
# Line 990  Line 1004 
1004                emit(I.TRAPB)                emit(I.TRAPB)
1005            end            end
1006    
1007          and funary(opcode,e,d,an) = mark(I.FUNARY{oper=opcode,fb=fexpr e,fc=d},an)
1008    
1009    
1010        (* generate an floating point expression        (* generate an floating point expression
1011         * return the register that holds the result         * return the register that holds the result
1012         *)         *)
# Line 997  Line 1014 
1014          | fexpr e = let val d = newFreg() in doFexpr(e,d,[]); d end          | fexpr e = let val d = newFreg() in doFexpr(e,d,[]); d end
1015    
1016        (* generate an external floating point operation *)        (* generate an external floating point operation *)
1017        and fcvti2f(gen,e,fd,an) =        and fcvti2f(pseudo,e,fd,an) =
1018            let val opnd = opn e            let val opnd = opn e
1019            in  app emit (gen({opnd=opnd, fd=fd}, reduceOpn))            in  app emit (pseudo({opnd=opnd, fd=fd}, reduceOpn))
1020            end            end
1021    
1022        (* generate a floating point store *)        (* generate a floating point store *)
# Line 1018  Line 1035 
1035            | T.FSUB(32,a,b) => farith(SUBS,a,b,d,an)            | T.FSUB(32,a,b) => farith(SUBS,a,b,d,an)
1036            | T.FMUL(32,a,b) => farith(MULS,a,b,d,an)            | T.FMUL(32,a,b) => farith(MULS,a,b,d,an)
1037            | T.FDIV(32,a,b) => farith(DIVS,a,b,d,an)            | T.FDIV(32,a,b) => farith(DIVS,a,b,d,an)
           | T.CVTI2F(32,_,e) => fcvti2f(PseudoInstrs.cvti2s,e,d,an)  
1038    
1039              (* double precision support *)              (* double precision support *)
1040            | T.FADD(64,a,b) => farith(ADDT,a,b,d,an)            | T.FADD(64,a,b) => farith(ADDT,a,b,d,an)
1041            | T.FSUB(64,a,b) => farith(SUBT,a,b,d,an)            | T.FSUB(64,a,b) => farith(SUBT,a,b,d,an)
1042            | T.FMUL(64,a,b) => farith(MULT,a,b,d,an)            | T.FMUL(64,a,b) => farith(MULT,a,b,d,an)
1043            | T.FDIV(64,a,b) => farith(DIVT,a,b,d,an)            | T.FDIV(64,a,b) => farith(DIVT,a,b,d,an)
1044            | T.CVTI2F(64,_,e) => fcvti2f(PseudoInstrs.cvti2d,e,d,an)  
1045    
1046              (* generic *)              (* generic *)
1047            | T.FABS(_,a)   =>            | T.FABS(_,a)   =>
# Line 1039  Line 1055 
1055            | T.FLOAD(32,ea,mem) => fload(I.LDS,ea,d,mem,an)            | T.FLOAD(32,ea,mem) => fload(I.LDS,ea,d,mem,an)
1056            | T.FLOAD(64,ea,mem) => fload(I.LDT,ea,d,mem,an)            | T.FLOAD(64,ea,mem) => fload(I.LDT,ea,d,mem,an)
1057    
1058                (* floating/floating conversion
1059                 * Note: it is not necessary to convert single precision
1060                 * to double on the alpha.
1061                 *)
1062              | T.CVTF2F(fty,_,e) => (* ignore rounding mode for now *)
1063                (case (fty,Gen.fsize e) of
1064                   (64,64) => doFexpr(e,d,an)
1065                 | (64,32) => doFexpr(e,d,an)
1066                 | (32,32) => doFexpr(e,d,an)
1067                 | (32,64) => funary(I.CVTTS,e,d,an) (* use normal rounding *)
1068                 | _       => error "CVTF2F"
1069                )
1070    
1071                (* integer -> floating point conversion *)
1072              | T.CVTI2F(fty,T.SIGN_EXTEND,e) =>
1073                let val pseudo =
1074                    case (Gen.size e,fty) of
1075                      (ty,32) => if ty <= 32 then P.cvtls else P.cvtqs
1076                    | (ty,64) => if ty <= 32 then P.cvtlt else P.cvtqt
1077                    | _       => error "CVTI2F"
1078                in  fcvti2f(pseudo,e,d,an) end
1079    
1080              (* misc *)              (* misc *)
1081            | T.FSEQ(s,e) => (doStmt s; doFexpr(e,d,an))            | T.FSEQ(s,e) => (doStmt s; doFexpr(e,d,an))
1082            | T.FMARK(e,a) => doFexpr(e,d,a::an)            | T.FMARK(e,a) => doFexpr(e,d,a::an)
# Line 1333  Line 1371 
1371    
1372        and doStmt s = stmt(s,[])        and doStmt s = stmt(s,[])
1373    
1374        fun mltreeComp mltree =        (* condition code registers are mapped onto general registers *)
       let (* condition code registers are mapped onto general registers *)  
1375            fun cc(T.CCR(T.CC cc)) = T.GPR(T.REG(32,cc))            fun cc(T.CCR(T.CC cc)) = T.GPR(T.REG(32,cc))
1376              | cc r = r              | cc r = r
1377            fun comp(T.PSEUDO_OP pOp)    = pseudoOp pOp  
1378              | comp(T.DEFINELABEL lab)  = defineLabel lab     in S.STREAM
1379              | comp(T.ENTRYLABEL lab)   = entryLabel lab        { beginCluster= beginCluster,
1380              | comp(T.BEGINCLUSTER)     = init 0          endCluster  = endCluster,
1381              | comp(T.CODE stms)        = app doStmt stms          emit        = doStmt,
1382              | comp(T.BLOCK_NAME name)  = blockName name          pseudoOp    = pseudoOp,
1383              | comp(T.BLOCK_ANNOTATION a) = annotation a          defineLabel = defineLabel,
1384              | comp(T.ENDCLUSTER regmap)= finish regmap          entryLabel  = entryLabel,
1385              | comp(T.ESCAPEBLOCK regs) = exitBlock (map cc regs)          blockName   = blockName,
1386              | comp _ = error "mltreeComp"          comment     = comment,
1387        in  comp mltree          annotation  = annotation,
1388        end          exitBlock   = fn regs => exitBlock(map cc regs),
1389            alias       = alias,
1390     in { mltreeComp = mltreeComp,          phi         = phi
         mlriscComp = doStmt,  
         emitInstr  = emit  
1391        }        }
1392     end     end
1393    

Legend:
Removed from v.410  
changed lines
  Added in v.429

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