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 694, Thu Jul 27 16:00:25 2000 UTC revision 695, Mon Aug 7 23:57:38 2000 UTC
# Line 175  Line 175 
175          | setZeroBit(T.SRA _)      = true          | setZeroBit(T.SRA _)      = true
176          | setZeroBit(T.SRL _)      = true          | setZeroBit(T.SRL _)      = true
177          | setZeroBit(T.SLL _)      = true          | setZeroBit(T.SLL _)      = true
178            | setZeroBit(T.SUB _)      = true
179            | setZeroBit(T.ADDT _)     = true
180            | setZeroBit(T.SUBT _)     = true
181          | setZeroBit(T.MARK(e, _)) = setZeroBit e          | setZeroBit(T.MARK(e, _)) = setZeroBit e
182          | setZeroBit _             = false          | setZeroBit _             = false
183    
184          fun setZeroBit2(T.ANDB _)     = true
185            | setZeroBit2(T.ORB _)      = true
186            | setZeroBit2(T.XORB _)     = true
187            | setZeroBit2(T.SRA _)      = true
188            | setZeroBit2(T.SRL _)      = true
189            | setZeroBit2(T.SLL _)      = true
190            | setZeroBit2(T.ADD(32, _, _)) = true (* can't use leal! *)
191            | setZeroBit2(T.SUB _)      = true
192            | setZeroBit2(T.ADDT _)     = true
193            | setZeroBit2(T.SUBT _)     = true
194            | setZeroBit2(T.MARK(e, _)) = setZeroBit2 e
195            | setZeroBit2 _             = false
196    
197        (* emit parallel copies for floating point *)        (* emit parallel copies for floating point *)
198        fun fcopy(fty, [], [], _) = ()        fun fcopy(fty, [], [], _) = ()
199          | fcopy(fty, dst as [_], src as [_], an) =          | fcopy(fty, dst as [_], src as [_], an) =
# Line 602  Line 618 
618                     * only writes to the low order                     * only writes to the low order
619                     * byte.  That's Intel architecture, folks.                     * byte.  That's Intel architecture, folks.
620                     *)                     *)
621                    zero eax;                    case (yes, no, cc) of
622                    case (yes, no) of                      (1, 0, T.LT) =>
623                      (1, 0) => (* normal case *)                       let val tmp = I.Direct(expr(T.SUB(32,t1,t2)))
624                         in  move(tmp, rdOpnd);
625                             emit(I.BINARY{binOp=I.SHRL,src=I.Immed 31,dst=rdOpnd})
626                         end
627                      | (1, 0, T.GT) =>
628                         let val tmp = I.Direct(expr(T.SUB(32,t1,t2)))
629                         in  emit(I.UNARY{unOp=I.NOTL,opnd=tmp});
630                             move(tmp, rdOpnd);
631                             emit(I.BINARY{binOp=I.SHRL,src=I.Immed 31,dst=rdOpnd})
632                         end
633                      | (1, 0, _) => (* normal case *)
634                      let val cc = cmp(true, ty, cc, t1, t2, [])                      let val cc = cmp(true, ty, cc, t1, t2, [])
635                      in  mark(I.SET{cond=cond cc, opnd=eax}, an);                      in  mark(I.SET{cond=cond cc, opnd=eax}, an);
636                            emit(I.BINARY{binOp=I.ANDL,src=I.Immed 255, dst=eax});
637                          move(eax, rdOpnd)                          move(eax, rdOpnd)
638                      end                      end
639                    | (C1, C2)  =>                    | (C1, C2, _)  =>
640                      (* general case;                      (* general case;
641                       * from the Intel optimization guide p3-5                       * from the Intel optimization guide p3-5
642                       *)                       *)
643                      let val cc = cmp(true, ty, cc, t1, t2, [])                      let val _  = zero eax;
644                            val cc = cmp(true, ty, cc, t1, t2, [])
645                      in  case C1-C2 of                      in  case C1-C2 of
646                            D as (1 | 2 | 3 | 4 | 5 | 8 | 9) =>                            D as (1 | 2 | 3 | 4 | 5 | 8 | 9) =>
647                            let val (base,scale) =                            let val (base,scale) =
# Line 720  Line 748 
748               | T.ADD(32, T.LI ~1, e) => unary(I.DECL, e)               | T.ADD(32, T.LI ~1, e) => unary(I.DECL, e)
749               | T.ADD(32, e1, e2) => addition(e1, e2)               | T.ADD(32, e1, e2) => addition(e1, e2)
750    
751                   (* 32-bit addition but set the flag!
752                    * This is a stupid hack for now.
753                    *)
754                 | T.ADD(0, e, (T.LI 1|T.LI32 0w1)) => unary(I.INCL, e)
755                 | T.ADD(0, (T.LI 1|T.LI32 0w1), e) => unary(I.INCL, e)
756                 | T.ADD(0, e, T.LI ~1) => unary(I.DECL, e)
757                 | T.ADD(0, T.LI ~1, e) => unary(I.DECL, e)
758                 | T.ADD(0, e1, e2) => binaryComm(I.ADDL, e1, e2)
759    
760                 (* 32-bit subtraction *)                 (* 32-bit subtraction *)
761                 | T.SUB(32, e, (T.LI 0 | T.LI32 0w0)) => doExpr(e, rd, an)
762               | T.SUB(32, e, (T.LI 1 | T.LI32 0w1)) => unary(I.DECL, e)               | T.SUB(32, e, (T.LI 1 | T.LI32 0w1)) => unary(I.DECL, e)
763               | T.SUB(32, e, T.LI ~1) => unary(I.INCL, e)               | T.SUB(32, e, T.LI ~1) => unary(I.INCL, e)
764               | T.SUB(32, (T.LI 0 | T.LI32 0w0), e) => unary(I.NEGL, e)               | T.SUB(32, (T.LI 0 | T.LI32 0w0), e) => unary(I.NEGL, e)
# Line 797  Line 835 
835            * On the x86, TEST is superior to AND for doing the same thing,            * On the x86, TEST is superior to AND for doing the same thing,
836            * since it doesn't need to write out the result in a register.            * since it doesn't need to write out the result in a register.
837            *)            *)
838       and cmpWithZero(cc as (T.EQ | T.NE), e as T.ANDB(ty, a, b))  =       and cmpWithZero(cc as (T.EQ | T.NE), e as T.ANDB(ty, a, b), an) =
839              (case ty of              (case ty of
840                 8 =>  test(I.TESTB, a, b)                 8  => test(I.TESTB, a, b, an)
841               | 16 => test(I.TESTW, a, b)               | 16 => test(I.TESTW, a, b, an)
842               | 32 => test(I.TESTL, a, b)               | 32 => test(I.TESTL, a, b, an)
843               | _  => (expr e; ())               | _  => doExpr(e, newReg(), an);
844               ; cc)               cc)
845          | cmpWithZero(cc, e) = (expr e; cc)          | cmpWithZero(cc, e, an) =
846              let val e =
847                    case e of (* hack to disable the lea optimization XXX *)
848                      T.ADD(_, a, b) => T.ADD(0, a, b)
849                    | e => e
850              in  doExpr(e, newReg(), an); cc end
851    
852            (* Emit a test.            (* Emit a test.
853             *   The available modes are             *   The available modes are
# Line 821  Line 864 
864             * are one of EAX, ECX, EBX, or EDX, replace the TESTL instruction             * are one of EAX, ECX, EBX, or EDX, replace the TESTL instruction
865             * by TESTB.             * by TESTB.
866             *)             *)
867        and test(testopcode, a, b) =        and test(testopcode, a, b, an) =
868            let val (_, opnd1, opnd2) = commuteComparison(T.EQ, true, a, b)            let val (_, opnd1, opnd2) = commuteComparison(T.EQ, true, a, b)
869                (* translate r, r/m => r/m, r *)                (* translate r, r/m => r/m, r *)
870                val (opnd1, opnd2) =                val (opnd1, opnd2) =
871                     if isMemOpnd opnd2 then (opnd2, opnd1) else (opnd1, opnd2)                     if isMemOpnd opnd2 then (opnd2, opnd1) else (opnd1, opnd2)
872            in  emit(testopcode{lsrc=opnd1, rsrc=opnd2})            in  mark(testopcode{lsrc=opnd1, rsrc=opnd2}, an)
873            end            end
874    
875           (* generate a condition code expression           (* generate a condition code expression
# Line 848  Line 891 
891             * we can also reorder the operands.             * we can also reorder the operands.
892             *)             *)
893        and cmp(swapable, ty, cc, t1, t2, an) =        and cmp(swapable, ty, cc, t1, t2, an) =
894            (case cc of                 (* == and <> can be always be reordered *)
895               (T.EQ | T.NE) =>            let val swapable = swapable orelse cc = T.EQ orelse cc = T.NE
896                (* Sometimes the comparison is not necessary because            in (* Sometimes the comparison is not necessary because
897                 * the bits are already set!                 * the bits are already set!
898                 *)                 *)
899                if isZero t1 andalso setZeroBit t2 then cmpWithZero(cc, t2)               if isZero t1 andalso setZeroBit2 t2 then
900                else if isZero t2 andalso setZeroBit t1 then cmpWithZero(cc, t1)                   if swapable then
901                     (* == and <> can be reordered *)                      cmpWithZero(T.Basis.swapCond cc, t2, an)
902                else genCmp(ty, true, cc, t1, t2, an)                   else (* can't reorder the comparison! *)
903             |  _ => genCmp(ty, swapable, cc, t1, t2, an)                      genCmp(ty, false, cc, t1, t2, an)
904            )               else if isZero t2 andalso setZeroBit2 t1 then
905                    cmpWithZero(cc, t1, an)
906                 else genCmp(ty, swapable, cc, t1, t2, an)
907              end
908    
909            (* Give a and b which are the operands to a comparison (or test)            (* Give a and b which are the operands to a comparison (or test)
910             * Return the appropriate condition code and operands.             * Return the appropriate condition code and operands.

Legend:
Removed from v.694  
changed lines
  Added in v.695

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