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 779, Sun Jan 14 06:40:32 2001 UTC
# Line 39  Line 39 
39    
40  functor X86  functor X86
41    (structure X86Instr : X86INSTR    (structure X86Instr : X86INSTR
    structure X86MLTree : MLTREE  
42     structure ExtensionComp : MLTREE_EXTENSION_COMP     structure ExtensionComp : MLTREE_EXTENSION_COMP
43       where I = X86Instr and T = X86MLTree       where I = X86Instr
      sharing X86MLTree.Region = X86Instr.Region  
      sharing X86MLTree.LabelExp = X86Instr.LabelExp  
44      datatype arch = Pentium | PentiumPro | PentiumII | PentiumIII      datatype arch = Pentium | PentiumPro | PentiumII | PentiumIII
45      val arch : arch ref      val arch : arch ref
46      val cvti2f :      val cvti2f :
47           (* source operand, guaranteed to be non-memory! *)           (* source operand, guaranteed to be non-memory! *)
48           {ty: X86MLTree.ty, src: X86Instr.operand} ->           {ty: X86Instr.T.ty, src: X86Instr.operand} ->
49           {instrs : X86Instr.instruction list,(* the instructions *)           {instrs : X86Instr.instruction list,(* the instructions *)
50            tempMem: X86Instr.operand,         (* temporary for CVTI2F *)            tempMem: X86Instr.operand,         (* temporary for CVTI2F *)
51            cleanup: X86Instr.instruction list (* cleanup code *)            cleanup: X86Instr.instruction list (* cleanup code *)
# Line 61  Line 58 
58            val rewriteMemReg : bool            val rewriteMemReg : bool
59        end =        end =
60  struct  struct
   structure T = X86MLTree  
   structure S = T.Stream  
61    structure I = X86Instr    structure I = X86Instr
62      structure T = I.T
63      structure S = T.Stream
64    structure C = I.C    structure C = I.C
65    structure Shuffle = Shuffle(I)    structure Shuffle = Shuffle(I)
66    structure W32 = Word32    structure W32 = Word32
# Line 132  Line 129 
129              case !trapLabel of              case !trapLabel of
130                NONE => let val label = Label.newLabel "trap"                NONE => let val label = Label.newLabel "trap"
131                            val jmp   = I.JCC{cond=I.O,                            val jmp   = I.JCC{cond=I.O,
132                                              opnd=I.ImmedLabel(LE.LABEL label)}                                              opnd=I.ImmedLabel(T.LABEL label)}
133                        in  trapLabel := SOME(jmp, label); jmp end                        in  trapLabel := SOME(jmp, label); jmp end
134              | SOME(jmp, _) => jmp              | SOME(jmp, _) => jmp
135        in  emit jmp end        in  emit jmp end
# Line 179  Line 176 
176        (* conversions *)        (* conversions *)
177        val itow = Word.fromInt        val itow = Word.fromInt
178        val wtoi = Word.toInt        val wtoi = Word.toInt
179        fun toInt32 i = Int32.fromLarge(Int.toLarge i)        fun toInt32 i = T.I.toInt32(32, i)
180        val w32toi32 = Word32.toLargeIntX        val w32toi32 = Word32.toLargeIntX
181        val i32tow32 = Word32.fromLargeInt        val i32tow32 = Word32.fromLargeInt
182    
# Line 191  Line 188 
188        val ecx = I.Direct(C.ecx)        val ecx = I.Direct(C.ecx)
189        val edx = I.Direct(C.edx)        val edx = I.Direct(C.edx)
190    
191        fun immedLabel lab = I.ImmedLabel(LE.LABEL lab)        fun immedLabel lab = I.ImmedLabel(T.LABEL lab)
192    
193        (* Is the expression zero? *)        (* Is the expression zero? *)
194        fun isZero(T.LI 0) = true        fun isZero(T.LI z) = T.I.isZero z
         | isZero(T.LI32 0w0) = true  
195          | isZero(T.MARK(e,a)) = isZero e          | isZero(T.MARK(e,a)) = isZero e
196          | isZero _ = false          | isZero _ = false
197         (* Does the expression set the zero bit?         (* Does the expression set the zero bit?
# Line 283  Line 279 
279        val readonly = I.Region.readonly        val readonly = I.Region.readonly
280    
281        (*        (*
282         * Compute an effective address.  This is a new version         * Compute an effective address.
283         *)         *)
284        fun address(ea, mem) =        fun address(ea, mem) = let
       let (* tricky way to negate without overflow! *)  
           fun neg32 w = Word32.notb w + 0w1  
   
285            (* Keep building a bigger and bigger effective address expressions            (* Keep building a bigger and bigger effective address expressions
286             * The input is a list of trees             * The input is a list of trees
287             * b -- base             * b -- base
# Line 299  Line 292 
292            fun doEA([], b, i, s, d) = makeAddressingMode(b, i, s, d)            fun doEA([], b, i, s, d) = makeAddressingMode(b, i, s, d)
293              | doEA(t::trees, b, i, s, d) =              | doEA(t::trees, b, i, s, d) =
294                (case t of                (case t of
295                   T.LI n   => doEAImmed(trees, n, b, i, s, d)                   T.LI n   => doEAImmed(trees, toInt32 n, b, i, s, d)
296                 | T.LI32 n => doEAImmedw(trees, n, b, i, s, d)                 | T.CONST _ => doEALabel(trees, t, b, i, s, d)
297                 | T.CONST c => doEALabel(trees, LE.CONST c, b, i, s, d)                 | T.LABEL _ => doEALabel(trees, t, b, i, s, d)
298                 | T.LABEL le => doEALabel(trees, le, b, i, s, d)                 | T.LABEXP le => doEALabel(trees, le, b, i, s, d)
299                 | T.ADD(32, t1, t2 as T.REG(_,r)) =>                 | T.ADD(32, t1, t2 as T.REG(_,r)) =>
300                      if isMemReg r then doEA(t2::t1::trees, b, i, s, d)                      if isMemReg r then doEA(t2::t1::trees, b, i, s, d)
301                      else doEA(t1::t2::trees, b, i, s, d)                      else doEA(t1::t2::trees, b, i, s, d)
302                 | 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)
303                 | T.SUB(32, t1, T.LI n) =>                 | T.SUB(32, t1, T.LI n) =>
304                      (* can't overflow here *)                      doEA(t1::T.LI(T.I.NEG(32,n))::trees, b, i, s, d)
305                      doEA(t1::T.LI32(neg32(Word32.fromInt n))::trees, b, i, s, d)                 | T.SLL(32, t1, T.LI n) => let
306                 | T.SUB(32, t1, T.LI32 n) =>                      val n = T.I.toInt(32, n)
307                      doEA(t1::T.LI32(neg32 n)::trees, b, i, s, d)                   in
308                 | T.SLL(32, t1, T.LI 0) => displace(trees, t1, b, i, s, d)                     case n
309                 | 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)
310                 | 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)
311                 | 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)
312                 | T.SLL(32, t1, T.LI32 0w0) => displace(trees, t1, b, i, s, d)                      | 3 => indexed(trees, t1, t, 3, b, i, s, d)
313                 | T.SLL(32, t1, T.LI32 0w1) => indexed(trees,t1,t,1,b,i,s,d)                      | _ => displace(trees, t, b, i, s, d)
314                 | 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)  
315                 | t => displace(trees, t, b, i, s, d)                 | t => displace(trees, t, b, i, s, d)
316                )                )
317    
318            (* Add an immed constant *)            (* Add an immed constant *)
319            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)
320              | doEAImmed(trees, n, b, i, s, I.Immed m) =              | doEAImmed(trees, n, b, i, s, I.Immed m) =
321                   doEA(trees, b, i, s, (* no overflow! *)                   doEA(trees, b, i, s, I.Immed(n+m))
                        I.Immed(w32toi32(Word32.fromInt n + i32tow32 m)))  
322              | doEAImmed(trees, n, b, i, s, I.ImmedLabel le) =              | doEAImmed(trees, n, b, i, s, I.ImmedLabel le) =
                  doEA(trees, b, i, s, I.ImmedLabel(LE.PLUS(le,LE.INT n)))  
             | doEAImmed(trees, n, b, i, s, _) = error "doEAImmed"  
   
           (* 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) =  
323                   doEA(trees, b, i, s,                   doEA(trees, b, i, s,
324                        I.ImmedLabel(LE.PLUS(le,LE.INT(Word32.toIntX n)))                        I.ImmedLabel(T.ADD(32,le,T.LI(T.I.fromInt32(32, n)))))
325                        handle Overflow => error "doEAImmedw: constant too large")              | doEAImmed(trees, n, b, i, s, _) = error "doEAImmed"
             | doEAImmedw(trees, n, b, i, s, _) = error "doEAImmedw"  
326    
327            (* Add a label expression *)            (* Add a label expression *)
328            and doEALabel(trees, le, b, i, s, I.Immed 0) =            and doEALabel(trees, le, b, i, s, I.Immed 0) =
329                   doEA(trees, b, i, s, I.ImmedLabel le)                   doEA(trees, b, i, s, I.ImmedLabel le)
330              | doEALabel(trees, le, b, i, s, I.Immed m) =              | doEALabel(trees, le, b, i, s, I.Immed m) =
331                   doEA(trees, b, i, s,                   doEA(trees, b, i, s,
332                        I.ImmedLabel(LE.PLUS(le,LE.INT(Int32.toInt m)))                        I.ImmedLabel(T.ADD(32,le,T.LI(T.I.fromInt32(32, m))))
333                        handle Overflow => error "doEALabel: constant too large")                        handle Overflow => error "doEALabel: constant too large")
334              | doEALabel(trees, le, b, i, s, I.ImmedLabel le') =              | doEALabel(trees, le, b, i, s, I.ImmedLabel le') =
335                   doEA(trees, b, i, s, I.ImmedLabel(LE.PLUS(le,le')))                   doEA(trees, b, i, s, I.ImmedLabel(T.ADD(32,le,le')))
336              | doEALabel(trees, le, b, i, s, _) = error "doEALabel"              | doEALabel(trees, le, b, i, s, _) = error "doEALabel"
337    
338            and makeAddressingMode(NONE, NONE, _, disp) = disp            and makeAddressingMode(NONE, NONE, _, disp) = disp
# Line 408  Line 389 
389        end (* address *)        end (* address *)
390    
391            (* reduce an expression into an operand *)            (* reduce an expression into an operand *)
392        and operand(T.LI i) = I.Immed(toInt32 i)        and operand(T.LI i) = I.Immed(toInt32(i))
393          | operand(T.LI32 w) = I.Immed(wToInt32 w)          | operand(x as (T.CONST _ | T.LABEL _)) = I.ImmedLabel x
394          | operand(T.CONST c) = I.ImmedLabel(LE.CONST c)          | operand(T.LABEXP le) = I.ImmedLabel le
         | operand(T.LABEL lab) = I.ImmedLabel lab  
395          | operand(T.REG(_,r)) = IntReg r          | operand(T.REG(_,r)) = IntReg r
396          | operand(T.LOAD(32,ea,mem)) = address(ea, mem)          | operand(T.LOAD(32,ea,mem)) = address(ea, mem)
397          | operand(t) = I.Direct(expr t)          | operand(t) = I.Direct(expr t)
# Line 540  Line 520 
520                end                end
521    
522                    (* Optimize the special case for division *)                    (* Optimize the special case for division *)
523                fun divide(signed, overflow, e1, e2 as T.LI n) =                fun divide(signed, overflow, e1, e2 as T.LI n') = let
524                let fun isPowerOf2 w = Word.andb((w - 0w1), w) = 0w0                    val n = toInt32 n'
525                      val w = T.I.toWord32(32, n')
526                      fun isPowerOf2 w = W32.andb((w - 0w1), w) = 0w0
527                    fun log2 n =  (* n must be > 0!!! *)                    fun log2 n =  (* n must be > 0!!! *)
528                        let fun loop(0w1,pow) = pow                        let fun loop(0w1,pow) = pow
529                              | loop(w,pow) = loop(Word.>>(w, 0w1),pow+1)                              | loop(w,pow) = loop(W32.>>(w, 0w1),pow+1)
530                        in loop(n,0) end                        in loop(n,0) end
                   val w = Word.fromInt n  
531                in  if n > 1 andalso isPowerOf2 w then                in  if n > 1 andalso isPowerOf2 w then
532                       let val pow = T.LI(log2 w)                       let val pow = T.LI(T.I.fromInt(32,log2 w))
533                       in  if signed then                       in  if signed then
534                           (* signed; simulate round towards zero *)                           (* signed; simulate round towards zero *)
535                           let val label = Label.newLabel ""                           let val label = Label.newLabel ""
# Line 561  Line 542 
542                                       I.UNARY{unOp=I.INCL, opnd=opnd1}                                       I.UNARY{unOp=I.INCL, opnd=opnd1}
543                                    else                                    else
544                                       I.BINARY{binOp=I.ADDL,                                       I.BINARY{binOp=I.ADDL,
545                                                src=I.Immed(toInt32 n - 1),                                                src=I.Immed(n - 1),
546                                                dst=opnd1});                                                dst=opnd1});
547                               defineLabel label;                               defineLabel label;
548                               shift(I.SARL, T.REG(32, reg1), pow)                               shift(I.SARL, T.REG(32, reg1), pow)
# Line 793  Line 774 
774                            move'(tmp, rdOpnd, [])                            move'(tmp, rdOpnd, [])
775                        end                        end
776                     else move'(IntReg rs, rdOpnd, an)                     else move'(IntReg rs, rdOpnd, an)
777               | (T.LI 0 | T.LI32 0w0) =>               | T.LI z => let
778                     val n = toInt32 z
779                   in
780                     if n=0 then
781                   (* As per Fermin's request, special optimization for rd := 0.                   (* As per Fermin's request, special optimization for rd := 0.
782                    * Currently we don't bother with the size.                    * Currently we don't bother with the size.
783                    *)                    *)
784                   if isMemReg rd then move'(I.Immed 0, rdOpnd, an)                   if isMemReg rd then move'(I.Immed 0, rdOpnd, an)
785                   else mark(I.BINARY{binOp=I.XORL, src=rdOpnd, dst=rdOpnd}, an)                   else mark(I.BINARY{binOp=I.XORL, src=rdOpnd, dst=rdOpnd}, an)
786               | T.LI n      => move'(I.Immed(toInt32 n), rdOpnd, an)                   else
787               | T.LI32 w    => move'(I.Immed(wToInt32 w), rdOpnd, an)                     move'(I.Immed(n), rdOpnd, an)
788               | T.CONST c   => move'(I.ImmedLabel(LE.CONST c), rdOpnd, an)                 end
789               | T.LABEL lab => move'(I.ImmedLabel lab, rdOpnd, an)               | (T.CONST _ | T.LABEL _) =>
790                     move'(I.ImmedLabel exp, rdOpnd, an)
791                 | T.LABEXP le => move'(I.ImmedLabel le, 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 860  Line 869 
869               | T.LOAD(8, ea, mem) => load8(ea, mem)               | T.LOAD(8, ea, mem) => load8(ea, mem)
870               | T.LOAD(16, ea, mem) => load16(ea, mem)               | T.LOAD(16, ea, mem) => load16(ea, mem)
871               | T.LOAD(32, ea, mem) => load32(ea, mem)               | T.LOAD(32, ea, mem) => load32(ea, mem)
872               | T.SX(_,_,T.LOAD(8,ea,mem)) => load8s(ea, mem)  
873               | T.SX(_,_,T.LOAD(16,ea,mem)) => load16s(ea, mem)               | T.SX(32,8,T.LOAD(8,ea,mem)) => load8s(ea, mem)
874                 | T.SX(32,16,T.LOAD(16,ea,mem)) => load16s(ea, mem)
875                 | T.ZX(32,8,T.LOAD(8,ea,mem)) => load8(ea, mem)
876                 | T.ZX(32,16,T.LOAD(16,ea,mem)) => load16(ea, mem)
877    
878               | 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) =>
879                   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)  
880               | T.COND(32, T.CMP(ty, cc, t1, t2), yes, no) =>               | T.COND(32, T.CMP(ty, cc, t1, t2), yes, no) =>
881                  (case !arch of (* PentiumPro and higher has CMOVcc *)                  (case !arch of (* PentiumPro and higher has CMOVcc *)
882                     Pentium => unknownExp exp                     Pentium => unknownExp exp
# Line 1003  Line 1012 
1012            end            end
1013    
1014            (* generate code for jumps *)            (* generate code for jumps *)
1015        and jmp(T.LABEL(lexp as LE.LABEL lab), labs, an) =        and jmp(lexp as T.LABEL lab, labs, an) =
1016               mark(I.JMP(I.ImmedLabel lexp, [lab]), an)               mark(I.JMP(I.ImmedLabel lexp, [lab]), an)
1017          | jmp(T.LABEL lexp, labs, an) = mark(I.JMP(I.ImmedLabel lexp, labs), an)          | jmp(T.LABEXP le, labs, an) = mark(I.JMP(I.ImmedLabel le, labs), an)
1018          | jmp(ea, labs, an)           = mark(I.JMP(operand ea, labs), an)          | jmp(ea, labs, an)           = mark(I.JMP(operand ea, labs), an)
1019    
1020         (* convert mlrisc to cellset:         (* convert mlrisc to cellset:

Legend:
Removed from v.744  
changed lines
  Added in v.779

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