Bug 1134626 part 2 - Move x86 & x64 Architecture into a shared file. r=jandem
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Thu, 02 Apr 2015 23:26:53 +0200
changeset 237460 72368655a2d5621d85328f3dab94382a2f237f16
parent 237459 5d83bd430b88cc88e718f00cc554a76232c1f3f6
child 237461 1298c13f4181b9c42ab72390de8a95495630d40d
push id28536
push userryanvm@gmail.com
push dateFri, 03 Apr 2015 14:34:15 +0000
treeherdermozilla-central@6d849a62ec0d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1134626
milestone40.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 1134626 part 2 - Move x86 & x64 Architecture into a shared file. r=jandem
js/src/jit/Registers.h
js/src/jit/x64/Architecture-x64.h
js/src/jit/x64/Assembler-x64.cpp
js/src/jit/x86-shared/Architecture-x86-shared.cpp
js/src/jit/x86-shared/Architecture-x86-shared.h
js/src/jit/x86-shared/Assembler-x86-shared.cpp
js/src/jit/x86/Architecture-x86.h
js/src/jit/x86/Assembler-x86.cpp
js/src/moz.build
--- a/js/src/jit/Registers.h
+++ b/js/src/jit/Registers.h
@@ -5,20 +5,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_Registers_h
 #define jit_Registers_h
 
 #include "mozilla/Array.h"
 
 #include "jit/IonTypes.h"
-#if defined(JS_CODEGEN_X86)
-# include "jit/x86/Architecture-x86.h"
-#elif defined(JS_CODEGEN_X64)
-# include "jit/x64/Architecture-x64.h"
+#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
+# include "jit/x86-shared/Architecture-x86-shared.h"
 #elif defined(JS_CODEGEN_ARM)
 # include "jit/arm/Architecture-arm.h"
 #elif defined(JS_CODEGEN_MIPS)
 # include "jit/mips/Architecture-mips.h"
 #elif defined(JS_CODEGEN_NONE)
 # include "jit/none/Architecture-none.h"
 #else
 # error "Unknown architecture!"
