Bug 1279248 - Part 6: Implement the 64bit variant of BitOp on x86, r=bbouvier
authorHannes Verschore <hv1989@gmail.com>
Fri, 29 Jul 2016 16:51:41 +0200
changeset 347327 02f604c9ad7330732c13792141aa24dc5f0c4d92
parent 347326 27826b22e1406ba39e5bc6f11546f411b7ad7324
child 347328 e3e8bb6b8d812c9ec3f2003fe1cf0c7e2af8d3f2
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1279248
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1279248 - Part 6: Implement the 64bit variant of BitOp on x86, r=bbouvier
js/src/jit/MacroAssembler.h
js/src/jit/x64/CodeGenerator-x64.cpp
js/src/jit/x64/CodeGenerator-x64.h
js/src/jit/x64/MacroAssembler-x64-inl.h
js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
js/src/jit/x86-shared/CodeGenerator-x86-shared.h
js/src/jit/x86/MacroAssembler-x86-inl.h
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -714,25 +714,30 @@ class MacroAssembler : public MacroAssem
 
     inline void or32(Register src, Register dest) PER_SHARED_ARCH;
     inline void or32(Imm32 imm, Register dest) PER_SHARED_ARCH;
     inline void or32(Imm32 imm, const Address& dest) PER_SHARED_ARCH;
 
     inline void orPtr(Register src, Register dest) PER_ARCH;
     inline void orPtr(Imm32 imm, Register dest) PER_ARCH;
 
+    inline void and64(Register64 src, Register64 dest) DEFINED_ON(x86);
     inline void or64(Register64 src, Register64 dest) PER_ARCH;
     inline void xor64(Register64 src, Register64 dest) PER_ARCH;
 
     inline void xor32(Register src, Register dest) PER_SHARED_ARCH;
     inline void xor32(Imm32 imm, Register dest) PER_SHARED_ARCH;
 
     inline void xorPtr(Register src, Register dest) PER_ARCH;
     inline void xorPtr(Imm32 imm, Register dest) PER_ARCH;
 
+    inline void and64(const Operand& src, Register64 dest) DEFINED_ON(x64);
+    inline void or64(const Operand& src, Register64 dest) DEFINED_ON(x64);
+    inline void xor64(const Operand& src, Register64 dest) DEFINED_ON(x64);
+
     // ===============================================================
     // Arithmetic functions
 
     inline void add32(Register src, Register dest) PER_SHARED_ARCH;
     inline void add32(Imm32 imm, Register dest) PER_SHARED_ARCH;
     inline void add32(Imm32 imm, const Address& dest) PER_SHARED_ARCH;
     inline void add32(Imm32 imm, const AbsoluteAddress& dest) DEFINED_ON(x86_shared);
 
--- a/js/src/jit/x64/CodeGenerator-x64.cpp
+++ b/js/src/jit/x64/CodeGenerator-x64.cpp
@@ -258,46 +258,16 @@ CodeGeneratorX64::visitCompareI64AndBran
         masm.cmpPtr(lhsReg, Operand(rhsReg));
     }
 
     bool isSigned = mir->compareType() == MCompare::Compare_Int64;
     emitBranch(JSOpToCondition(lir->jsop(), isSigned), lir->ifTrue(), lir->ifFalse());
 }
 
 void
