Bug 1420104 - rabaldr, clean up temp register managements and some ifdefs. r?bbouvier draft
authorLars T Hansen <lhansen@mozilla.com>
Thu, 23 Nov 2017 12:37:22 +0100
changeset 704217 adc00474bdae6284448accfd1fcfbb1d6ca6c43c
parent 704216 767ea41d5d71b3ff2dbb5eb3248fa9394441e405
child 704218 82424d76a290f0c54dac09b6c5bab73642233eeb
push id91107
push userbmo:lhansen@mozilla.com
push dateTue, 28 Nov 2017 10:55:44 +0000
reviewersbbouvier
bugs1420104
milestone59.0a1
Bug 1420104 - rabaldr, clean up temp register managements and some ifdefs. r?bbouvier A few ifdefs that were on platform names were really supposed to be on JS_PUNBOX64. Changes temp register management so that functions in the platform layer now allocate and return the temp registers when appropriate and return invalid registers when not appropriate. This cleans up a bit of code in the platform-independent layer. MozReview-Commit-ID: K69Bj1gUNbZ
js/src/wasm/WasmBaselineCompile.cpp
--- a/js/src/wasm/WasmBaselineCompile.cpp
+++ b/js/src/wasm/WasmBaselineCompile.cpp
@@ -3087,26 +3087,24 @@ class BaseCompiler final : public BaseCo
                 loadI32(arg, RegI32(argLoc.gpr()));
             }
             break;
           }
           case ValType::I64: {
             ABIArg argLoc = call.abi.next(MIRType::Int64);
             if (argLoc.kind() == ABIArg::Stack) {
                 ScratchI32 scratch(*this);
-#if defined(JS_CODEGEN_X64)
+#ifdef JS_PUNBOX64
                 loadI64(arg, fromI32(scratch));
-                masm.movq(scratch, Operand(masm.getStackPointer(), argLoc.offsetFromArgBase()));
-#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
+                masm.storePtr(scratch, Address(masm.getStackPointer(), argLoc.offsetFromArgBase()));
+#else
                 loadI64Low(arg, scratch);
                 masm.store32(scratch, LowWord(Address(masm.getStackPointer(), argLoc.offsetFromArgBase())));
                 loadI64High(arg, scratch);
                 masm.store32(scratch, HighWord(Address(masm.getStackPointer(), argLoc.offsetFromArgBase())));
-#else
-                MOZ_CRASH("BaseCompiler platform hook: passArg I64");
 #endif
             } else {
                 loadI64(arg, RegI64(argLoc.gpr64()));
             }
             break;
           }
           case ValType::F64: {
             ABIArg argLoc = call.abi.next(MIRType::Double);
@@ -3495,47 +3493,49 @@ class BaseCompiler final : public BaseCo
         *r1 = widenI32(specific_ecx);
         *r1 = popI64ToSpecific(*r1);
         *r0 = popI64();
 #else
         pop2xI64(r0, r1);
 #endif
     }
 
