Bug 1419025 - wasm baseline, clean up scratch registers further. r=bbouvier
authorLars T Hansen <lhansen@mozilla.com>
Wed, 22 Nov 2017 12:27:16 +0100
changeset 393398 2079792e5c71451b2dfac559d72e7f6f97a5526b
parent 393397 ad749012c057f562414ddac2b8d24cb1066dfd6f
child 393399 32b00c586da29bfca96d5fdfd5c9e7932e6736d7
push id32960
push usertoros@mozilla.com
push dateThu, 23 Nov 2017 22:29:10 +0000
treeherdermozilla-central@3f5d48c08903 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1419025
milestone59.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 1419025 - wasm baseline, clean up scratch registers further. r=bbouvier
js/src/wasm/WasmBaselineCompile.cpp
--- a/js/src/wasm/WasmBaselineCompile.cpp
+++ b/js/src/wasm/WasmBaselineCompile.cpp
@@ -297,17 +297,18 @@ BaseLocalIter::operator++(int)
     MOZ_ASSERT(!done_);
     index_++;
     if (!argsIter_.done())
         argsIter_++;
     settle();
 }
 
 // The strongly typed register wrappers are especially useful to distinguish
-// float registers from double registers.
+// float registers from double registers, but they also clearly distinguish
+// 32-bit registers from 64-bit register pairs on 32-bit systems.
 
 struct RegI32 : public Register
 {
     RegI32() : Register(Register::Invalid()) {}
     explicit RegI32(Register reg) : Register(reg) {}
 };
 
 struct RegI64 : public Register64
@@ -729,45 +730,62 @@ class BaseRegAlloc
         }
     };
 #endif
 };
 
 // ScratchRegister abstractions.  We define our own, deferring to the platform's
 // when possible.
 
-#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
-typedef ScratchDoubleScope ScratchF64;
-#else
-class ScratchF64
+#if defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_NONE)
+class ScratchDoubleScope
 {
   public:
-    ScratchF64(BaseRegAlloc&) {}
+    explicit ScratchDoubleScope(MacroAssembler& m) {}
     operator FloatRegister() const {
-        MOZ_CRASH("BaseCompiler platform hook - ScratchF64");
+        MOZ_CRASH("BaseCompiler platform hook - ScratchDoubleScope");
+    }
+};
+
+class ScratchFloat32Scope
+{
+  public:
+    explicit ScratchFloat32Scope(MacroAssembler& m) {}
+    operator FloatRegister() const {
+        MOZ_CRASH("BaseCompiler platform hook - ScratchFloat32Scope");
     }
 };
-#endif
-
-#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
-typedef ScratchFloat32Scope ScratchF32;
-#else
-class ScratchF32
+
+class ScratchRegisterScope
+{
+  public:
+    explicit ScratchRegisterScope(MacroAssembler& m) {}
+    operator Register() const {
+        MOZ_CRASH("BaseCompiler platform hook - ScratchRegisterScope");
+    }
+};
+#endif
+
+class ScratchF64 : public ScratchDoubleScope
 {
   public:
-    ScratchF32(BaseRegAlloc&) {}
-    operator FloatRegister() const {
-        MOZ_CRASH("BaseCompiler platform hook - ScratchF32");
-    }
+    explicit ScratchF64(MacroAssembler& m) : ScratchDoubleScope(m) {}
+    operator RegF64() const { return RegF64(FloatRegister(*this)); }
 };
-#endif
-
-#if defined(JS_CODEGEN_X64)
-typedef ScratchRegisterScope ScratchI32;
-#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
+
+class ScratchF32 : public ScratchFloat32Scope
+{
+  public:
+    explicit ScratchF32(MacroAssembler& m) : ScratchFloat32Scope(m) {}
+    operator RegF32() const { return RegF32(FloatRegister(*this)); }
+};
+
+#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
+// On x86 we do not have a dedicated masm scratch register; on ARM, we need one
+// in addition to the one defined by masm because masm uses it too often.
 class ScratchI32
 {
 # ifdef DEBUG
     BaseRegAlloc& ra;
   public:
     explicit ScratchI32(BaseRegAlloc& ra) : ra(ra) {
         MOZ_ASSERT(!ra.scratchRegisterTaken());
         ra.setScratchRegisterTaken(true);
@@ -775,32 +793,31 @@ class ScratchI32
     ~ScratchI32() {
         MOZ_ASSERT(ra.scratchRegisterTaken());
         ra.setScratchRegisterTaken(false);
     }
 # else
   public:
     explicit ScratchI32(BaseRegAlloc&) {}
 # endif
-    operator Register() const {
+
+    operator RegI32() const {
 # ifdef JS_CODEGEN_X86
-        return ScratchRegX86;
+        return RegI32(ScratchRegX86);
 # else
-        return ScratchRegARM;
+        return RegI32(ScratchRegARM);
 # endif
     }
 };
 #else
-class ScratchI32
-{
-public:
-    ScratchI32(BaseRegAlloc&) {}
-    operator Register() const {
-        MOZ_CRASH("BaseCompiler platform hook - ScratchI32");
-    }
+class ScratchI32 : public ScratchRegisterScope
+{
+  public:
+    explicit ScratchI32(MacroAssembler& m) : ScratchRegisterScope(m) {}
+    operator RegI32() const { return RegI32(Register(*this)); }
 };
 #endif
 
 #if defined(JS_CODEGEN_X86)
 // ScratchEBX is a mnemonic device: For some atomic ops we really need EBX,
 // no other register will do.  And we would normally have to allocate that
 // register using ScratchI32 since normally the scratch register is EBX.
 // But the whole point of ScratchI32 is to hide that relationship.  By using