Bug 1289054 - Part 10: Implement the 64bit variant of BitOp on arm, r=bbouvier
authorHannes Verschore <hv1989@gmail.com>
Fri, 29 Jul 2016 16:53:49 +0200
changeset 332393 d2e991415189568ea0f906e0912aa8d1de44694c
parent 332392 65981e46881a04d3b36fd9fbd69cb79169d75e83
child 332394 9ae4ad38a4b390c75efddb3a4f718c997248b5e8
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1289054
milestone50.0a1
Bug 1289054 - Part 10: Implement the 64bit variant of BitOp on arm, r=bbouvier
js/src/jit-test/tests/wasm/basic-integer.js
js/src/jit/MacroAssembler.h
js/src/jit/arm/CodeGenerator-arm.cpp
js/src/jit/arm/CodeGenerator-arm.h
js/src/jit/arm/MacroAssembler-arm-inl.h
--- a/js/src/jit-test/tests/wasm/basic-integer.js
+++ b/js/src/jit-test/tests/wasm/basic-integer.js
@@ -197,16 +197,18 @@ if (hasI64()) {
     testBinary64('shr_u', -40, 2, "0x3ffffffffffffff6");
     testBinary64('shl', 0xff00ff, 28, "0xff00ff0000000");
     testBinary64('shl', 1, 63, "0x8000000000000000");
     testBinary64('shl', 1, 64, 1);
     testBinary64('shr_s', "0xff00ff0000000", 28, 0xff00ff);
     testBinary64('shr_u', "0x8ffff00ff0000000", 56, 0x8f);
     testBinary64('rotl', 40, 2, 160);
     testBinary64('rotr', 40, 2, 10);
+    testBinary64('and', 42, 0, 0);
+    testBinary64('and', "0x0000000012345678", "0xffff0000ffff0000", "0x0000000012340000");
 
     testComparison64('eq', 40, 40, 1);
     testComparison64('ne', 40, 40, 0);
     testComparison64('lt_s', 40, 40, 0);
     testComparison64('lt_u', 40, 40, 0);
     testComparison64('le_s', 40, 40, 1);
     testComparison64('le_u', 40, 40, 1);
     testComparison64('gt_s', 40, 40, 0);
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -716,17 +716,17 @@ 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 and64(Register64 src, Register64 dest) DEFINED_ON(x86, arm);
     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;
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -3292,8 +3292,40 @@ CodeGeneratorARM::visitShiftI64(LShiftI6
         break;
       case JSOP_URSH:
         masm.rshift64(ToRegister(rhs), ToRegister64(lhs));
         break;
       default:
         MOZ_CRASH("Unexpected shift op");
     }
 }
+
+void
+CodeGeneratorARM::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");
+    }
+}
--- a/js/src/jit/arm/CodeGenerator-arm.h
+++ b/js/src/jit/arm/CodeGenerator-arm.h
@@ -162,16 +162,17 @@ class CodeGeneratorARM : public CodeGene
     virtual void visitExtendInt32ToInt64(LExtendInt32ToInt64* lir);
     virtual void visitAddI64(LAddI64* lir);
     virtual void visitSubI64(LSubI64* lir);
     virtual void visitMulI64(LMulI64* lir);
     virtual void visitDivOrModI64(LDivOrModI64* lir);
     virtual void visitUDivOrModI64(LUDivOrModI64* lir);
     virtual void visitCompareI64(LCompareI64* lir);
     virtual void visitCompareI64AndBranch(LCompareI64AndBranch* lir);
+    virtual void visitBitOpI64(LBitOpI64* lir);
 
     // Out of line visitors.
     void visitOutOfLineBailout(OutOfLineBailout* ool);
     void visitOutOfLineTableSwitch(OutOfLineTableSwitch* ool);
 
   protected:
     ValueOperand ToValue(LInstruction* ins, size_t pos);
     ValueOperand ToOutValue(LInstruction* ins);
--- a/js/src/jit/arm/MacroAssembler-arm-inl.h
+++ b/js/src/jit/arm/MacroAssembler-arm-inl.h
@@ -88,32 +88,38 @@ void
 MacroAssembler::andPtr(Imm32 imm, Register dest)
 {
     ma_and(imm, dest);
 }
 
 void
 MacroAssembler::and64(Imm64 imm, Register64 dest)
 {
-    and32(Imm32(imm.value & 0xFFFFFFFFL), dest.low);
-    and32(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high);
+    if (imm.low().value != int32_t(0xFFFFFFFF))
+        and32(imm.low(), dest.low);
+    if (imm.hi().value != int32_t(0xFFFFFFFF))
+        and32(imm.hi(), dest.high);
 }
 
 void
 MacroAssembler::or64(Imm64 imm, Register64 dest)
 {
-    or32(Imm32(imm.value & 0xFFFFFFFFL), dest.low);
-    or32(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high);
+    if (imm.low().value)
+        or32(imm.low(), dest.low);
+    if (imm.hi().value)
+        or32(imm.hi(), dest.high);
 }
 
 void
 MacroAssembler::xor64(Imm64 imm, Register64 dest)
 {
-    xor32(Imm32(imm.value & 0xFFFFFFFFL), dest.low);
-    xor32(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high);
+    if (imm.low().value)
+        xor32(imm.low(), dest.low);
+    if (imm.hi().value)
+        xor32(imm.hi(), dest.high);
 }
 
 void
 MacroAssembler::or32(Register src, Register dest)
 {
     ma_orr(src, dest);
 }
 
@@ -140,16 +146,23 @@ MacroAssembler::orPtr(Register src, Regi
 
 void
 MacroAssembler::orPtr(Imm32 imm, Register dest)
 {
     ma_orr(imm, dest);
 }
 
 void
+MacroAssembler::and64(Register64 src, Register64 dest)
+{
+    and32(src.low, dest.low);
+    and32(src.high, dest.high);
+}
+
+void
 MacroAssembler::or64(Register64 src, Register64 dest)
 {
     or32(src.low, dest.low);
     or32(src.high, dest.high);
 }
 
 void
 MacroAssembler::xor64(Register64 src, Register64 dest)