-CodeGeneratorX64::visitBitOpI64(LBitOpI64* lir)
-{
-    Register lhs = ToRegister(lir->getOperand(0));
-    const LAllocation* rhs = lir->getOperand(1);
-
-    switch (lir->bitop()) {
-      case JSOP_BITOR:
-        if (rhs->isConstant())
-            masm.or64(Imm64(ToInt64(rhs)), Register64(lhs));
-        else
-            masm.orq(ToOperand(rhs), lhs);
-        break;
-      case JSOP_BITXOR:
-        if (rhs->isConstant())
-            masm.xor64(Imm64(ToInt64(rhs)), Register64(lhs));
-        else
-            masm.xorq(ToOperand(rhs), lhs);
-        break;
-      case JSOP_BITAND:
-        if (rhs->isConstant())
-            masm.and64(Imm64(ToInt64(rhs)), Register64(lhs));
-        else
-            masm.andq(ToOperand(rhs), lhs);
-        break;
-      default:
-        MOZ_CRASH("unexpected binary opcode");
-    }
-}
-
-void
 CodeGeneratorX64::visitRotate64(LRotate64* lir)
 {
     MRotate* mir = lir->mir();
     Register input = ToRegister(lir->input());
     const LAllocation* count = lir->count();
 
     if (count->isConstant()) {
         int32_t c = int32_t(ToInt64(count) & 0x3F);
--- a/js/src/jit/x64/CodeGenerator-x64.h
+++ b/js/src/jit/x64/CodeGenerator-x64.h
@@ -47,17 +47,16 @@ class CodeGeneratorX64 : public CodeGene
     void visitBox(LBox* box);
     void visitUnbox(LUnbox* unbox);
     void visitCompareB(LCompareB* lir);
     void visitCompareBAndBranch(LCompareBAndBranch* lir);
     void visitCompareBitwise(LCompareBitwise* lir);
     void visitCompareBitwiseAndBranch(LCompareBitwiseAndBranch* lir);
     void visitCompareI64(LCompareI64* lir);
     void visitCompareI64AndBranch(LCompareI64AndBranch* lir);
-    void visitBitOpI64(LBitOpI64* lir);
     void visitRotate64(LRotate64* lir);
     void visitAddI64(LAddI64* lir);
     void visitSubI64(LSubI64* lir);
     void visitMulI64(LMulI64* lir);
     void visitDivOrModI64(LDivOrModI64* lir);
     void visitUDivOrMod64(LUDivOrMod64* lir);
     void visitNotI64(LNotI64* lir);
     void visitClzI64(LClzI64* lir);
--- a/js/src/jit/x64/MacroAssembler-x64-inl.h
+++ b/js/src/jit/x64/MacroAssembler-x64-inl.h
@@ -108,16 +108,34 @@ MacroAssembler::xorPtr(Register src, Reg
 }
 
 void
 MacroAssembler::xorPtr(Imm32 imm, Register dest)
 {
     xorq(imm, dest);
 }
 
+void
+MacroAssembler::and64(const Operand& src, Register64 dest)
+{
+    andq(src, dest.reg);
+}
+
+void
+MacroAssembler::or64(const Operand& src, Register64 dest)
+{
+    orq(src, dest.reg);
+}
+
+void
+MacroAssembler::xor64(const Operand& src, Register64 dest)
+{
+    xorq(src, dest.reg);
+}
+
 // ===============================================================
 // Arithmetic functions
 
 void
 MacroAssembler::addPtr(Register src, Register dest)
 {
     addq(src, dest);
 }
--- a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
@@ -1662,16 +1662,48 @@ CodeGeneratorX86Shared::visitBitOpI(LBit
                 masm.andl(ToOperand(rhs), ToRegister(lhs));
             break;
         default:
             MOZ_CRASH("unexpected binary opcode");
     }
 }
 
 void
+CodeGeneratorX86Shared::visitBitOpI64(LBitOpI64* lir)
+{
+    const LInt64Allocation lhs = lir->getInt64Operand(LBitOpI64::Lhs);
+    const LInt64Allocation rhs = lir->getInt64Operand(LBitOpI64::Rhs);
+
+    MOZ_ASSERT(ToOutRegister64(lir) == ToRegister64(lhs));
+
+    switch (lir->bitop()) {
+      case JSOP_BITOR:
+        if (IsConstant(rhs))
+            masm.or64(Imm64(ToInt64(rhs)), ToRegister64(lhs));
+        else
+            masm.or64(ToOperandOrRegister64(rhs), ToRegister64(lhs));
+        break;
+      case JSOP_BITXOR:
+        if (IsConstant(rhs))
+            masm.xor64(Imm64(ToInt64(rhs)), ToRegister64(lhs));
+        else
+            masm.xor64(ToOperandOrRegister64(rhs), ToRegister64(lhs));
+        break;
+      case JSOP_BITAND:
+        if (IsConstant(rhs))
+            masm.and64(Imm64(ToInt64(rhs)), ToRegister64(lhs));
+        else
+            masm.and64(ToOperandOrRegister64(rhs), ToRegister64(lhs));
+        break;
+      default:
+        MOZ_CRASH("unexpected binary opcode");
+    }
+}
+
+void
 CodeGeneratorX86Shared::visitShiftI(LShiftI* ins)
 {
     Register lhs = ToRegister(ins->lhs());
     const LAllocation* rhs = ins->rhs();
 
     if (rhs->isConstant()) {
         int32_t shift = ToInt32(rhs) & 0x1F;
         switch (ins->bitop()) {
--- a/js/src/jit/x86-shared/CodeGenerator-x86-shared.h
+++ b/js/src/jit/x86-shared/CodeGenerator-x86-shared.h
@@ -242,16 +242,17 @@ class CodeGeneratorX86Shared : public Co
     virtual void visitMulI(LMulI* ins);
     virtual void visitDivI(LDivI* ins);
     virtual void visitDivPowTwoI(LDivPowTwoI* ins);
     virtual void visitDivOrModConstantI(LDivOrModConstantI* ins);
     virtual void visitModI(LModI* ins);
     virtual void visitModPowTwoI(LModPowTwoI* ins);
     virtual void visitBitNotI(LBitNotI* ins);
     virtual void visitBitOpI(LBitOpI* ins);
+    virtual void visitBitOpI64(LBitOpI64* ins);
     virtual void visitShiftI(LShiftI* ins);
     virtual void visitShiftI64(LShiftI64* ins);
     virtual void visitUrshD(LUrshD* ins);
     virtual void visitTestIAndBranch(LTestIAndBranch* test);
     virtual void visitTestDAndBranch(LTestDAndBranch* test);
     virtual void visitTestFAndBranch(LTestFAndBranch* test);
     virtual void visitCompare(LCompare* comp);
     virtual void visitCompareAndBranch(LCompareAndBranch* comp);
--- a/js/src/jit/x86/MacroAssembler-x86-inl.h
+++ b/js/src/jit/x86/MacroAssembler-x86-inl.h
@@ -43,47 +43,60 @@ void
 MacroAssembler::andPtr(Imm32 imm, Register dest)
 {
     andl(imm, dest);
 }
 
 void
 MacroAssembler::and64(Imm64 imm, Register64 dest)
 {
-    andl(Imm32(imm.value & 0xFFFFFFFFL), dest.low);
-    andl(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high);
+    if (imm.low().value != int32_t(0xFFFFFFFF))
+        andl(imm.low(), dest.low);
+    if (imm.hi().value != int32_t(0xFFFFFFFF))
+        andl(imm.hi(), dest.high);
 }
 
 void
 MacroAssembler::or64(Imm64 imm, Register64 dest)
 {
-    orl(Imm32(imm.value & 0xFFFFFFFFL), dest.low);
-    orl(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high);
+    if (imm.low().value != 0)
+        orl(imm.low(), dest.low);
+    if (imm.hi().value != 0)
+        orl(imm.hi(), dest.high);
 }
 
 void
 MacroAssembler::xor64(Imm64 imm, Register64 dest)
 {
-    xorl(Imm32(imm.value & 0xFFFFFFFFL), dest.low);
-    xorl(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high);
+    if (imm.low().value != 0)
+        xorl(imm.low(), dest.low);
+    if (imm.hi().value != 0)
+        xorl(imm.hi(), dest.high);
 }
 
 void
 MacroAssembler::orPtr(Register src, Register dest)
 {
     orl(src, dest);
 }
 
 void
 MacroAssembler::orPtr(Imm32 imm, Register dest)
 {
     orl(imm, dest);
 }
 
 void
+MacroAssembler::and64(Register64 src, Register64 dest)
+{
+    andl(src.low, dest.low);
+    andl(src.high, dest.high);
+}
+
+void
 MacroAssembler::or64(Register64 src, Register64 dest)
 {
     orl(src.low, dest.low);
     orl(src.high, dest.high);
 }
 
 void
 MacroAssembler::xor64(Register64 src, Register64 dest)