--- a/js/src/jit/x64/Assembler-x64.cpp
+++ b/js/src/jit/x64/Assembler-x64.cpp
@@ -298,65 +298,8 @@ Assembler::TraceJumpRelocations(JSTracer
 {
     RelocationIterator iter(reader);
     while (iter.read()) {
         JitCode* child = CodeFromJump(code, code->raw() + iter.offset());
         MarkJitCodeUnbarriered(trc, &child, "rel32");
         MOZ_ASSERT(child == CodeFromJump(code, code->raw() + iter.offset()));
     }
 }
-
-FloatRegisterSet
-FloatRegister::ReduceSetForPush(const FloatRegisterSet& s)
-{
-    SetType bits = s.bits();
-
-    // Ignore all SIMD register, if not supported.
-    if (!JitSupportsSimd())
-        bits &= Codes::AllPhysMask * Codes::SpreadScalar;
-
-    // Exclude registers which are already pushed with a larger type. High bits
-    // are associated with larger register types. Thus we keep the set of
-    // registers which are not included in larger type.
-    bits &= ~(bits >> (1 * Codes::TotalPhys));
-    bits &= ~(bits >> (2 * Codes::TotalPhys));
-    bits &= ~(bits >> (3 * Codes::TotalPhys));
-
-    return FloatRegisterSet(bits);
-}
-
-uint32_t
-FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s)
-{
-    SetType all = s.bits();
-    SetType float32x4Set =
-        (all >> (uint32_t(Codes::Float32x4) * Codes::TotalPhys)) & Codes::AllPhysMask;
-    SetType int32x4Set =
-        (all >> (uint32_t(Codes::Int32x4) * Codes::TotalPhys)) & Codes::AllPhysMask;
-    SetType doubleSet =
-        (all >> (uint32_t(Codes::Double) * Codes::TotalPhys)) & Codes::AllPhysMask;
-    SetType singleSet =
-        (all >> (uint32_t(Codes::Single) * Codes::TotalPhys)) & Codes::AllPhysMask;
-
-    // PushRegsInMask pushes the largest register first, and thus avoids pushing
-    // aliased registers. So we have to filter out the physical registers which
-    // are already pushed as part of larger registers.
-    SetType set128b = int32x4Set | float32x4Set;
-    SetType set64b = doubleSet & ~set128b;
-    SetType set32b = singleSet & ~set64b  & ~set128b;
-
-    static_assert(Codes::AllPhysMask <= 0xffff, "We can safely use CountPopulation32");
-    uint32_t count32b = mozilla::CountPopulation32(set32b);
-
-    // If we have an odd number of 32 bits values, then we increase the size to
-    // keep the stack aligned on 8 bytes. Note: Keep in sync with
-    // PushRegsInMask, and PopRegsInMaskIgnore.
-    count32b += count32b & 1;
-
-    return mozilla::CountPopulation32(set128b) * (4 * sizeof(int32_t))
-        + mozilla::CountPopulation32(set64b) * sizeof(double)
-        + count32b * sizeof(float);
-}
-uint32_t
-FloatRegister::getRegisterDumpOffsetInBytes()
-{
-    return uint32_t(encoding()) * sizeof(FloatRegisters::RegisterContent);
-}
new file mode 100644
--- /dev/null
+++ b/js/src/jit/x86-shared/Architecture-x86-shared.cpp
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "jit/x86-shared/Architecture-x86-shared.h"
+#if !defined(JS_CODEGEN_X86) && !defined(JS_CODEGEN_X64)
+# error "Wrong architecture. Only x86 and x64 should build this file!"
+#endif
+
+const char*
+FloatRegister::name() const {
+    static const char* const names[] = {
+
+#ifdef JS_CODEGEN_X64
+#define FLOAT_REGS_(TYPE) \
+        "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, \
+        "%xmm4" TYPE, "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE, \
+        "%xmm8" TYPE, "%xmm9" TYPE, "%xmm10" TYPE, "%xmm11" TYPE, \
+        "%xmm12" TYPE, "%xmm13" TYPE, "%xmm14" TYPE, "%xmm15" TYPE
+#else
+#define FLOAT_REGS_(TYPE) \
+        "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, \
+        "%xmm4" TYPE, "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE
+#endif
+
+        // These should be enumerated in the same order as in
+        // FloatRegisters::ContentType.
+        FLOAT_REGS_(".s"),
+        FLOAT_REGS_(".d"),
+        FLOAT_REGS_(".i4"),
+        FLOAT_REGS_(".s4")
+#undef FLOAT_REGS_
+
+    };
+    MOZ_ASSERT(size_t(code()) < mozilla::ArrayLength(names));
+    return names[size_t(code())];
+}
+
+FloatRegisterSet
+FloatRegister::ReduceSetForPush(const FloatRegisterSet& s)
+{
+    SetType bits = s.bits();
+
+    // Ignore all SIMD register, if not supported.
+    if (!JitSupportsSimd())
+        bits &= Codes::AllPhysMask * Codes::SpreadScalar;
+
+    // Exclude registers which are already pushed with a larger type. High bits
+    // are associated with larger register types. Thus we keep the set of
+    // registers which are not included in larger type.
+    bits &= ~(bits >> (1 * Codes::TotalPhys));
+    bits &= ~(bits >> (2 * Codes::TotalPhys));
+    bits &= ~(bits >> (3 * Codes::TotalPhys));
+
+    return FloatRegisterSet(bits);
+}
+
+uint32_t
+FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s)
+{
+    SetType all = s.bits();
+    SetType float32x4Set =
+        (all >> (uint32_t(Codes::Float32x4) * Codes::TotalPhys)) & Codes::AllPhysMask;
+    SetType int32x4Set =
+        (all >> (uint32_t(Codes::Int32x4) * Codes::TotalPhys)) & Codes::AllPhysMask;
+    SetType doubleSet =
+        (all >> (uint32_t(Codes::Double) * Codes::TotalPhys)) & Codes::AllPhysMask;
+    SetType singleSet =
+        (all >> (uint32_t(Codes::Single) * Codes::TotalPhys)) & Codes::AllPhysMask;
+
+    // PushRegsInMask pushes the largest register first, and thus avoids pushing
+    // aliased registers. So we have to filter out the physical registers which
+    // are already pushed as part of larger registers.
+    SetType set128b = int32x4Set | float32x4Set;
+    SetType set64b = doubleSet & ~set128b;
+    SetType set32b = singleSet & ~set64b  & ~set128b;
+
+    static_assert(Codes::AllPhysMask <= 0xffff, "We can safely use CountPopulation32");
+    uint32_t count32b = mozilla::CountPopulation32(set32b);
+
+#if defined(JS_CODEGEN_X64)
+    // If we have an odd number of 32 bits values, then we increase the size to
+    // keep the stack aligned on 8 bytes. Note: Keep in sync with
+    // PushRegsInMask, and PopRegsInMaskIgnore.
+    count32b += count32b & 1;
+#endif
+
+    return mozilla::CountPopulation32(set128b) * (4 * sizeof(int32_t))
+        + mozilla::CountPopulation32(set64b) * sizeof(double)
+        + count32b * sizeof(float);
+}
+uint32_t
+FloatRegister::getRegisterDumpOffsetInBytes()
+{
+    return uint32_t(encoding()) * sizeof(FloatRegisters::RegisterContent);
+}
rename from js/src/jit/x64/Architecture-x64.h
rename to js/src/jit/x86-shared/Architecture-x86-shared.h
--- a/js/src/jit/x64/Architecture-x64.h
+++ b/js/src/jit/x86-shared/Architecture-x86-shared.h
@@ -1,139 +1,193 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef jit_x64_Architecture_x64_h
-#define jit_x64_Architecture_x64_h
+#ifndef jit_x86_shared_Architecture_x86_h
+#define jit_x86_shared_Architecture_x86_h
+
+#if !defined(JS_CODEGEN_X86) && !defined(JS_CODEGEN_X64)
+# error "Unsupported architecture!"
+#endif
 
 #include "jit/x86-shared/Constants-x86-shared.h"
 
 namespace js {
 namespace jit {
 
+#if defined(JS_CODEGEN_X86)
+// In bytes: slots needed for potential memory->memory move spills.
+//   +8 for cycles
+//   +4 for gpr spills
+//   +8 for double spills
+static const uint32_t ION_FRAME_SLACK_SIZE    = 20;
+
+#elif defined(JS_CODEGEN_X64)
 // In bytes: slots needed for potential memory->memory move spills.
 //   +8 for cycles
 //   +8 for gpr spills
 //   +8 for double spills
 static const uint32_t ION_FRAME_SLACK_SIZE     = 24;
+#endif
 
-#ifdef _WIN64
+#if defined(JS_CODEGEN_X86)
+// These offsets are specific to nunboxing, and capture offsets into the
+// components of a js::Value.
+static const int32_t NUNBOX32_TYPE_OFFSET         = 4;
+static const int32_t NUNBOX32_PAYLOAD_OFFSET      = 0;
+
+// Size of each bailout table entry. On x86 this is a 5-byte relative call.
+static const uint32_t BAILOUT_TABLE_ENTRY_SIZE    = 5;
+#endif
+
+#if defined(JS_CODEGEN_X64) && defined(_WIN64)
 static const uint32_t ShadowStackSpace = 32;
 #else
 static const uint32_t ShadowStackSpace = 0;
 #endif
 
 class Registers {
   public:
     typedef X86Encoding::RegisterID Code;
     typedef X86Encoding::RegisterID Encoding;
 
     // Content spilled during bailouts.
     union RegisterContent {
         uintptr_t r;
     };
 
-    typedef uint32_t SetType;
+#if defined(JS_CODEGEN_X86)
+    typedef uint8_t SetType;
+
+    static const char* GetName(Code code) {
+        return X86Encoding::GPRegName(code);
+    }
+
+    static const uint32_t Total = 8;
+    static const uint32_t TotalPhys = 8;
+    static const uint32_t Allocatable = 7;
+
+#elif defined(JS_CODEGEN_X64)
+    typedef uint16_t SetType;
+
+    static const char* GetName(Code code) {
+        static const char * const Names[] = { "rax", "rcx", "rdx", "rbx",
+                                              "rsp", "rbp", "rsi", "rdi",
+                                              "r8",  "r9",  "r10", "r11",
+                                              "r12", "r13", "r14", "r15" };
+        return Names[code];
+    }
+
+    static const uint32_t Total = 16;
+    static const uint32_t TotalPhys = 16;
+    static const uint32_t Allocatable = 14;
+#endif
+
     static uint32_t SetSize(SetType x) {
-        static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
+        static_assert(sizeof(SetType) <= 4, "SetType must be, at most, 32 bits");
         return mozilla::CountPopulation32(x);
     }
     static uint32_t FirstBit(SetType x) {
         return mozilla::CountTrailingZeroes32(x);
     }
     static uint32_t LastBit(SetType x) {
         return 31 - mozilla::CountLeadingZeroes32(x);
     }
-    static const char* GetName(Code code) {
-        static const char * const Names[] = { "rax", "rcx", "rdx", "rbx",
-                                              "rsp", "rbp", "rsi", "rdi",
-                                              "r8",  "r9",  "r10", "r11",
-                                              "r12", "r13", "r14", "r15" };
-        return Names[code];
-    }
 
     static Code FromName(const char* name) {
         for (size_t i = 0; i < Total; i++) {
             if (strcmp(GetName(Code(i)), name) == 0)
                 return Code(i);
         }
         return Invalid;
     }
 
     static const Code StackPointer = X86Encoding::rsp;
     static const Code Invalid = X86Encoding::invalid_reg;
 
-    static const uint32_t Total = 16;
-    static const uint32_t TotalPhys = 16;
-    static const uint32_t Allocatable = 14;
-
     static const SetType AllMask = (1 << Total) - 1;
 
+#if defined(JS_CODEGEN_X86)
+    static const SetType ArgRegMask = 0;
+
+    static const SetType VolatileMask =
+        (1 << X86Encoding::rax) |
+        (1 << X86Encoding::rcx) |
+        (1 << X86Encoding::rdx);
+
+    static const SetType WrapperMask =
+        VolatileMask |
+        (1 << X86Encoding::rbx);
+
+    static const SetType SingleByteRegs =
+        (1 << X86Encoding::rax) |
+        (1 << X86Encoding::rcx) |
+        (1 << X86Encoding::rdx) |
+        (1 << X86Encoding::rbx);
+
+    static const SetType NonAllocatableMask =
+        (1 << X86Encoding::rsp);
+
+    // Registers returned from a JS -> JS call.
+    static const SetType JSCallMask =
+        (1 << X86Encoding::rcx) |
+        (1 << X86Encoding::rdx);
+
+    // Registers returned from a JS -> C call.
+    static const SetType CallMask =
+        (1 << X86Encoding::rax);
+
+#elif defined(JS_CODEGEN_X64)
     static const SetType ArgRegMask =
 # if !defined(_WIN64)
         (1 << X86Encoding::rdi) |
         (1 << X86Encoding::rsi) |
 # endif
         (1 << X86Encoding::rdx) |
         (1 << X86Encoding::rcx) |
         (1 << X86Encoding::r8) |
         (1 << X86Encoding::r9);
 
     static const SetType VolatileMask =
         (1 << X86Encoding::rax) |
-        (1 << X86Encoding::rcx) |
-        (1 << X86Encoding::rdx) |
-# if !defined(_WIN64)
-        (1 << X86Encoding::rsi) |
-        (1 << X86Encoding::rdi) |
-# endif
-        (1 << X86Encoding::r8) |
-        (1 << X86Encoding::r9) |
+        ArgRegMask |
         (1 << X86Encoding::r10) |
         (1 << X86Encoding::r11);
 
-    static const SetType NonVolatileMask =
-        (1 << X86Encoding::rbx) |
-#if defined(_WIN64)
-        (1 << X86Encoding::rsi) |
-        (1 << X86Encoding::rdi) |
-#endif
-        (1 << X86Encoding::rbp) |
-        (1 << X86Encoding::r12) |
-        (1 << X86Encoding::r13) |
-        (1 << X86Encoding::r14) |
-        (1 << X86Encoding::r15);
-
     static const SetType WrapperMask = VolatileMask;
 
-    static const SetType SingleByteRegs = VolatileMask | NonVolatileMask;
+    static const SetType SingleByteRegs = AllMask & ~(1 << X86Encoding::rsp);
 
     static const SetType NonAllocatableMask =
         (1 << X86Encoding::rsp) |
         (1 << X86Encoding::r11);      // This is ScratchReg.
 
-    static const SetType AllocatableMask = AllMask & ~NonAllocatableMask;
-
-    // Registers that can be allocated without being saved, generally.
-    static const SetType TempMask = VolatileMask & ~NonAllocatableMask;
-
     // Registers returned from a JS -> JS call.
     static const SetType JSCallMask =
         (1 << X86Encoding::rcx);
 
     // Registers returned from a JS -> C call.
     static const SetType CallMask =
         (1 << X86Encoding::rax);
+
+#endif
+
+    static const SetType NonVolatileMask =
+        AllMask & ~VolatileMask & ~(1 << X86Encoding::rsp);
+
+    static const SetType AllocatableMask = AllMask & ~NonAllocatableMask;
+
+    // Registers that can be allocated without being saved, generally.
+    static const SetType TempMask = VolatileMask & ~NonAllocatableMask;
 };
 
-// Smallest integer type that can hold a register bitmask.
-typedef uint16_t PackedRegisterMask;
+typedef Registers::SetType PackedRegisterMask;
 
 class FloatRegisters {
   public:
     typedef X86Encoding::XMMRegisterID Encoding;
 
     enum ContentType {
         Single,
         Double,
@@ -159,21 +213,30 @@ class FloatRegisters {
             if (strcmp(GetName(Encoding(i)), name) == 0)
                 return Encoding(i);
         }
         return Invalid;
     }
 
     static const Encoding Invalid = X86Encoding::invalid_xmm;
 
+#if defined(JS_CODEGEN_X86)
+    static const uint32_t Total = 8 * NumTypes;
+    static const uint32_t TotalPhys = 8;
+    static const uint32_t Allocatable = 7;
+    typedef uint32_t SetType;
+
+#elif defined(JS_CODEGEN_X64)
     static const uint32_t Total = 16 * NumTypes;
     static const uint32_t TotalPhys = 16;
     static const uint32_t Allocatable = 15;
+    typedef uint64_t SetType;
 
-    typedef uint64_t SetType;
+#endif
+
     static_assert(sizeof(SetType) * 8 >= Total,
                   "SetType should be large enough to enumerate all registers.");
 
     // Magic values which are used to duplicate a mask of physical register for
     // a specific type of register. A multiplication is used to copy and shift
     // the bits of the physical register mask.
     static const SetType SpreadSingle = SetType(1) << (uint32_t(Single) * TotalPhys);
     static const SetType SpreadDouble = SetType(1) << (uint32_t(Double) * TotalPhys);
@@ -181,78 +244,101 @@ class FloatRegisters {
     static const SetType SpreadFloat32x4 = SetType(1) << (uint32_t(Float32x4) * TotalPhys);
     static const SetType SpreadScalar = SpreadSingle | SpreadDouble;
     static const SetType SpreadVector = SpreadInt32x4 | SpreadFloat32x4;
     static const SetType Spread = SpreadScalar | SpreadVector;
 
     static const SetType AllPhysMask = ((1 << TotalPhys) - 1);
     static const SetType AllMask = AllPhysMask * Spread;
     static const SetType AllDoubleMask = AllPhysMask * SpreadDouble;
+
+#if defined(JS_CODEGEN_X86)
+    static const SetType NonAllocatableMask =
+        Spread * (1 << X86Encoding::xmm7);     // This is ScratchDoubleReg.
+
+#elif defined(JS_CODEGEN_X64)
+    static const SetType NonAllocatableMask =
+        Spread * (1 << X86Encoding::xmm15);    // This is ScratchDoubleReg.
+#endif
+
+#if defined(JS_CODEGEN_X64) && defined(_WIN64)
     static const SetType VolatileMask =
-#if defined(_WIN64)
         ( (1 << X86Encoding::xmm0) |
           (1 << X86Encoding::xmm1) |
           (1 << X86Encoding::xmm2) |
           (1 << X86Encoding::xmm3) |
           (1 << X86Encoding::xmm4) |
           (1 << X86Encoding::xmm5)
         ) * SpreadScalar
         | AllPhysMask * SpreadVector;
+
 #else
+    static const SetType VolatileMask =
         AllMask;
 #endif
 
     static const SetType NonVolatileMask = AllMask & ~VolatileMask;
-
     static const SetType WrapperMask = VolatileMask;
-
-    static const SetType NonAllocatableMask =
-        Spread * (1 << X86Encoding::xmm15);    // This is ScratchDoubleReg.
-
     static const SetType AllocatableMask = AllMask & ~NonAllocatableMask;
 };
 
 template <typename T>
 class TypedRegisterSet;
 
 struct FloatRegister {
     typedef FloatRegisters Codes;
     typedef size_t Code;
     typedef Codes::Encoding Encoding;
     typedef Codes::SetType SetType;
     static uint32_t SetSize(SetType x) {
-        static_assert(sizeof(SetType) == 8, "SetType must be 64 bits");
         // Count the number of non-aliased registers, for the moment.
         //
         // Copy the set bits of each typed register to the low part of the of
         // the Set, and count the number of registers. This is made to avoid
         // registers which are allocated twice with different types (such as in
         // AllMask).
         x |= x >> (2 * Codes::TotalPhys);
         x |= x >> Codes::TotalPhys;
         x &= Codes::AllPhysMask;
         static_assert(Codes::AllPhysMask <= 0xffff, "We can safely use CountPopulation32");
         return mozilla::CountPopulation32(x);
     }
+
+#if defined(JS_CODEGEN_X86)
     static uint32_t FirstBit(SetType x) {
+        static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
+        return mozilla::CountTrailingZeroes32(x);
+    }
+    static uint32_t LastBit(SetType x) {
+        return 31 - mozilla::CountLeadingZeroes32(x);
+    }
+
+#elif defined(JS_CODEGEN_X64)
+    static uint32_t FirstBit(SetType x) {
+        static_assert(sizeof(SetType) == 8, "SetType must be 64 bits");
         return mozilla::CountTrailingZeroes64(x);
     }
     static uint32_t LastBit(SetType x) {
         return 63 - mozilla::CountLeadingZeroes64(x);
     }
+#endif
 
   private:
     // Note: These fields are using one extra bit to make the invalid enumerated
     // values fit, and thus prevent a warning.
     Codes::Encoding reg_ : 5;
     Codes::ContentType type_ : 3;
     bool isInvalid_ : 1;
 
     // Constants used for exporting/importing the float register code.
+#if defined(JS_CODEGEN_X86)
+    static const size_t RegSize = 3;
+#elif defined(JS_CODEGEN_X64)
     static const size_t RegSize = 4;
+#endif
     static const size_t RegMask = (1 << RegSize) - 1;
 
   public:
     MOZ_CONSTEXPR FloatRegister()
         : reg_(Codes::Encoding(0)), type_(Codes::Single), isInvalid_(true)
     { }
     MOZ_CONSTEXPR FloatRegister(uint32_t r, Codes::ContentType k)
         : reg_(Codes::Encoding(r)), type_(k), isInvalid_(false)
@@ -363,9 +449,9 @@ hasMultiAlias()
 // Support some constant-offset addressing.
 // See the comments above AsmJSMappedSize in AsmJSValidate.h for more info.
 static const size_t AsmJSCheckedImmediateRange = 4096;
 static const size_t AsmJSImmediateRange = UINT32_C(0x80000000);
 
 } // namespace jit
 } // namespace js
 
-#endif /* jit_x64_Architecture_x64_h */
+#endif /* jit_x86_shared_Architecture_x86_h */
--- a/js/src/jit/x86-shared/Assembler-x86-shared.cpp
+++ b/js/src/jit/x86-shared/Assembler-x86-shared.cpp
@@ -288,37 +288,8 @@ CPUInfo::SetSSEVersion()
     // If the hardware supports AVX, check whether the OS supports it too.
     if (avxPresent) {
         size_t xcr0EAX = ReadXGETBV();
         static const int xcr0SSEBit = 1 << 1;
         static const int xcr0AVXBit = 1 << 2;
         avxPresent = (xcr0EAX & xcr0SSEBit) && (xcr0EAX & xcr0AVXBit);
     }
 }
-
-const char*
-FloatRegister::name() const {
-    static const char* const names[] = {
-
-#ifdef JS_CODEGEN_X64
-#define FLOAT_REGS_(TYPE) \
-        "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, \
-        "%xmm4" TYPE, "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE, \
-        "%xmm8" TYPE, "%xmm9" TYPE, "%xmm10" TYPE, "%xmm11" TYPE, \
-        "%xmm12" TYPE, "%xmm13" TYPE, "%xmm14" TYPE, "%xmm15" TYPE
-#else
-#define FLOAT_REGS_(TYPE) \
-        "%xmm0" TYPE, "%xmm1" TYPE, "%xmm2" TYPE, "%xmm3" TYPE, \
-        "%xmm4" TYPE, "%xmm5" TYPE, "%xmm6" TYPE, "%xmm7" TYPE
-#endif
-
-        // These should be enumerated in the same order as in
-        // FloatRegisters::ContentType.
-        FLOAT_REGS_(".s"),
-        FLOAT_REGS_(".d"),
-        FLOAT_REGS_(".i4"),
-        FLOAT_REGS_(".s4")
-#undef FLOAT_REGS_
-
-    };
-    MOZ_ASSERT(size_t(code()) < mozilla::ArrayLength(names));
-    return names[size_t(code())];
-}
deleted file mode 100644
--- a/js/src/jit/x86/Architecture-x86.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef jit_x86_Architecture_x86_h
-#define jit_x86_Architecture_x86_h
-
-#include "jit/x86-shared/Constants-x86-shared.h"
-
-namespace js {
-namespace jit {
-
-// In bytes: slots needed for potential memory->memory move spills.
-//   +8 for cycles
-//   +4 for gpr spills
-//   +8 for double spills
-static const uint32_t ION_FRAME_SLACK_SIZE    = 20;
-
-// Only Win64 requires shadow stack space.
-static const uint32_t ShadowStackSpace = 0;
-
-// These offsets are specific to nunboxing, and capture offsets into the
-// components of a js::Value.
-static const int32_t NUNBOX32_TYPE_OFFSET         = 4;
-static const int32_t NUNBOX32_PAYLOAD_OFFSET      = 0;
-
-////
-// These offsets are related to bailouts.
-////
-
-// Size of each bailout table entry. On x86 this is a 5-byte relative call.
-static const uint32_t BAILOUT_TABLE_ENTRY_SIZE    = 5;
-
-class Registers {
-  public:
-    typedef X86Encoding::RegisterID Code;
-    typedef X86Encoding::RegisterID Encoding;
-
-    // Content spilled during bailouts.
-    union RegisterContent {
-        uintptr_t r;
-    };
-
-    typedef uint8_t SetType;
-    static uint32_t SetSize(SetType x) {
-        static_assert(sizeof(SetType) == 1, "SetType must be 8 bits");
-        return mozilla::CountPopulation32(x);
-    }
-    static uint32_t FirstBit(SetType x) {
-        return mozilla::CountTrailingZeroes32(x);
-    }
-    static uint32_t LastBit(SetType x) {
-        return 31 - mozilla::CountLeadingZeroes32(x);
-    }
-    static const char* GetName(Code code) {
-        return X86Encoding::GPRegName(code);
-    }
-
-    static Code FromName(const char* name) {
-        for (size_t i = 0; i < Total; i++) {
-            if (strcmp(GetName(Code(i)), name) == 0)
-                return Code(i);
-        }
-        return Invalid;
-    }
-
-    static const Code StackPointer = X86Encoding::rsp;
-    static const Code Invalid = X86Encoding::invalid_reg;
-
-    static const uint32_t Total = 8;
-    static const uint32_t TotalPhys = 8;
-    static const uint32_t Allocatable = 7;
-
-    static const SetType AllMask = (1 << Total) - 1;
-
-    static const SetType ArgRegMask = 0;
-
-    static const SetType VolatileMask =
-        (1 << X86Encoding::rax) |
-        (1 << X86Encoding::rcx) |
-        (1 << X86Encoding::rdx);
-
-    static const SetType NonVolatileMask =
-        (1 << X86Encoding::rbx) |
-        (1 << X86Encoding::rsi) |
-        (1 << X86Encoding::rdi) |
-        (1 << X86Encoding::rbp);
-
-    static const SetType WrapperMask =
-        VolatileMask |
-        (1 << X86Encoding::rbx);
-
-    static const SetType SingleByteRegs =
-        (1 << X86Encoding::rax) |
-        (1 << X86Encoding::rcx) |
-        (1 << X86Encoding::rdx) |
-        (1 << X86Encoding::rbx);
-
-    static const SetType NonAllocatableMask =
-        (1 << X86Encoding::rsp);
-
-    static const SetType AllocatableMask = AllMask & ~NonAllocatableMask;
-
-    // Registers that can be allocated without being saved, generally.
-    static const SetType TempMask = VolatileMask & ~NonAllocatableMask;
-
-    // Registers returned from a JS -> JS call.
-    static const SetType JSCallMask =
-        (1 << X86Encoding::rcx) |
-        (1 << X86Encoding::rdx);
-
-    // Registers returned from a JS -> C call.
-    static const SetType CallMask =
-        (1 << X86Encoding::rax);
-};
-
-// Smallest integer type that can hold a register bitmask.
-typedef uint8_t PackedRegisterMask;
-
-class FloatRegisters {
-  public:
-    typedef X86Encoding::XMMRegisterID Encoding;
-
-    enum ContentType {
-        Single,
-        Double,
-        Int32x4,
-        Float32x4,
-        NumTypes
-    };
-
-    // Content spilled during bailouts.
-    union RegisterContent {
-        float s;
-        double d;
-        int32_t i4[4];
-        float s4[4];
-    };
-
-    static const char* GetName(Encoding code) {
-        return X86Encoding::XMMRegName(code);
-    }
-
-    static Encoding FromName(const char* name) {
-        for (size_t i = 0; i < Total; i++) {
-            if (strcmp(GetName(Encoding(i)), name) == 0)
-                return Encoding(i);
-        }
-        return Invalid;
-    }
-
-    static const Encoding Invalid = X86Encoding::invalid_xmm;
-
-    static const uint32_t Total = 8 * NumTypes;
-    static const uint32_t TotalPhys = 8;
-    static const uint32_t Allocatable = 7;
-
-    typedef uint32_t SetType;
-    static_assert(sizeof(SetType) * 8 >= Total,
-                  "SetType should be large enough to enumerate all registers.");
-
-    // Magic values which are used to duplicate a mask of physical register for
-    // a specific type of register. A multiplication is used to copy and shift
-    // the bits of the physical register mask.
-    static const SetType SpreadSingle = SetType(1) << (uint32_t(Single) * TotalPhys);
-    static const SetType SpreadDouble = SetType(1) << (uint32_t(Double) * TotalPhys);
-    static const SetType SpreadInt32x4 = SetType(1) << (uint32_t(Int32x4) * TotalPhys);
-    static const SetType SpreadFloat32x4 = SetType(1) << (uint32_t(Float32x4) * TotalPhys);
-    static const SetType SpreadScalar = SpreadSingle | SpreadDouble;
-    static const SetType SpreadVector = SpreadInt32x4 | SpreadFloat32x4;
-    static const SetType Spread = SpreadScalar | SpreadVector;
-
-    static const SetType AllPhysMask = ((1 << TotalPhys) - 1);
-    static const SetType AllMask = AllPhysMask * Spread;
-    static const SetType AllDoubleMask = AllPhysMask * SpreadDouble;
-    static const SetType VolatileMask = AllMask;
-    static const SetType NonVolatileMask = 0;
-
-    static const SetType WrapperMask = VolatileMask;
-
-    static const SetType NonAllocatableMask =
-        Spread * (1 << X86Encoding::xmm7);     // This is ScratchDoubleReg.
-
-    static const SetType AllocatableMask = AllMask & ~NonAllocatableMask;
-};
-
-template <typename T>
-class TypedRegisterSet;
-
-struct FloatRegister {
-    typedef FloatRegisters Codes;
-    typedef size_t Code;
-    typedef Codes::Encoding Encoding;
-    typedef Codes::SetType SetType;
-    static uint32_t SetSize(SetType x) {
-        static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
-        // Count the number of non-aliased registers, for the moment.
-        //
-        // Copy the set bits of each typed register to the low part of the of
-        // the Set, and count the number of registers. This is made to avoid
-        // registers which are allocated twice with different types (such as in
-        // AllMask).
-        x |= x >> (2 * Codes::TotalPhys);
-        x |= x >> Codes::TotalPhys;
-        x &= Codes::AllPhysMask;
-        static_assert(Codes::AllPhysMask <= 0xffff, "We can safely use CountPopulation32");
-        return mozilla::CountPopulation32(x);
-    }
-    static uint32_t FirstBit(SetType x) {
-        return mozilla::CountTrailingZeroes32(x);
-    }
-    static uint32_t LastBit(SetType x) {
-        return 31 - mozilla::CountLeadingZeroes32(x);
-    }
-
-  private:
-    // Note: These fields are using one extra bit to make the invalid enumerated
-    // values fit, and thus prevent a warning.
-    Codes::Encoding reg_ : 4;
-    Codes::ContentType type_ : 3;
-    bool isInvalid_ : 1;
-
-    // Constants used for exporting/importing the float register code.
-    static const size_t RegSize = 3;
-    static const size_t RegMask = (1 << RegSize) - 1;
-
-  public:
-    MOZ_CONSTEXPR FloatRegister()
-        : reg_(Codes::Encoding(0)), type_(Codes::Single), isInvalid_(true)
-    { }
-    MOZ_CONSTEXPR FloatRegister(uint32_t r, Codes::ContentType k)
-        : reg_(Codes::Encoding(r)), type_(k), isInvalid_(false)
-    { }
-
-    static FloatRegister FromCode(uint32_t i) {
-        MOZ_ASSERT(i < Codes::Total);
-        return FloatRegister(i & RegMask, Codes::ContentType(i >> RegSize));
-    }
-
-    bool isSingle() const { MOZ_ASSERT(!isInvalid()); return type_ == Codes::Single; }
-    bool isDouble() const { MOZ_ASSERT(!isInvalid()); return type_ == Codes::Double; }
-    bool isInt32x4() const { MOZ_ASSERT(!isInvalid()); return type_ == Codes::Int32x4; }
-    bool isFloat32x4() const { MOZ_ASSERT(!isInvalid()); return type_ == Codes::Float32x4; }
-    bool isInvalid() const { return isInvalid_; }
-
-    FloatRegister asSingle() const { MOZ_ASSERT(!isInvalid()); return FloatRegister(reg_, Codes::Single); }
-    FloatRegister asDouble() const { MOZ_ASSERT(!isInvalid()); return FloatRegister(reg_, Codes::Double); }
-    FloatRegister asInt32x4() const { MOZ_ASSERT(!isInvalid()); return FloatRegister(reg_, Codes::Int32x4); }
-    FloatRegister asFloat32x4() const { MOZ_ASSERT(!isInvalid()); return FloatRegister(reg_, Codes::Float32x4); }
-
-    uint32_t size() const {
-        MOZ_ASSERT(!isInvalid());
-        if (isSingle())
-            return sizeof(float);
-        if (isDouble())
-            return sizeof(double);
-        MOZ_ASSERT(isInt32x4() || isFloat32x4());
-        return 4 * sizeof(int32_t);
-    }
-
-    Code code() const {
-        MOZ_ASSERT(!isInvalid());
-        MOZ_ASSERT(uint32_t(reg_) < Codes::TotalPhys);
-        // :TODO: ARM is doing the same thing, but we should avoid this, except
-        // that the RegisterSets depends on this.
-        return Code(reg_ | (type_ << RegSize));
-    }
-    Encoding encoding() const {
-        MOZ_ASSERT(!isInvalid());
-        MOZ_ASSERT(uint32_t(reg_) < Codes::TotalPhys);
-        return reg_;
-    }
-    // defined in Assembler-x86-shared.cpp
-    const char* name() const;
-    bool volatile_() const {
-        return !!((SetType(1) << code()) & FloatRegisters::VolatileMask);
-    }
-    bool operator !=(FloatRegister other) const {
-        return other.reg_ != reg_ || other.type_ != type_;
-    }
-    bool operator ==(FloatRegister other) const {
-        return other.reg_ == reg_ && other.type_ == type_;
-    }
-    bool aliases(FloatRegister other) const {
-        return other.reg_ == reg_;
-    }
-    // Check if two floating point registers have the same type.
-    bool equiv(FloatRegister other) const {
-        return other.type_ == type_;
-    }
-
-    uint32_t numAliased() const {
-        return Codes::NumTypes;
-    }
-    uint32_t numAlignedAliased() const {
-        return numAliased();
-    }
-
-    // N.B. FloatRegister is an explicit outparam here because msvc-2010
-    // miscompiled it on win64 when the value was simply returned
-    void aliased(uint32_t aliasIdx, FloatRegister* ret) const {
-        MOZ_ASSERT(aliasIdx < Codes::NumTypes);
-        *ret = FloatRegister(reg_, Codes::ContentType((aliasIdx + type_) % Codes::NumTypes));
-    }
-    void alignedAliased(uint32_t aliasIdx, FloatRegister* ret) const {
-        aliased(aliasIdx, ret);
-    }
-
-    SetType alignedOrDominatedAliasedSet() const {
-        return Codes::Spread << reg_;
-    }
-
-    static TypedRegisterSet<FloatRegister> ReduceSetForPush(const TypedRegisterSet<FloatRegister>& s);
-    static uint32_t GetPushSizeInBytes(const TypedRegisterSet<FloatRegister>& s);
-    uint32_t getRegisterDumpOffsetInBytes();
-};
-
-// Arm/D32 has double registers that can NOT be treated as float32
-// and this requires some dances in lowering.
-inline bool
-hasUnaliasedDouble()
-{
-    return false;
-}
-
-// On ARM, Dn aliases both S2n and S2n+1, so if you need to convert a float32
-// to a double as a temporary, you need a temporary double register.
-inline bool
-hasMultiAlias()
-{
-    return false;
-}
-
-// Support some constant-offset addressing.
-// See the comments above AsmJSMappedSize in AsmJSValidate.h for more info.
-static const size_t AsmJSCheckedImmediateRange = 4096;
-static const size_t AsmJSImmediateRange = UINT32_C(0x80000000);
-
-} // namespace jit
-} // namespace js
-
-#endif /* jit_x86_Architecture_x86_h */
--- a/js/src/jit/x86/Assembler-x86.cpp
+++ b/js/src/jit/x86/Assembler-x86.cpp
@@ -96,58 +96,8 @@ Assembler::TraceJumpRelocations(JSTracer
 {
     RelocationIterator iter(reader);
     while (iter.read()) {
         JitCode* child = CodeFromJump(code->raw() + iter.offset());
         MarkJitCodeUnbarriered(trc, &child, "rel32");
         MOZ_ASSERT(child == CodeFromJump(code->raw() + iter.offset()));
     }
 }
-
-FloatRegisterSet
-FloatRegister::ReduceSetForPush(const FloatRegisterSet& s)
-{
-    SetType bits = s.bits();
-
-    // Ignore all SIMD register, if not supported.
-    if (!JitSupportsSimd())
-        bits &= Codes::AllPhysMask * Codes::SpreadScalar;
-
-    // Exclude registers which are already pushed with a larger type. High bits
-    // are associated with larger register types. Thus we keep the set of
-    // registers which are not included in larger type.
-    bits &= ~(bits >> (1 * Codes::TotalPhys));
-    bits &= ~(bits >> (2 * Codes::TotalPhys));
-    bits &= ~(bits >> (3 * Codes::TotalPhys));
-
-    return FloatRegisterSet(bits);
-}
-
-uint32_t
-FloatRegister::GetPushSizeInBytes(const FloatRegisterSet& s)
-{
-    SetType all = s.bits();
-    SetType float32x4Set =
-        (all >> (uint32_t(Codes::Float32x4) * Codes::TotalPhys)) & Codes::AllPhysMask;
-    SetType int32x4Set =
-        (all >> (uint32_t(Codes::Int32x4) * Codes::TotalPhys)) & Codes::AllPhysMask;
-    SetType doubleSet =
-        (all >> (uint32_t(Codes::Double) * Codes::TotalPhys)) & Codes::AllPhysMask;
-    SetType singleSet =
-        (all >> (uint32_t(Codes::Single) * Codes::TotalPhys)) & Codes::AllPhysMask;
-
-    // PushRegsInMask pushes the largest register first, and thus avoids pushing
-    // aliased registers. So we have to filter out the physical registers which
-    // are already pushed as part of larger registers.
-    SetType set128b = int32x4Set | float32x4Set;
-    SetType set64b = doubleSet & ~set128b;
-    SetType set32b = singleSet & ~set64b  & ~set128b;
-
-    static_assert(Codes::AllPhysMask <= 0xffff, "We can safely use CountPopulation32");
-    return mozilla::CountPopulation32(set128b) * (4 * sizeof(int32_t))
-        + mozilla::CountPopulation32(set64b) * sizeof(double)
-        + mozilla::CountPopulation32(set32b) * sizeof(float);
-}
-uint32_t
-FloatRegister::getRegisterDumpOffsetInBytes()
-{
-    return uint32_t(encoding()) * sizeof(FloatRegisters::RegisterContent);
-}
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -360,16 +360,17 @@ if CONFIG['ENABLE_TRACE_LOGGING']:
     ]
 
 if not CONFIG['ENABLE_ION']:
     UNIFIED_SOURCES += [
         'jit/none/Trampoline-none.cpp'
     ]
 elif CONFIG['JS_CODEGEN_X86'] or CONFIG['JS_CODEGEN_X64']:
     UNIFIED_SOURCES += [
+        'jit/x86-shared/Architecture-x86-shared.cpp',
         'jit/x86-shared/Assembler-x86-shared.cpp',
         'jit/x86-shared/AssemblerBuffer-x86-shared.cpp',
         'jit/x86-shared/BaselineCompiler-x86-shared.cpp',
         'jit/x86-shared/BaselineIC-x86-shared.cpp',
         'jit/x86-shared/CodeGenerator-x86-shared.cpp',
         'jit/x86-shared/Disassembler-x86-shared.cpp',
         'jit/x86-shared/Lowering-x86-shared.cpp',
         'jit/x86-shared/MacroAssembler-x86-shared.cpp',