-    bool rotate64NeedsTemp() const {
+    RegI32 needRotate64Temp() {
 #if defined(JS_CODEGEN_X86)
-        return true;
+        return needI32();
+#elif defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_ARM)
+        return RegI32::Invalid();
 #else
-        return false;
+        MOZ_CRASH("BaseCompiler platform hook: needRotate64Temp");
 #endif
     }
 
     void maskShiftCount32(RegI32 r) {
 #if defined(JS_CODEGEN_ARM)
         masm.and32(Imm32(31), r);
 #endif
     }
 
-    bool popcnt32NeedsTemp() const {
+    RegI32 needPopcnt32Temp() {
 #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
-        return !AssemblerX86Shared::HasPOPCNT();
+        return AssemblerX86Shared::HasPOPCNT() ? RegI32::Invalid() : needI32();
 #elif defined(JS_CODEGEN_ARM)
-        return true;
+        return needI32();
 #else
-        MOZ_CRASH("BaseCompiler platform hook: popcnt32NeedsTemp");
-#endif
-    }
-
-    bool popcnt64NeedsTemp() const {
+        MOZ_CRASH("BaseCompiler platform hook: needPopcnt32Temp");
+#endif
+    }
+
+    RegI32 needPopcnt64Temp() {
 #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
-        return !AssemblerX86Shared::HasPOPCNT();
+        return AssemblerX86Shared::HasPOPCNT() ? RegI32::Invalid() : needI32();
 #elif defined(JS_CODEGEN_ARM)
-        return true;
+        return needI32();
 #else
-        MOZ_CRASH("BaseCompiler platform hook: popcnt64NeedsTemp");
+        MOZ_CRASH("BaseCompiler platform hook: needPopcnt64Temp");
 #endif
     }
 
     RegI64 popI32ForSignExtendI64() {
 #if defined(JS_CODEGEN_X86)
         need2xI32(specific_edx, specific_eax);
         RegI32 r0 = popI32ToSpecific(specific_eax);
         RegI64 x0 = specific_edx_eax;
@@ -3714,24 +3714,25 @@ class BaseCompiler final : public BaseCo
 # else
         MOZ_CRASH("BaseCompiler platform hook: truncateF64ToI64");
 # endif
         return true;
     }
 #endif // RABALDR_FLOAT_TO_I64_CALLOUT
 
 #ifndef RABALDR_I64_TO_FLOAT_CALLOUT
-    bool convertI64ToFloatNeedsTemp(ValType to, bool isUnsigned) const {
+    RegI32 needConvertI64ToFloatTemp(ValType to, bool isUnsigned) {
 # if defined(JS_CODEGEN_X86)
-        return isUnsigned &&
-               ((to == ValType::F64 && AssemblerX86Shared::HasSSE3()) ||
-               to == ValType::F32);
+        bool needs = isUnsigned &&
+                     ((to == ValType::F64 && AssemblerX86Shared::HasSSE3()) ||
+                      to == ValType::F32);
 # else
-        return isUnsigned;
+        bool needs = isUnsigned;
 # endif
+        return needs ? needI32() : RegI32::Invalid();
     }
 
     void convertI64ToF32(RegI64 src, bool isUnsigned, RegF32 dest, RegI32 temp) {
 # if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)
         if (isUnsigned)
             masm.convertUInt64ToFloat32(src, dest, temp);
         else
             masm.convertInt64ToFloat32(src, dest);
@@ -4037,21 +4038,22 @@ class BaseCompiler final : public BaseCo
         }
 #else
         MOZ_CRASH("BaseCompiler platform hook: load");
 #endif
 
         return true;
     }
 
-    void needStoreTemps(const MemoryAccessDesc& access, ValType srcType, RegI32* tmp) {
+    RegI32 needStoreTemp(const MemoryAccessDesc& access, ValType srcType) {
 #if defined(JS_CODEGEN_ARM)
         if (IsUnaligned(access) && srcType != ValType::I32)
-            *tmp = needI32();
-#endif
+            return needI32();
+#endif
+        return RegI32::Invalid();
     }
 
     // ptr and src must not be the same register.
     // This may destroy ptr and src.
     MOZ_MUST_USE bool store(MemoryAccessDesc* access, AccessCheck* check, RegI32 tls, RegI32 ptr,
                             AnyReg src, RegI32 tmp)
     {
         prepareMemoryAccess(access, check, tls, ptr);
@@ -4180,30 +4182,32 @@ class BaseCompiler final : public BaseCo
         freeI32(specific_ecx);
 #elif defined(JS_CODEGEN_ARM)
         freeI64(rv);
 #else
         MOZ_CRASH("BaseCompiler porting interface: xchg64");
 #endif
     }
 
-    void needAtomicRMWTemps(AtomicOp op, MemoryAccessDesc* access, RegI32* tmp) {
+    RegI32 needAtomicRMWTemp(AtomicOp op, MemoryAccessDesc* access) {
+        RegI32 tmp;
 #if defined(JS_CODEGEN_X86)
         // Handled specially in atomicRMW
         if (access->byteSize() == 1)
-            return;
+            return tmp;
 #endif
 #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
         if (op != AtomicFetchAddOp && op != AtomicFetchSubOp)
-            *tmp = needI32();
+            tmp = needI32();
 #elif defined(JS_CODEGEN_ARM)
-        *tmp = needI32();
+        tmp = needI32();
 #else
         MOZ_CRASH("BaseCompiler platform hook: atomicRMWTemps");
 #endif
+        return tmp;
     }
 
     void
     atomicRMW(AtomicOp op, MemoryAccessDesc* access, AccessCheck* check, RegI32 tls, RegI32 ptr,
               RegI32 rv, RegI32 rd, RegI32 tmp)
     {
         prepareMemoryAccess(access, check, tls, ptr);
         ATOMIC_PTR(srcAddr, access, tls, ptr);
@@ -4253,27 +4257,29 @@ class BaseCompiler final : public BaseCo
             break;
           }
           default: {
             MOZ_CRASH("Bad type for atomic operation");
           }
         }
     }
 
-    void needAtomicRMW64Temps(AtomicOp op, RegI64* tmp) {
+    RegI64 needAtomicRMW64Temp(AtomicOp op) {
+        RegI64 tmp;
 #if defined(JS_CODEGEN_X86)
         MOZ_CRASH("Do not call on x86");
 #elif defined(JS_CODEGEN_X64)
         if (op != AtomicFetchAddOp && op != AtomicFetchSubOp)
-            *tmp = needI64();
+            tmp = needI64();
 #elif defined(JS_CODEGEN_ARM)
-        *tmp = needI64Pair();
+        tmp = needI64Pair();
 #else
         MOZ_CRASH("BaseCompiler platform hook: atomicRMW64Temps");
 #endif
+        return tmp;
     }
 
     // On x86, T is Address.  On other platforms, it is Register64.
     // U is BaseIndex or Address.
     template <typename T, typename U>
     void
     atomicRMW64(AtomicOp op, T value, const U& srcAddr, Register64 tmp, Register64 rd) {
         switch (op) {
@@ -5497,19 +5503,17 @@ BaseCompiler::emitRotrI32()
 }
 
 void
 BaseCompiler::emitRotrI64()
 {
     int64_t c;
     if (popConstI64(&c)) {
         RegI64 r = popI64();
-        RegI32 temp;
-        if (rotate64NeedsTemp())
-            temp = needI32();
+        RegI32 temp = needRotate64Temp();
         masm.rotateRight64(Imm32(c & 63), r, r, temp);
         maybeFreeI32(temp);
         pushI64(r);
     } else {
         RegI64 r0, r1;
         pop2xI64ForShiftOrRotate(&r0, &r1);
         masm.rotateRight64(lowPart(r1), r0, r0, maybeHighPart(r1));
         freeI64(r1);
@@ -5535,19 +5539,17 @@ BaseCompiler::emitRotlI32()
 }
 
 void
 BaseCompiler::emitRotlI64()
 {
     int64_t c;
     if (popConstI64(&c)) {
         RegI64 r = popI64();
-        RegI32 temp;
-        if (rotate64NeedsTemp())
-            temp = needI32();
+        RegI32 temp = needRotate64Temp();
         masm.rotateLeft64(Imm32(c & 63), r, r, temp);
         maybeFreeI32(temp);
         pushI64(r);
     } else {
         RegI64 r0, r1;
         pop2xI64ForShiftOrRotate(&r0, &r1);
         masm.rotateLeft64(lowPart(r1), r0, r0, maybeHighPart(r1));
         freeI64(r1);
@@ -5612,37 +5614,29 @@ BaseCompiler::emitCtzI64()
     maybeClearHighPart(r0);
     pushI64(r0);
 }
 
 void
 BaseCompiler::emitPopcntI32()
 {
     RegI32 r0 = popI32();
-    if (popcnt32NeedsTemp()) {
-        RegI32 tmp = needI32();
-        masm.popcnt32(r0, r0, tmp);
-        freeI32(tmp);
-    } else {
-        masm.popcnt32(r0, r0, RegI32::Invalid());
-    }
+    RegI32 tmp = needPopcnt32Temp();
+    masm.popcnt32(r0, r0, tmp);
+    maybeFreeI32(tmp);
     pushI32(r0);
 }
 
 void
 BaseCompiler::emitPopcntI64()
 {
     RegI64 r0 = popI64();
-    if (popcnt64NeedsTemp()) {
-        RegI32 tmp = needI32();
-        masm.popcnt64(r0, r0, tmp);
-        freeI32(tmp);
-    } else {
-        masm.popcnt64(r0, r0, RegI32::Invalid());
-    }
+    RegI32 tmp = needPopcnt64Temp();
+    masm.popcnt64(r0, r0, tmp);
+    maybeFreeI32(tmp);
     pushI64(r0);
 }
 
 void
 BaseCompiler::emitAbsF32()
 {
     RegF32 r0 = popF32();
     masm.absFloat32(r0, r0);
@@ -5885,19 +5879,17 @@ BaseCompiler::emitConvertI64ToF32()
     pushF32(f0);
 }
 
 void
 BaseCompiler::emitConvertU64ToF32()
 {
     RegI64 r0 = popI64();
     RegF32 f0 = needF32();
-    RegI32 temp;
-    if (convertI64ToFloatNeedsTemp(ValType::F32, IsUnsigned(true)))
-        temp = needI32();
+    RegI32 temp = needConvertI64ToFloatTemp(ValType::F32, IsUnsigned(true));
     convertI64ToF32(r0, IsUnsigned(true), f0, temp);
     maybeFreeI32(temp);
     freeI64(r0);
     pushF32(f0);
 }
 #endif
 
 void
@@ -5941,19 +5933,17 @@ BaseCompiler::emitConvertI64ToF64()
     pushF64(d0);
 }
 
 void
 BaseCompiler::emitConvertU64ToF64()
 {
     RegI64 r0 = popI64();
     RegF64 d0 = needF64();
-    RegI32 temp;
-    if (convertI64ToFloatNeedsTemp(ValType::F64, IsUnsigned(true)))
-        temp = needI32();
+    RegI32 temp = needConvertI64ToFloatTemp(ValType::F64, IsUnsigned(true));
     convertI64ToF64(r0, IsUnsigned(true), d0, temp);
     maybeFreeI32(temp);
     freeI64(r0);
     pushF64(d0);
 }
 #endif // RABALDR_I64_TO_FLOAT_CALLOUT
 
 void
@@ -7352,18 +7342,18 @@ BaseCompiler::emitLoad(ValType type, Sca
     return loadCommon(&access, type);
 }
 
 bool
 BaseCompiler::storeCommon(MemoryAccessDesc* access, ValType resultType)
 {
     AccessCheck check;
 
-    RegI32 tls, tmp;
-    needStoreTemps(*access, resultType, &tmp);
+    RegI32 tls;
+    RegI32 tmp = needStoreTemp(*access, resultType);
 
     switch (resultType) {
       case ValType::I32: {
         RegI32 rv = popI32();
         RegI32 rp = popMemoryAccess(access, &check);
         tls = maybeLoadTlsForAccess(check);
         if (!store(access, &check, tls, rp, AnyReg(rv), tmp))
             return false;
@@ -7860,18 +7850,17 @@ BaseCompiler::emitAtomicRMW(ValType type
         RegI32 rv = narrowing ? popI64ToI32() : popI32();
         RegI32 rp = popMemoryAccess(&access, &check);
         RegI32 output = needI32();
 #else
         RegI32 rv, rp, output;
         MOZ_CRASH("BaseCompiler porting interface: atomic rmw");
 #endif
         RegI32 tls = maybeLoadTlsForAccess(check);
-        RegI32 tmp;
-        needAtomicRMWTemps(op, &access, &tmp);
+        RegI32 tmp = needAtomicRMWTemp(op, &access);
 
         atomicRMW(op, &access, &check, tls, rp, rv, output, tmp);
 
         maybeFreeI32(tls);
         maybeFreeI32(tmp);
         freeI32(rp);
         if (rv != output)
             freeI32(rv);
@@ -7943,18 +7932,17 @@ BaseCompiler::emitAtomicRMW(ValType type
     RegI64 rd = needI64Pair();
 #  else
     RegI64 rv, rd;
     RegI32 rp;
     MOZ_CRASH("BaseCompiler porting interface: 64-bit atomic RMW");
 # endif
 
     RegI32 tls = maybeLoadTlsForAccess(check);
-    RegI64 tmp;
-    needAtomicRMW64Temps(op, &tmp);
+    RegI64 tmp = needAtomicRMW64Temp(op);
 
     prepareMemoryAccess(&access, &check, tls, rp);
     ATOMIC_PTR(srcAddr, &access, tls, rp);
 
     atomicRMW64(op, rv, srcAddr, tmp, rd);
 
     pushI64(rd);