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

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

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

revision 555, Fri Mar 3 16:10:30 2000 UTC revision 565, Sun Mar 5 04:10:18 2000 UTC
# Line 54  Line 54 
54    type instrStream = (I.instruction,C.regmap,C.cellset) T.stream    type instrStream = (I.instruction,C.regmap,C.cellset) T.stream
55    type mltreeStream = (T.stm,C.regmap,T.mlrisc list) T.stream    type mltreeStream = (T.stm,C.regmap,T.mlrisc list) T.stream
56    
57      datatype kind = REAL | INTEGER
58    
59    structure Gen = MLTreeGen    structure Gen = MLTreeGen
60       (structure T = T       (structure T = T
61        val intTy = 32        val intTy = 32
# Line 941  Line 943 
943          | fld(80, opnd) = I.FLDT opnd          | fld(80, opnd) = I.FLDT opnd
944          | fld _         = error "fld"          | fld _         = error "fld"
945    
946          and fild(16, opnd) = I.FILD opnd
947            | fild(32, opnd) = I.FILDL opnd
948            | fild(64, opnd) = I.FILDLL opnd
949            | fild _         = error "fild"
950    
951          and fxld(INTEGER, ty, opnd) = fild(ty, opnd)
952            | fxld(REAL, fty, opnd) = fld(fty, opnd)
953    
954        and fstp(32, opnd) = I.FSTPS opnd        and fstp(32, opnd) = I.FSTPS opnd
955          | fstp(64, opnd) = I.FSTPL opnd          | fstp(64, opnd) = I.FSTPL opnd
956          | fstp(80, opnd) = I.FSTPT opnd          | fstp(80, opnd) = I.FSTPT opnd
# Line 980  Line 990 
990            let val ST = I.ST(C.ST 0)            let val ST = I.ST(C.ST 0)
991                val ST1 = I.ST(C.ST 1)                val ST1 = I.ST(C.ST 1)
992    
993                datatype su_numbers =                datatype su_tree =
994                  LEAF of int                  LEAF of int * T.fexp * ans
995                | BINARY of int * su_numbers * su_numbers                | BINARY of int * T.fty * fbinop * su_tree * su_tree * ans
996                | UNARY of int * su_numbers                | UNARY of int * T.fty * I.funOp * su_tree * ans
997                  and fbinop = FADD | FSUB | FMUL | FDIV
998                datatype direction = LEFT | RIGHT                           | FIADD | FISUB | FIMUL | FIDIV
999                  withtype ans = Annotations.annotations
1000                fun label(LEAF n) = n  
1001                  | label(BINARY(n, _, _)) = n                fun label(LEAF(n, _, _)) = n
1002                  | label(UNARY(n, _)) = n                  | label(BINARY(n, _, _, _, _, _)) = n
1003                    | label(UNARY(n, _, _, _, _)) = n
1004               (* Generate tree of sethi-ullman numbers *)  
1005                fun suBinary(t1, t2) =                fun annotate(LEAF(n, x, an), a)  = LEAF(n,x,a::an)
1006                    let val su1 = suNumbering(t1, LEFT)                  | annotate(BINARY(n,t,b,x,y,an), a) = BINARY(n,t,b,x,y,a::an)
1007                        val su2 = suNumbering(t2, RIGHT)                  | annotate(UNARY(n,t,u,x,an), a) = UNARY(n,t,u,x,a::an)
1008                        val n1 = label su1  
1009                        val n2 = label su2                (* Generate expression tree with sethi-ullman numbers *)
1010                    in  BINARY(if n1=n2 then n1+1 else Int.max(n1, n2), su1, su2)                fun su(e as T.FREG _)       = LEAF(1, e, [])
1011                    end                  | su(e as T.FLOAD _)      = LEAF(1, e, [])
1012                    | su(e as T.CVTI2F _)     = LEAF(1, e, [])
1013                and suUnary(t) =                  | su(T.CVTF2F(_, _, t))   = su t
1014                    let val su = suNumbering(t, LEFT)                  | su(T.FMARK(t, a))       = annotate(su t, a)
1015                    in  UNARY(label su, su)                  | su(T.FABS(fty, t))      = suUnary(fty, I.FABS, t)
1016                    end                  | su(T.FNEG(fty, t))      = suUnary(fty, I.FCHS, t)
1017                    | su(T.FSQRT(fty, t))     = suUnary(fty, I.FSQRT, t)
1018                and suNumbering(T.FREG _, LEFT) = LEAF 1                  | su(T.FADD(fty, t1, t2)) = suComBinary(fty,FADD,FIADD,t1,t2)
1019                  | suNumbering(T.FREG _, RIGHT) = LEAF 0                  | su(T.FMUL(fty, t1, t2)) = suComBinary(fty,FMUL,FIMUL,t1,t2)
1020                  | suNumbering(T.FLOAD _, LEFT) = LEAF 1                  | su(T.FSUB(fty, t1, t2)) = suBinary(fty,FSUB,FISUB,t1,t2)
1021                  | suNumbering(T.FLOAD _, RIGHT) = LEAF 0                  | su(T.FDIV(fty, t1, t2)) = suBinary(fty,FDIV,FIDIV,t1,t2)
1022                  | suNumbering(T.FADD(_, t1, t2), _) = suBinary(t1, t2)                  | su _ = error "su"
1023                  | suNumbering(T.FMUL(_, t1, t2), _) = suBinary(t1, t2)  
1024                  | suNumbering(T.FSUB(_, t1, t2), _) = suBinary(t1, t2)                (* Try to fold the the memory operand or integer conversion *)
1025                  | suNumbering(T.FDIV(_, t1, t2), _) = suBinary(t1, t2)                and suFold(e as T.FREG _) = (LEAF(0, e, []), false)
1026                  | suNumbering(T.FABS(_,t), _) = suUnary(t)                  | suFold(e as T.FLOAD _) = (LEAF(0, e, []), false)
1027                  | suNumbering(T.FNEG(_,t), _) = suUnary(t)                  | suFold(e as T.CVTI2F(_,(16 | 32),_)) = (LEAF(0, e, []), true)
1028                  | suNumbering(T.CVTI2F _, _) = UNARY(1, LEAF 0)                  | suFold(T.CVTF2F(_, _, t)) = suFold t
1029                  | suNumbering(T.CVTF2F(_,_,T.FLOAD _), _) = UNARY(1, LEAF 0)                  | suFold(T.FMARK(t, a)) =
1030                  | suNumbering(T.CVTF2F(_,_,t), _) = suUnary t                    let val (t, integer) = suFold t
1031                  | suNumbering(T.FMARK(e,a),x) = suNumbering(e,x)                    in  (annotate(t, a), integer) end
1032                  | suNumbering _ = error "suNumbering"                  | suFold e = (su e, false)
1033    
1034                fun leafEA(T.FREG(fty, f)) = (fty, I.FDirect f)                (* Can the tree be folded into the src operand? *)
1035                  | leafEA(T.FLOAD(fty, ea, mem)) = (fty, address(ea, mem))                and foldable(T.FREG _) = true
1036                  | leafEA(T.CVTF2F(_, _, T.FLOAD(fty, ea, mem))) =                  | foldable(T.FLOAD _) = true
1037                        (fty, address(ea, mem))                  | foldable(T.CVTI2F(_, (16 | 32), _)) = true
1038                  | leafEA _ = error "leafEA"                  | foldable(T.CVTF2F(_, _, t)) = foldable t
1039                    | foldable(T.FMARK(t, _)) = foldable t
1040                fun cvti2d(t,an) =                  | foldable _ = false
1041                let val opnd = operand t  
1042                    fun doMemOpnd () =                (* Form unary tree *)
1043                        (emit(I.MOVE{mvOp=I.MOVL, src=opnd, dst=tempMem});                and suUnary(fty, funary, t) =
1044                         mark(I.FILD tempMem,an))                    let val t = su t
1045                in  case opnd of                    in  UNARY(label t, fty, funary, t, [])
1046                      I.Direct _ => doMemOpnd()                    end
1047                    | I.Immed _ => doMemOpnd()  
1048                    | _ => mark(I.FILD opnd, an)                (* Form binary tree *)
1049                end                and suBinary(fty, binop, ibinop, t1, t2) =
1050                      let val t1 = su t1
1051                (* traverse expression and su-number tree *)                        val (t2, integer) = suFold t2
1052                fun gencode(_, LEAF 0, an) = ()                        val n1 = label t1
1053                  | gencode(T.FMARK(e,a), x, an) = gencode(e, x, a::an)                        val n2 = label t2
1054                  | gencode(f, LEAF 1, an) = mark(fld(leafEA f), an)                        val n  = if n1=n2 then n1+1 else Int.max(n1,n2)
1055                  | gencode(t, BINARY(_, su1, LEAF 0), an) =                        val myOp = if integer then ibinop else binop
1056                    let (* optimize the common case when both operands                    in  BINARY(n, fty, myOp, t1, t2, [])
1057                         * are equal *)                    end
1058                        fun sameEA(T.FREG(t1, f1), T.FREG(t2, f2)) =  
1059                              t1 = t2 andalso f1 = f2                (* Try to fold in the operand if possible.
1060                          | sameEA _ = false                 * This only applies to commutative operations.
1061                   *)
1062                        fun doit(oper32, oper64, t1, t2) =                and suComBinary(fty, binop, ibinop, t1, t2) =
1063                        let val _ = gencode(t1, su1, [])                    let val (t1, t2) = if foldable t2 then (t1, t2) else (t2, t1)
1064                            val (fty, src) = leafEA t2                    in  suBinary(fty, binop, ibinop, t1, t2) end
1065                        in  if sameEA(t1, t2) then  
1066                               mark(I.FBINARY{binOp=oper64, src=ST, dst=ST}, an)                and sameTree(LEAF(_, T.FREG(t1,f1), []),
1067                               LEAF(_, T.FREG(t2,f2), [])) = t1=t2 andalso f1=f2
1068                    | sameTree _ = false
1069    
1070                  (* Traverse tree and generate code *)
1071                  fun gencode(LEAF(_, t, an)) = mark(fxld(leafEA t), an)
1072                    | gencode(BINARY(_, _, binop, x, t2 as LEAF(0, y, a1), a2)) =
1073                      let val _          = gencode x
1074                          val (_, fty, src) = leafEA y
1075                          fun gen(code) = mark(code, a1 @ a2)
1076                          fun binary(oper32, oper64) =
1077                              if sameTree(x, t2) then
1078                                 gen(I.FBINARY{binOp=oper64, src=ST, dst=ST})
1079                            else                            else
1080                               let val oper =                               let val oper =
1081                                       if isMemOpnd src then                                       if isMemOpnd src then
1082                                           case fty of                                           case fty of
1083                                             32 => oper32                                             32 => oper32
1084                                           | 64 => oper64                                           | 64 => oper64
1085                                           | _  => error "gencode: binary"                                        | _  => error "gencode: BINARY"
1086                                       else oper64                                       else oper64
1087                               in mark(I.FBINARY{binOp=oper, src=src, dst=ST}, an)                               in gen(I.FBINARY{binOp=oper, src=src, dst=ST}) end
1088                               end                        fun ibinary(oper16, oper32) =
1089                        end                            let val oper = case fty of
1090                    in                                             16 => oper16
1091                      case t of                                           | 32 => oper32
1092                         T.FADD(_, t1, t2) => doit(I.FADDS,I.FADDL,t1,t2)                                           | _  => error "gencode: IBINARY"
1093                       | T.FMUL(_, t1, t2) => doit(I.FMULS,I.FMULL,t1,t2)                            in  gen(I.FIBINARY{binOp=oper, src=src}) end
1094                       | T.FSUB(_, t1, t2) => doit(I.FSUBS,I.FSUBL,t1,t2)                    in  case binop of
1095                       | T.FDIV(_, t1, t2) => doit(I.FDIVS,I.FDIVL,t1,t2)                          FADD => binary(I.FADDS, I.FADDL)
1096                       | _ => error "gencode.BINARY"                        | FSUB => binary(I.FDIVS, I.FSUBL)
1097                    end                        | FMUL => binary(I.FMULS, I.FMULL)
1098                  | gencode(fexp, BINARY(fty, su1, su2), an) =                        | FDIV => binary(I.FDIVS, I.FDIVL)
1099                    let fun doit(t1, t2, oper, operP, operRP) = let                        | FIADD => ibinary(I.FIADDS, I.FIADDL)
1100                       (* oper[P] =>  ST(1) := ST oper ST(1); [pop]                        | FISUB => ibinary(I.FIDIVS, I.FISUBL)
1101                          | FIMUL => ibinary(I.FIMULS, I.FIMULL)
1102                          | FIDIV => ibinary(I.FIDIVS, I.FIDIVL)
1103                      end
1104                    | gencode(BINARY(_, fty, binop, t1, t2, an)) =
1105                      let fun doit(t1, t2, oper, operP, operRP) =
1106                          let (* oper[P] =>  ST(1) := ST oper ST(1); [pop]
1107                        * operR[P] => ST(1) := ST(1) oper ST; [pop]                        * operR[P] => ST(1) := ST(1) oper ST; [pop]
1108                        *)                        *)
1109                        val n1 = label su1                             val n1 = label t1
1110                        val n2 = label su2                             val n2 = label t2
1111                      in                        in if n1 < n2 andalso n1 <= 7 then
1112                        if n1 < n2 andalso n1 <= 7 then                             (gencode t2;
1113                          (gencode(t2, su2, []);                              gencode t1;
                          gencode(t1, su1, []);  
1114                           mark(I.FBINARY{binOp=operP, src=ST, dst=ST1}, an))                           mark(I.FBINARY{binOp=operP, src=ST, dst=ST1}, an))
1115                        else if n2 <= n1 andalso n2 <= 7 then                        else if n2 <= n1 andalso n2 <= 7 then
1116                          (gencode(t1, su1, []);                             (gencode t1;
1117                           gencode(t2, su2, []);                              gencode t2;
1118                           mark(I.FBINARY{binOp=operRP, src=ST, dst=ST1}, an))                           mark(I.FBINARY{binOp=operRP, src=ST, dst=ST1}, an))
1119                        else let (* both labels > 7 *)                           else
1120                             let (* both labels > 7 *)
1121                            val fs = I.FDirect(newFreg())                            val fs = I.FDirect(newFreg())
1122                          in                           in  gencode t2;
                           gencode (t2, su2, []);  
1123                            emit(fstp(fty, fs));                            emit(fstp(fty, fs));
1124                            gencode (t1, su1, []);                               gencode t1;
1125                            mark(I.FBINARY{binOp=oper, src=fs, dst=ST}, an)                            mark(I.FBINARY{binOp=oper, src=fs, dst=ST}, an)
1126                          end                          end
1127                      end                      end
1128                    in                    in case binop of
1129                      case fexp                         FADD => doit(t1,t2,I.FADDL,I.FADDP,I.FADDP)
1130                      of T.FADD(_, t1, t2) => doit(t1,t2,I.FADDL,I.FADDP,I.FADDP)                       | FMUL => doit(t1,t2,I.FMULL,I.FMULP,I.FMULP)
1131                       | T.FMUL(_, t1, t2) => doit(t1,t2,I.FMULL,I.FMULP,I.FMULP)                       | FSUB => doit(t1,t2,I.FSUBL,I.FSUBP,I.FSUBRP)
1132                       | T.FSUB(_, t1, t2) => doit(t1,t2,I.FSUBL,I.FSUBP,I.FSUBRP)                       | FDIV => doit(t1,t2,I.FDIVL,I.FDIVP,I.FDIVRP)
                      | T.FDIV(_, t1, t2) => doit(t1,t2,I.FDIVL,I.FDIVP,I.FDIVRP)  
1133                       | _ => error "gencode.BINARY"                       | _ => error "gencode.BINARY"
1134                    end                    end
1135                  | gencode(fexp, UNARY(_, LEAF 0), an) =                  | gencode(UNARY(_, _, unaryOp, su, an)) =
1136                    (case fexp                     (gencode(su); mark(I.FUNARY(unaryOp),an))
                     of T.FABS(fty, t) =>  
                          (emit(fld(leafEA t)); mark(I.FUNARY(I.FABS),an))  
                      | T.FNEG(fty, t) =>  
                          (emit(fld(leafEA t)); mark(I.FUNARY(I.FCHS),an))  
                      | T.CVTI2F(_,_,t) => cvti2d(t,an) (* XXX *)  
                      | _ => error "gencode.UNARY"  
                    (*esac*))  
                 | gencode(fexp, UNARY(_, su), an) =  
                   let fun doit(oper, t) =  
                        (gencode(t, su, []); mark(I.FUNARY(oper),an))  
                   in case fexp  
                      of T.FABS(_, t) => doit(I.FABS, t)  
                       | T.FNEG(_, t) => doit(I.FCHS, t)  
                       | T.CVTF2F(_,_,t) => gencode(t, su, an)  
                       | T.CVTI2F _ => error "gencode:UNARY:cvti2f"  
                       | _ => error "gencode.UNARY"  
                   end  
                 | gencode _ = error "gencode"  
1137    
1138                val labels = suNumbering(fexp, LEFT)                (* Generate code for a leaf.
1139            in  gencode(fexp, labels, an)                 * Returns the type and an effective address
1140                   *)
1141                  and leafEA(T.FREG(fty, f)) = (REAL, fty, I.FDirect f)
1142                    | leafEA(T.FLOAD(fty, ea, mem)) = (REAL, fty, address(ea, mem))
1143                    | leafEA(T.CVTI2F(_, 32, t)) = int2real(32, I.MOVL, t)
1144                    | leafEA(T.CVTI2F(_, 16, t)) = int2real(16, I.MOVSWL, t)
1145                    | leafEA(T.CVTI2F(_, 8, t))  = int2real(8, I.MOVSBL, t)
1146                    | leafEA _ = error "leafEA"
1147    
1148                  (* Move integer t of size ty into a memory location *)
1149                  and int2real(ty, mov, t) =
1150                      let val opnd = operand t
1151                      in  if isMemOpnd opnd andalso (ty = 16 orelse ty = 32)
1152                          then (INTEGER, ty, opnd)
1153                          else (emit(I.MOVE{mvOp=mov, src=opnd, dst=tempMem});
1154                                (INTEGER, 32, tempMem))
1155                      end
1156              in  gencode(su fexp)
1157            end (*reduceFexp*)            end (*reduceFexp*)
1158    
1159            (* generate code for a statement *)            (* generate code for a statement *)

Legend:
Removed from v.555  
changed lines
  Added in v.565

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