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 744, Fri Dec 8 04:11:42 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 
282        val readonly = I.Region.readonly        val readonly = I.Region.readonly
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
545                                       I.BINARY{binOp=I.ADDL,                                       I.BINARY{binOp=I.ADDL,
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.744  
changed lines
  Added in v.761

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