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
 [smlnj] / sml / trunk / src / MLRISC / x86 / mltree / x86.sml

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

revision 760, Fri Dec 22 14:15:24 2000 UTC revision 761, Sat Dec 23 05:37:37 2000 UTC
# Line 179  Line 179
179        (* conversions *)        (* conversions *)
180        val itow = Word.fromInt        val itow = Word.fromInt
181        val wtoi = Word.toInt        val wtoi = Word.toInt
182        fun toInt32 i = Int32.fromLarge(Int.toLarge i)        fun toInt32 i = T.I.toInt32(32, i)
183        val w32toi32 = Word32.toLargeIntX        val w32toi32 = Word32.toLargeIntX
184        val i32tow32 = Word32.fromLargeInt        val i32tow32 = Word32.fromLargeInt
185
# Line 194  Line 194
194        fun immedLabel lab = I.ImmedLabel(LE.LABEL lab)        fun immedLabel lab = I.ImmedLabel(LE.LABEL lab)
195
196        (* Is the expression zero? *)        (* Is the expression zero? *)
197        fun isZero(T.LI 0) = true        fun isZero(T.LI z) = T.I.isZero z
| isZero(T.LI32 0w0) = true
198          | isZero(T.MARK(e,a)) = isZero e          | isZero(T.MARK(e,a)) = isZero e
199          | isZero _ = false          | isZero _ = false
200         (* Does the expression set the zero bit?         (* Does the expression set the zero bit?
# Line 283  Line 282
283
284        (*        (*
285         * Compute an effective address.  This is a new version         * Compute an effective address.
286         *)         *)
287        fun address(ea, mem) =        fun address(ea, mem) = let
let (* tricky way to negate without overflow! *)
fun neg32 w = Word32.notb w + 0w1

288            (* Keep building a bigger and bigger effective address expressions            (* Keep building a bigger and bigger effective address expressions
289             * The input is a list of trees             * The input is a list of trees
290             * b -- base             * b -- base
# Line 299  Line 295
295            fun doEA([], b, i, s, d) = makeAddressingMode(b, i, s, d)            fun doEA([], b, i, s, d) = makeAddressingMode(b, i, s, d)
296              | doEA(t::trees, b, i, s, d) =              | doEA(t::trees, b, i, s, d) =
297                (case t of                (case t of
298                   T.LI n   => doEAImmed(trees, n, b, i, s, d)                   T.LI n   => doEAImmed(trees, toInt32 n, b, i, s, d)
| T.LI32 n => doEAImmedw(trees, n, b, i, s, d)
299                 | T.CONST c => doEALabel(trees, LE.CONST c, b, i, s, d)                 | T.CONST c => doEALabel(trees, LE.CONST c, b, i, s, d)
300                 | T.LABEL le => doEALabel(trees, le, b, i, s, d)                 | T.LABEL le => doEALabel(trees, le, b, i, s, d)
301                 | T.ADD(32, t1, t2 as T.REG(_,r)) =>                 | T.ADD(32, t1, t2 as T.REG(_,r)) =>
# Line 308  Line 303
303                      else doEA(t1::t2::trees, b, i, s, d)                      else doEA(t1::t2::trees, b, i, s, d)
304                 | T.ADD(32, t1, t2) => doEA(t1::t2::trees, b, i, s, d)                 | T.ADD(32, t1, t2) => doEA(t1::t2::trees, b, i, s, d)
305                 | T.SUB(32, t1, T.LI n) =>                 | T.SUB(32, t1, T.LI n) =>
306                      (* can't overflow here *)                      doEA(t1::T.LI(T.I.NEG(32,n))::trees, b, i, s, d)
307                      doEA(t1::T.LI32(neg32(Word32.fromInt n))::trees, b, i, s, d)                 | T.SLL(32, t1, T.LI n) => let
308                 | T.SUB(32, t1, T.LI32 n) =>                      val n = T.I.toInt(32, n)
309                      doEA(t1::T.LI32(neg32 n)::trees, b, i, s, d)                   in
310                 | T.SLL(32, t1, T.LI 0) => displace(trees, t1, b, i, s, d)                     case n
311                 | T.SLL(32, t1, T.LI 1) => indexed(trees, t1, t, 1, b, i, s, d)                     of 0 => displace(trees, t1, b, i, s, d)
312                 | T.SLL(32, t1, T.LI 2) => indexed(trees, t1, t, 2, b, i, s, d)                      | 1 => indexed(trees, t1, t, 1, b, i, s, d)
313                 | T.SLL(32, t1, T.LI 3) => indexed(trees, t1, t, 3, b, i, s, d)                      | 2 => indexed(trees, t1, t, 2, b, i, s, d)
314                 | T.SLL(32, t1, T.LI32 0w0) => displace(trees, t1, b, i, s, d)                      | 3 => indexed(trees, t1, t, 3, b, i, s, d)
315                 | T.SLL(32, t1, T.LI32 0w1) => indexed(trees,t1,t,1,b,i,s,d)                      | _ => displace(trees, t, b, i, s, d)
316                 | T.SLL(32, t1, T.LI32 0w2) => indexed(trees,t1,t,2,b,i,s,d)                   end
| T.SLL(32, t1, T.LI32 0w3) => indexed(trees,t1,t,3,b,i,s,d)
317                 | t => displace(trees, t, b, i, s, d)                 | t => displace(trees, t, b, i, s, d)
318                )                )
319
320            (* Add an immed constant *)            (* Add an immed constant *)
321            and doEAImmed(trees, 0, b, i, s, d) = doEA(trees, b, i, s, d)            and doEAImmed(trees, 0, b, i, s, d) = doEA(trees, b, i, s, d)
322              | doEAImmed(trees, n, b, i, s, I.Immed m) =              | doEAImmed(trees, n, b, i, s, I.Immed m) =
323                   doEA(trees, b, i, s, (* no overflow! *)                   doEA(trees, b, i, s, I.Immed(n+m))
I.Immed(w32toi32(Word32.fromInt n + i32tow32 m)))
324              | doEAImmed(trees, n, b, i, s, I.ImmedLabel le) =              | doEAImmed(trees, n, b, i, s, I.ImmedLabel le) =
325                   doEA(trees, b, i, s, I.ImmedLabel(LE.PLUS(le,LE.INT n)))                   doEA(trees, b, i, s, I.ImmedLabel(LE.PLUS(le,LE.INT(Int32.toInt n))))
326              | doEAImmed(trees, n, b, i, s, _) = error "doEAImmed"              | doEAImmed(trees, n, b, i, s, _) = error "doEAImmed"
327
(* Add an immed32 constant *)
and doEAImmedw(trees, 0w0, b, i, s, d) = doEA(trees, b, i, s, d)
| doEAImmedw(trees, n, b, i, s, I.Immed m) =
(* no overflow! *)
doEA(trees, b, i, s, I.Immed(w32toi32(i32tow32 m + n)))
| doEAImmedw(trees, n, b, i, s, I.ImmedLabel le) =
doEA(trees, b, i, s,
I.ImmedLabel(LE.PLUS(le,LE.INT(Word32.toIntX n)))
handle Overflow => error "doEAImmedw: constant too large")
| doEAImmedw(trees, n, b, i, s, _) = error "doEAImmedw"

328            (* Add a label expression *)            (* Add a label expression *)
329            and doEALabel(trees, le, b, i, s, I.Immed 0) =            and doEALabel(trees, le, b, i, s, I.Immed 0) =
330                   doEA(trees, b, i, s, I.ImmedLabel le)                   doEA(trees, b, i, s, I.ImmedLabel le)
# Line 408  Line 390
390        end (* address *)        end (* address *)
391
392            (* reduce an expression into an operand *)            (* reduce an expression into an operand *)
393        and operand(T.LI i) = I.Immed(toInt32 i)        and operand(T.LI i) = I.Immed(toInt32(i))
| operand(T.LI32 w) = I.Immed(wToInt32 w)
394          | operand(T.CONST c) = I.ImmedLabel(LE.CONST c)          | operand(T.CONST c) = I.ImmedLabel(LE.CONST c)
395          | operand(T.LABEL lab) = I.ImmedLabel lab          | operand(T.LABEL lab) = I.ImmedLabel lab
396          | operand(T.REG(_,r)) = IntReg r          | operand(T.REG(_,r)) = IntReg r
# Line 540  Line 521
521                end                end
522
523                    (* Optimize the special case for division *)                    (* Optimize the special case for division *)
524                fun divide(signed, overflow, e1, e2 as T.LI n) =                fun divide(signed, overflow, e1, e2 as T.LI n') = let
525                let fun isPowerOf2 w = Word.andb((w - 0w1), w) = 0w0                    val n = toInt32 n'
526                      val w = T.I.toWord32(32, n')
527                      fun isPowerOf2 w = W32.andb((w - 0w1), w) = 0w0
528                    fun log2 n =  (* n must be > 0!!! *)                    fun log2 n =  (* n must be > 0!!! *)
529                        let fun loop(0w1,pow) = pow                        let fun loop(0w1,pow) = pow
530                              | loop(w,pow) = loop(Word.>>(w, 0w1),pow+1)                              | loop(w,pow) = loop(W32.>>(w, 0w1),pow+1)
531                        in loop(n,0) end                        in loop(n,0) end
val w = Word.fromInt n
532                in  if n > 1 andalso isPowerOf2 w then                in  if n > 1 andalso isPowerOf2 w then
533                       let val pow = T.LI(log2 w)                       let val pow = T.LI(T.I.fromInt(32,log2 w))
534                       in  if signed then                       in  if signed then
535                           (* signed; simulate round towards zero *)                           (* signed; simulate round towards zero *)
536                           let val label = Label.newLabel ""                           let val label = Label.newLabel ""
# Line 561  Line 543
543                                       I.UNARY{unOp=I.INCL, opnd=opnd1}                                       I.UNARY{unOp=I.INCL, opnd=opnd1}
544                                    else                                    else
546                                                src=I.Immed(toInt32 n - 1),                                                src=I.Immed(n - 1),
547                                                dst=opnd1});                                                dst=opnd1});
548                               defineLabel label;                               defineLabel label;
549                               shift(I.SARL, T.REG(32, reg1), pow)                               shift(I.SARL, T.REG(32, reg1), pow)
# Line 793  Line 775
775                            move'(tmp, rdOpnd, [])                            move'(tmp, rdOpnd, [])
776                        end                        end
777                     else move'(IntReg rs, rdOpnd, an)                     else move'(IntReg rs, rdOpnd, an)
778               | (T.LI 0 | T.LI32 0w0) =>               | T.LI z => let
779                     val n = toInt32 z
780                   in
781                     if n=0 then
782                   (* As per Fermin's request, special optimization for rd := 0.                   (* As per Fermin's request, special optimization for rd := 0.
783                    * Currently we don't bother with the size.                    * Currently we don't bother with the size.
784                    *)                    *)
785                   if isMemReg rd then move'(I.Immed 0, rdOpnd, an)                   if isMemReg rd then move'(I.Immed 0, rdOpnd, an)
786                   else mark(I.BINARY{binOp=I.XORL, src=rdOpnd, dst=rdOpnd}, an)                   else mark(I.BINARY{binOp=I.XORL, src=rdOpnd, dst=rdOpnd}, an)
787               | T.LI n      => move'(I.Immed(toInt32 n), rdOpnd, an)                   else
788               | T.LI32 w    => move'(I.Immed(wToInt32 w), rdOpnd, an)                     move'(I.Immed(n), rdOpnd, an)
789                   end
790               | T.CONST c   => move'(I.ImmedLabel(LE.CONST c), rdOpnd, an)               | T.CONST c   => move'(I.ImmedLabel(LE.CONST c), rdOpnd, an)
791               | T.LABEL lab => move'(I.ImmedLabel lab, rdOpnd, an)               | T.LABEL lab => move'(I.ImmedLabel lab, rdOpnd, an)
792
793                 (* 32-bit addition *)                 (* 32-bit addition *)
794               | T.ADD(32, e, (T.LI 1|T.LI32 0w1)) => unary(I.INCL, e)               | T.ADD(32, e1, e2 as T.LI n) => let
795               | T.ADD(32, (T.LI 1|T.LI32 0w1), e) => unary(I.INCL, e)                   val n = toInt32 n
796               | T.ADD(32, e, T.LI ~1) => unary(I.DECL, e)                 in
797               | T.ADD(32, T.LI ~1, e) => unary(I.DECL, e)                   case n
798                     of 1  => unary(I.INCL, e1)
799                      | ~1 => unary(I.DECL, e1)
800                      | _ => addition(e1, e2)
801                   end
802                 | T.ADD(32, e1 as T.LI n, e2) => let
803                     val n = toInt32 n
804                   in
805                     case n
806                     of  1 => unary(I.INCL, e2)
807                      | ~1 => unary(I.DECL, e2)
808                      | _ => addition(e1, e2)
809                   end
810               | T.ADD(32, e1, e2) => addition(e1, e2)               | T.ADD(32, e1, e2) => addition(e1, e2)
811
812                 (* 32-bit addition but set the flag!                 (* 32-bit addition but set the flag!
813                  * This is a stupid hack for now.                  * This is a stupid hack for now.
814                  *)                  *)
815               | T.ADD(0, e, (T.LI 1|T.LI32 0w1)) => unary(I.INCL, e)               | T.ADD(0, e, e1 as T.LI n) => let
816               | T.ADD(0, (T.LI 1|T.LI32 0w1), e) => unary(I.INCL, e)                   val n = T.I.toInt(32, n)
817               | T.ADD(0, e, T.LI ~1) => unary(I.DECL, e)                 in
818               | T.ADD(0, T.LI ~1, e) => unary(I.DECL, e)                   if n=1 then unary(I.INCL, e)
819                     else if n = ~1 then unary(I.DECL, e)
820                          else binaryComm(I.ADDL, e, e1)
821                   end
822                 | T.ADD(0, e1 as T.LI n, e) => let
823                     val n = T.I.toInt(32, n)
824                   in
825                     if n=1 then unary(I.INCL, e)
826                     else if n = ~1 then unary(I.DECL, e)
827                          else binaryComm(I.ADDL, e1, e)
828                   end
829               | T.ADD(0, e1, e2) => binaryComm(I.ADDL, e1, e2)               | T.ADD(0, e1, e2) => binaryComm(I.ADDL, e1, e2)
830
831                 (* 32-bit subtraction *)                 (* 32-bit subtraction *)
832               | T.SUB(32, e, (T.LI 0 | T.LI32 0w0)) => doExpr(e, rd, an)               | T.SUB(32, e1, e2 as T.LI n) => let
833               | T.SUB(32, e, (T.LI 1 | T.LI32 0w1)) => unary(I.DECL, e)                   val n = toInt32 n
834               | T.SUB(32, e, T.LI ~1) => unary(I.INCL, e)                 in
835               | T.SUB(32, (T.LI 0 | T.LI32 0w0), e) => unary(I.NEGL, e)                   case n
836                     of 0 => doExpr(e1, rd, an)
837               (* Never mind:                    | 1 => unary(I.DECL, e1)
838                 | T.SUB(32, e1, e2 as T.LI n) =>                    | ~1 => unary(I.INCL, e1)
839                   (mark(I.LEA{r32=rd, addr=address(T.ADD(32, e1, T.LI(~n)),                    | _ => binary(I.SUBL, e1, e2)
840                                                    I.Region.readonly)}, an)                 end
841                    handle (Overflow|EA) => binary(I.SUBL, e1, e2))               | T.SUB(32, e1 as T.LI n, e2) =>
842               *)                   if T.I.isZero n then unary(I.NEGL, e2)
843                     else binary(I.SUBL, e1, e2)
844               | T.SUB(32, e1, e2) => binary(I.SUBL, e1, e2)               | T.SUB(32, e1, e2) => binary(I.SUBL, e1, e2)
845
846               | T.MULU(32, x, y) => uMultiply(x, y)               | T.MULU(32, x, y) => uMultiply(x, y)
# Line 865  Line 874
874
875               | T.COND(32, T.CMP(ty, cc, t1, t2), T.LI yes, T.LI no) =>               | T.COND(32, T.CMP(ty, cc, t1, t2), T.LI yes, T.LI no) =>
876                   setcc(ty, cc, t1, t2, toInt32 yes, toInt32 no)                   setcc(ty, cc, t1, t2, toInt32 yes, toInt32 no)
| T.COND(32, T.CMP(ty, cc, t1, t2), T.LI32 yes, T.LI32 no) =>
setcc(ty, cc, t1, t2, Word32.toLargeIntX yes,
Word32.toLargeIntX no)
877               | T.COND(32, T.CMP(ty, cc, t1, t2), yes, no) =>               | T.COND(32, T.CMP(ty, cc, t1, t2), yes, no) =>
878                  (case !arch of (* PentiumPro and higher has CMOVcc *)                  (case !arch of (* PentiumPro and higher has CMOVcc *)
879                     Pentium => unknownExp exp                     Pentium => unknownExp exp

Legend:
 Removed from v.760 changed lines Added in v.761

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