Bug 1301400: Baseline Wasm Compiler: Part 20: Don't fully generalize when functions are not yet available on every platform, r=lth
authorh4writer <hv1989@gmail.com>
Thu, 29 Sep 2016 22:33:23 +0200
changeset 315912 9643bfae6b315489c3fbafc7fac15d5e241ca585
parent 315911 ef4dbc8dc886d39bea1bb5042694501c0f5d2263
child 315913 8b70b53f6f27a27716706ed305ff69cb17b59606
push id30757
push usercbook@mozilla.com
push dateFri, 30 Sep 2016 10:02:43 +0000
treeherdermozilla-central@5ffed033557e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslth
bugs1301400
milestone52.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 1301400: Baseline Wasm Compiler: Part 20: Don't fully generalize when functions are not yet available on every platform, r=lth
js/src/asmjs/WasmBaselineCompile.cpp
--- a/js/src/asmjs/WasmBaselineCompile.cpp
+++ b/js/src/asmjs/WasmBaselineCompile.cpp
@@ -2117,24 +2117,26 @@ class BaseCompiler
                 loadI32(argLoc.gpr(), arg);
             }
             break;
           }
           case ValType::I64: {
             ABIArg argLoc = call.abi_.next(MIRType::Int64);
             if (argLoc.kind() == ABIArg::Stack) {
                 ScratchI32 scratch(*this);
-#ifdef JS_PUNBOX64
+#if defined(JS_CODEGEN_X64)
                 loadI64(Register64(scratch), arg);
                 masm.movq(scratch, Operand(StackPointer, argLoc.offsetFromArgBase()));
-#else
+#elif defined(JS_CODEGEN_X86)
                 loadI64Low(scratch, arg);
                 masm.move32(scratch, Operand(StackPointer, argLoc.offsetFromArgBase() + INT64LOW_OFFSET));
                 loadI64High(scratch, arg);
                 masm.move32(scratch, Operand(StackPointer, argLoc.offsetFromArgBase() + INT64HIGH_OFFSET));
+#else
+                MOZ_CRASH("BaseCompiler platform hook: passArg I64");
 #endif
             } else {
                 loadI64(argLoc.gpr64(), arg);
             }
             break;
           }
           case ValType::F64: {
             ABIArg argLoc = call.abi_.next(MIRType::Double);
@@ -2364,25 +2366,33 @@ class BaseCompiler
 
     void returnF32(RegF32 r) {
         moveF32(r, RegF32(ReturnFloat32Reg));
         popStackBeforeBranch(ctl_[0].framePushed);
         masm.jump(&returnLabel_);
     }
 
     void subtractI64(RegI64 rhs, RegI64 srcDest) {
+#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)
         masm.sub64(rhs.reg, srcDest.reg);
+#else
+        MOZ_CRASH("BaseCompiler platform hook: subtractI64");
+#endif
     }
 
     void multiplyI64(RegI64 rhs, RegI64 srcDest, RegI32 temp) {
 #if defined(JS_CODEGEN_X64)
         MOZ_ASSERT(srcDest.reg.reg == rax);
         MOZ_ASSERT(isAvailable(rdx));
+        masm.mul64(rhs.reg, srcDest.reg, temp.reg);
+#elif defined(JS_CODEGEN_X86)
+        masm.mul64(rhs.reg, srcDest.reg, temp.reg);
+#else
+        MOZ_CRASH("BaseCompiler platform hook: multiplyI64");
 #endif
-        masm.mul64(rhs.reg, srcDest.reg, temp.reg);
     }
 
     void checkDivideByZeroI32(RegI32 rhs, RegI32 srcDest, Label* done) {
         if (isCompilingAsmJS()) {
             // Truncated division by zero is zero (Infinity|0 == 0)
             Label notDivByZero;
             masm.branchTest32(Assembler::NonZero, rhs.reg, rhs.reg, &notDivByZero);
             masm.move32(Imm32(0), srcDest.reg);
@@ -2393,22 +2403,24 @@ class BaseCompiler
         }
     }
 
     void checkDivideByZeroI64(RegI64 rhs, RegI64 srcDest, Label* done) {
         MOZ_ASSERT(!isCompilingAsmJS());
 #ifdef JS_CODEGEN_X64
         masm.testq(rhs.reg.reg, rhs.reg.reg);
         masm.j(Assembler::Zero, wasm::JumpTarget::IntegerDivideByZero);
-#else
+#elif defined(JS_CODEGEN_X86)
         Label nonZero;
         masm.branchTest32(Assembler::NonZero, rhs.reg.low, rhs.reg.low, &nonZero);
         masm.branchTest32(Assembler::Zero, rhs.reg.high, rhs.reg.high,
                           wasm::JumpTarget::IntegerDivideByZero);
         masm.bind(&nonZero);
+#else
+        MOZ_CRASH("BaseCompiler platform hook: checkDivideByZeroI64");
 #endif
     }
 
     void checkDivideSignedOverflowI32(RegI32 rhs, RegI32 srcDest, Label* done, bool zeroOnOverflow) {
         Label notMin;
         masm.branch32(Assembler::NotEqual, srcDest.reg, Imm32(INT32_MIN), &notMin);
         if (zeroOnOverflow) {
             masm.branch32(Assembler::NotEqual, rhs.reg, Imm32(-1), &notMin);
@@ -2419,26 +2431,30 @@ class BaseCompiler
             masm.branch32(Assembler::Equal, rhs.reg, Imm32(-1), done);
         } else {
             masm.branch32(Assembler::Equal, rhs.reg, Imm32(-1), wasm::JumpTarget::IntegerOverflow);
         }
         masm.bind(&notMin);
     }
 
     void checkDivideSignedOverflowI64(RegI64 rhs, RegI64 srcDest, Label* done, bool zeroOnOverflow) {
+#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)
         MOZ_ASSERT(!isCompilingAsmJS());
         Label notmin;
         masm.branch64(Assembler::NotEqual, srcDest.reg, Imm64(INT64_MIN), &notmin);
         masm.branch64(Assembler::NotEqual, rhs.reg, Imm64(-1), &notmin);
         if (zeroOnOverflow)
             masm.xor64(srcDest.reg, srcDest.reg);
         else
             masm.jump(wasm::JumpTarget::IntegerOverflow);
         masm.jump(done);
         masm.bind(&notmin);
+#else
+        MOZ_CRASH("BaseCompiler platform hook: checkDivideSignedOverflowI64");
+#endif
     }
 
     void quotientI64(RegI64 rhs, RegI64 srcDest, IsUnsigned isUnsigned) {
         // This follows quotientI32, above.
         Label done;
 
         checkDivideByZeroI64(rhs, srcDest, &done);
 
@@ -2489,78 +2505,96 @@ class BaseCompiler
         masm.bind(&done);
     }
 
     void orI64(RegI64 rhs, RegI64 srcDest) {
         masm.or64(rhs.reg, srcDest.reg);
     }
 
     void andI64(RegI64 rhs, RegI64 srcDest) {
+#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
         masm.and64(rhs.reg, srcDest.reg);
+#else
+        MOZ_CRASH("BaseCompiler platform hook: andI64");
+#endif
     }
 
     void xorI64(RegI64 rhs, RegI64 srcDest) {
         masm.xor64(rhs.reg, srcDest.reg);
     }
 
     void lshiftI64(RegI64 shift, RegI64 srcDest) {
-#ifdef JS_PUNBOX64
+#if defined(JS_CODEGEN_X64)
         masm.lshift64(shift.reg.reg, srcDest.reg);
+#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
+        masm.lshift64(shift.reg.low, srcDest.reg);
 #else
-        masm.lshift64(shift.reg.low, srcDest.reg);
+        MOZ_CRASH("BaseCompiler platform hook: lshiftI64");
 #endif
     }
 
     void rshiftI64(RegI64 shift, RegI64 srcDest) {
-#ifdef JS_PUNBOX64
+#if defined(JS_CODEGEN_X64)
         masm.rshift64Arithmetic(shift.reg.reg, srcDest.reg);
+#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
+        masm.rshift64Arithmetic(shift.reg.low, srcDest.reg);
 #else
-        masm.rshift64Arithmetic(shift.reg.low, srcDest.reg);
+        MOZ_CRASH("BaseCompiler platform hook: rshiftI64");
 #endif
     }
 
     void rshiftU64(RegI64 shift, RegI64 srcDest) {
-#ifdef JS_PUNBOX64
+#if defined(JS_CODEGEN_X64)
         masm.rshift64(shift.reg.reg, srcDest.reg);
+#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
+        masm.rshift64(shift.reg.low, srcDest.reg);
 #else
-        masm.rshift64(shift.reg.low, srcDest.reg);
+        MOZ_CRASH("BaseCompiler platform hook: rshiftU64");
 #endif
     }
 
     void rotateRightI64(RegI64 shift, RegI64 srcDest) {
-#ifdef JS_PUNBOX64
+#if defined(JS_CODEGEN_X64)
         masm.rotateRight64(shift.reg.reg, srcDest.reg, srcDest.reg, Register::Invalid());
+#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
+        masm.rotateRight64(shift.reg.low, srcDest.reg, srcDest.reg, shift.reg.high);
 #else
-        masm.rotateRight64(shift.reg.low, srcDest.reg, srcDest.reg, shift.reg.high);
+        MOZ_CRASH("BaseCompiler platform hook: rotateRightI64");
 #endif
     }
 
     void rotateLeftI64(RegI64 shift, RegI64 srcDest) {
-#ifdef JS_PUNBOX64
+#if defined(JS_CODEGEN_X64)
         masm.rotateLeft64(shift.reg.reg, srcDest.reg, srcDest.reg, Register::Invalid());
+#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
+        masm.rotateLeft64(shift.reg.low, srcDest.reg, srcDest.reg, shift.reg.high);
 #else
-        masm.rotateLeft64(shift.reg.low, srcDest.reg, srcDest.reg, shift.reg.high);
+        MOZ_CRASH("BaseCompiler platform hook: rotateLeftI64");
 #endif
     }
 
     void clzI64(RegI64 srcDest) {
-#ifdef JS_PUNBOX64
+#if defined(JS_CODEGEN_X64)
         masm.clz64(srcDest.reg, srcDest.reg.reg);
-#else
+#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
         masm.clz64(srcDest.reg, srcDest.reg.low);
         masm.move32(Imm32(0), srcDest.reg.high);
+#else
+        MOZ_CRASH("BaseCompiler platform hook: clzI64");
 #endif
     }
 
     void ctzI64(RegI64 srcDest) {
-#ifdef JS_PUNBOX64
+#if defined(JS_CODEGEN_X64)
         masm.ctz64(srcDest.reg, srcDest.reg.reg);
-#else
+#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
         masm.ctz64(srcDest.reg, srcDest.reg.low);
         masm.move32(Imm32(0), srcDest.reg.high);
+#else
+        MOZ_CRASH("BaseCompiler platform hook: ctzI64");
 #endif
     }
 
     bool popcnt32NeedsTemp() const {
 #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
         return !AssemblerX86Shared::HasPOPCNT();
 #else
         MOZ_CRASH("BaseCompiler platform hook: popcnt32NeedsTemp");
@@ -2579,17 +2613,21 @@ class BaseCompiler
 #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
         return !AssemblerX86Shared::HasPOPCNT();
 #else
         MOZ_CRASH("BaseCompiler platform hook: popcnt64NeedsTemp");
 #endif
     }
 
     void popcntI64(RegI64 srcDest, RegI32 tmp) {
+#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_ARM)
         masm.popcnt64(srcDest.reg, srcDest.reg, tmp.reg);
+#else
+        MOZ_CRASH("BaseCompiler platform hook: popcntI64");
+#endif
     }
 
     void reinterpretI64AsF64(RegI64 src, RegF64 dest) {
 #if defined(JS_CODEGEN_X64)
         masm.vmovq(src.reg.reg, dest.reg);
 #elif defined(JS_CODEGEN_X86)
         masm.Push(src.reg.high);
         masm.Push(src.reg.low);
@@ -2875,24 +2913,26 @@ class BaseCompiler
         masm.append(GlobalAccess(label, globalDataOffset));
 #else
         MOZ_CRASH("BaseCompiler platform hook: loadGlobalVarI32");
 #endif
     }
 
     void loadGlobalVarI64(unsigned globalDataOffset, RegI64 r)
     {
-#if defined(JS_PUNBOX64)
+#if defined(JS_CODEGEN_X64)
         CodeOffset label = masm.loadRipRelativeInt64(r.reg.reg);
         masm.append(GlobalAccess(label, globalDataOffset));
-#else
+#elif defined(JS_CODEGEN_X86)
         CodeOffset labelLow = masm.movlWithPatch(PatchedAbsoluteAddress(), r.reg.low);
         masm.append(GlobalAccess(labelLow, globalDataOffset + INT64LOW_OFFSET));
         CodeOffset labelHigh = masm.movlWithPatch(PatchedAbsoluteAddress(), r.reg.high);
         masm.append(GlobalAccess(labelHigh, globalDataOffset + INT64HIGH_OFFSET));
+#else
+        MOZ_CRASH("BaseCompiler platform hook: loadGlobalVarI64");
 #endif
     }
 
     void loadGlobalVarF32(unsigned globalDataOffset, RegF32 r)
     {
 #if defined(JS_CODEGEN_X64)
         CodeOffset label = masm.loadRipRelativeFloat32(r.reg);
         masm.append(GlobalAccess(label, globalDataOffset));
@@ -3610,43 +3650,43 @@ BaseCompiler::emitQuotientI64()
 #endif
 }
 
 void
 BaseCompiler::emitQuotientU64()
 {
 #ifdef JS_PUNBOX64
     RegI64 r0, r1;
- #ifdef JS_CODEGEN_X64
+# ifdef JS_CODEGEN_X64
     // srcDest must be rax, and rdx will be clobbered.
     need2xI64(specific_rax, specific_rdx);
     r1 = popI64();
     r0 = popI64ToSpecific(specific_rax);
     freeI64(specific_rdx);
- #else
+# else
     pop2xI64(&r0, &r1);
- #endif
+# endif
     quotientI64(r1, r0, IsUnsigned(true));
     freeI64(r1);
     pushI64(r0);
 #else
- #if defined(JS_CODEGEN_X86)
+# if defined(JS_CODEGEN_X86)
     RegI64 r0, r1;
     RegI32 temp;
     needI64(abiReturnRegI64);
     temp = needI32();
     r1 = popI64();
     r0 = popI64ToSpecific(abiReturnRegI64);
     emitDivOrModI64BuiltinCall(SymbolicAddress::UDivI64, r1, r0, temp);
     freeI32(temp);
     freeI64(r1);
     pushI64(r0);
- #else
+# else
     MOZ_CRASH("BaseCompiler platform hook: emitQuotientU64");
- #endif
+# endif
 #endif
 }
 
 void
 BaseCompiler::emitRemainderI32()
 {
     // TODO / OPTIMIZE: Fast case if lhs >= 0 and rhs is power of two.
     RegI32 r0, r1;
@@ -3694,76 +3734,76 @@ BaseCompiler::emitRemainderU32()
     pushI32(r0);
 }
 
 void
 BaseCompiler::emitRemainderI64()
 {
 #ifdef JS_PUNBOX64
     RegI64 r0, r1;
- #ifdef JS_CODEGEN_X64
+# ifdef JS_CODEGEN_X64
     need2xI64(specific_rax, specific_rdx);
     r1 = popI64();
     r0 = popI64ToSpecific(specific_rax);
     freeI64(specific_rdx);
- #else
+# else
     pop2xI64(&r0, &r1);
- #endif
+# endif
     remainderI64(r1, r0, IsUnsigned(false));
     freeI64(r1);
     pushI64(r0);
 #else
- #if defined(JS_CODEGEN_X86)
+# if defined(JS_CODEGEN_X86)
     RegI64 r0, r1;
     RegI32 temp;
     needI64(abiReturnRegI64);
     temp = needI32();
     r1 = popI64();
     r0 = popI64ToSpecific(abiReturnRegI64);
     emitDivOrModI64BuiltinCall(SymbolicAddress::ModI64, r1, r0, temp);
     freeI32(temp);
     freeI64(r1);
     pushI64(r0);
- #else
+# else
     MOZ_CRASH("BaseCompiler platform hook: emitRemainderI64");
- #endif
+# endif
 #endif
 }
 
 void
 BaseCompiler::emitRemainderU64()
 {
 #ifdef JS_PUNBOX64
     RegI64 r0, r1;
- #ifdef JS_CODEGEN_X64
+# ifdef JS_CODEGEN_X64
     need2xI64(specific_rax, specific_rdx);
     r1 = popI64();
     r0 = popI64ToSpecific(specific_rax);
     freeI64(specific_rdx);
- #else
+# else
     pop2xI64(&r0, &r1);
- #endif
+# endif
     remainderI64(r1, r0, IsUnsigned(true));
     freeI64(r1);
     pushI64(r0);
 #else
- #if defined(JS_CODEGEN_X86)
+# if defined(JS_CODEGEN_X86)
     RegI64 r0, r1;
     RegI32 temp;
     needI64(abiReturnRegI64);
     temp = needI32();
     r1 = popI64();
     r0 = popI64ToSpecific(abiReturnRegI64);
     emitDivOrModI64BuiltinCall(SymbolicAddress::UModI64, r1, r0, temp);
     freeI32(temp);
     freeI64(r1);
     pushI64(r0);
- #else
+# else
     MOZ_CRASH("BaseCompiler platform hook: emitRemainderU64");
- #endif
+# endif
 #endif
 }
 
 void
 BaseCompiler::emitDivideF32()
 {
     RegF32 r0, r1;
     pop2xF32(&r0, &r1);