Revert of Remove register index/code indirection (patchset #17 id:320001 of https...
authordanno <danno@chromium.org>
Thu, 24 Sep 2015 13:38:50 +0000 (06:38 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 24 Sep 2015 13:39:03 +0000 (13:39 +0000)
Reason for revert:
Failures on greedy RegAlloc, Fuzzer

Original issue's description:
> Remove register index/code indirection
>
> Previous to this patch, both the lithium and TurboFan register
> allocators tracked allocated registers by "indices", rather than
> the register codes used elsewhere in the runtime. This patch
> ensures that codes are used everywhere, and in the process cleans
> up a bunch of redundant code and adds more structure to how the
> set of allocatable registers is defined.
>
> Some highlights of changes:
>
> * TurboFan's RegisterConfiguration class moved to V8's top level
>   so that it can be shared with Crankshaft.
> * Various "ToAllocationIndex" and related methods removed.
> * Code that can be easily shared between Register classes on
>   different platforms is now shared.
> * The list of allocatable registers on each platform is declared
>   as a list rather than implicitly via the register index <->
>   code mapping.
>
> Committed: https://crrev.com/80bc6f6e11f79524e3f1ad05579583adfd5f18b2
> Cr-Commit-Position: refs/heads/master@{#30913}

TBR=akos.palfi@imgtec.com,bmeurer@chromium.org,jarin@chromium.org,paul.lind@imgtec.com,titzer@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Review URL: https://codereview.chromium.org/1365073002

Cr-Commit-Position: refs/heads/master@{#30914}

93 files changed:
BUILD.gn
src/arm/assembler-arm-inl.h
src/arm/assembler-arm.cc
src/arm/assembler-arm.h
src/arm/constants-arm.cc
src/arm/deoptimizer-arm.cc
src/arm/disasm-arm.cc
src/arm/lithium-arm.cc
src/arm/lithium-codegen-arm.cc
src/arm/macro-assembler-arm.cc
src/arm/macro-assembler-arm.h
src/arm/simulator-arm.cc
src/arm64/assembler-arm64.cc
src/arm64/assembler-arm64.h
src/arm64/constants-arm64.h
src/arm64/deoptimizer-arm64.cc
src/arm64/lithium-arm64.cc
src/arm64/lithium-codegen-arm64.cc
src/arm64/macro-assembler-arm64.cc
src/arm64/simulator-arm64.h
src/arm64/utils-arm64.h
src/assembler.cc
src/assembler.h
src/compiler/c-linkage.cc
src/compiler/code-generator-impl.h
src/compiler/code-generator.cc
src/compiler/graph-visualizer.cc
src/compiler/instruction-selector-impl.h
src/compiler/instruction.cc
src/compiler/instruction.h
src/compiler/linkage.cc
src/compiler/pipeline.cc
src/compiler/pipeline.h
src/compiler/register-allocator-verifier.cc
src/compiler/register-allocator.cc
src/compiler/register-allocator.h
src/compiler/register-configuration.cc [new file with mode: 0644]
src/compiler/register-configuration.h [new file with mode: 0644]
src/deoptimizer.cc
src/frames.cc
src/hydrogen.cc
src/ia32/assembler-ia32.h
src/ia32/code-stubs-ia32.h
src/ia32/deoptimizer-ia32.cc
src/ia32/lithium-codegen-ia32.cc
src/ia32/lithium-gap-resolver-ia32.cc
src/ia32/lithium-gap-resolver-ia32.h
src/ia32/lithium-ia32.cc
src/ia32/macro-assembler-ia32.h
src/lithium-allocator.cc
src/lithium-allocator.h
src/lithium.cc
src/mips/assembler-mips-inl.h
src/mips/assembler-mips.cc
src/mips/assembler-mips.h
src/mips/deoptimizer-mips.cc
src/mips/lithium-codegen-mips.cc
src/mips/lithium-mips.cc
src/mips/macro-assembler-mips.cc
src/mips/macro-assembler-mips.h
src/mips64/assembler-mips64-inl.h
src/mips64/assembler-mips64.cc
src/mips64/assembler-mips64.h
src/mips64/deoptimizer-mips64.cc
src/mips64/lithium-codegen-mips64.cc
src/mips64/lithium-mips64.cc
src/mips64/macro-assembler-mips64.cc
src/mips64/macro-assembler-mips64.h
src/objects.cc
src/register-configuration.cc [deleted file]
src/register-configuration.h [deleted file]
src/x64/assembler-x64.cc
src/x64/assembler-x64.h
src/x64/code-stubs-x64.h
src/x64/deoptimizer-x64.cc
src/x64/lithium-codegen-x64.cc
src/x64/lithium-x64.cc
src/x64/macro-assembler-x64.cc
src/x64/macro-assembler-x64.h
src/x87/assembler-x87.h
test/cctest/compiler/test-gap-resolver.cc
test/cctest/compiler/test-run-native-calls.cc
test/cctest/test-code-stubs-arm.cc
test/cctest/test-code-stubs-arm64.cc
test/cctest/test-code-stubs-ia32.cc
test/cctest/test-code-stubs-mips.cc
test/cctest/test-code-stubs-mips64.cc
test/cctest/test-code-stubs-x64.cc
test/unittests/compiler/instruction-selector-unittest.cc
test/unittests/compiler/instruction-sequence-unittest.cc
test/unittests/compiler/instruction-sequence-unittest.h
test/unittests/compiler/register-allocator-unittest.cc
tools/gyp/v8.gyp

index 90b8fe237ced05720689aa690354485db10a5edc..a67948be1fd44aa53c1e149243469b9fc66546ea 100644 (file)
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -823,6 +823,8 @@ source_set("v8_base") {
     "src/compiler/register-allocator.h",
     "src/compiler/register-allocator-verifier.cc",
     "src/compiler/register-allocator-verifier.h",
+    "src/compiler/register-configuration.cc",
+    "src/compiler/register-configuration.h",
     "src/compiler/representation-change.h",
     "src/compiler/schedule.cc",
     "src/compiler/schedule.h",
@@ -1137,8 +1139,6 @@ source_set("v8_base") {
     "src/regexp/regexp-macro-assembler.h",
     "src/regexp/regexp-stack.cc",
     "src/regexp/regexp-stack.h",
-    "src/register-configuration.cc",
-    "src/register-configuration.h",
     "src/runtime-profiler.cc",
     "src/runtime-profiler.h",
     "src/runtime/runtime-array.cc",
index 0037e30ddac1b1467ce5bbc0b0cb8d6c1b03afd2..8f8956c9e1c7eb25890726abb3cfd3addeceeb54 100644 (file)
@@ -50,11 +50,53 @@ namespace internal {
 bool CpuFeatures::SupportsCrankshaft() { return IsSupported(VFP3); }
 
 
-int DoubleRegister::NumRegisters() {
+int Register::NumAllocatableRegisters() {
+  return kMaxNumAllocatableRegisters;
+}
+
+
+int DwVfpRegister::NumRegisters() {
   return CpuFeatures::IsSupported(VFP32DREGS) ? 32 : 16;
 }
 
 
+int DwVfpRegister::NumReservedRegisters() {
+  return kNumReservedRegisters;
+}
+
+
+int DwVfpRegister::NumAllocatableRegisters() {
+  return NumRegisters() - kNumReservedRegisters;
+}
+
+
+// static
+int DwVfpRegister::NumAllocatableAliasedRegisters() {
+  return LowDwVfpRegister::kMaxNumLowRegisters - kNumReservedRegisters;
+}
+
+
+int DwVfpRegister::ToAllocationIndex(DwVfpRegister reg) {
+  DCHECK(!reg.is(kDoubleRegZero));
+  DCHECK(!reg.is(kScratchDoubleReg));
+  if (reg.code() > kDoubleRegZero.code()) {
+    return reg.code() - kNumReservedRegisters;
+  }
+  return reg.code();
+}
+
+
+DwVfpRegister DwVfpRegister::FromAllocationIndex(int index) {
+  DCHECK(index >= 0 && index < NumAllocatableRegisters());
+  DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
+         kNumReservedRegisters - 1);
+  if (index >= kDoubleRegZero.code()) {
+    return from_code(index + kNumReservedRegisters);
+  }
+  return from_code(index);
+}
+
+
 void RelocInfo::apply(intptr_t delta) {
   if (RelocInfo::IsInternalReference(rmode_)) {
     // absolute code pointer inside code object moves with the code object.
index 32d36a27f2e6764245de1c273556997d9159feaf..b5910d05be5de63c9092aedecdec05ec9e487239 100644 (file)
@@ -213,6 +213,18 @@ void CpuFeatures::PrintFeatures() {
 }
 
 
+// -----------------------------------------------------------------------------
+// Implementation of DwVfpRegister
+
+const char* DwVfpRegister::AllocationIndexToString(int index) {
+  DCHECK(index >= 0 && index < NumAllocatableRegisters());
+  DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
+         kNumReservedRegisters - 1);
+  if (index >= kDoubleRegZero.code()) index += kNumReservedRegisters;
+  return VFPRegisters::Name(index, true);
+}
+
+
 // -----------------------------------------------------------------------------
 // Implementation of RelocInfo
 
@@ -379,26 +391,26 @@ NeonListOperand::NeonListOperand(DoubleRegister base, int registers_count) {
 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
 // register r is not encoded.
 const Instr kPushRegPattern =
-    al | B26 | 4 | NegPreIndex | Register::kCode_sp * B16;
+    al | B26 | 4 | NegPreIndex | kRegister_sp_Code * B16;
 // ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r))
 // register r is not encoded.
 const Instr kPopRegPattern =
-    al | B26 | L | 4 | PostIndex | Register::kCode_sp * B16;
+    al | B26 | L | 4 | PostIndex | kRegister_sp_Code * B16;
 // ldr rd, [pc, #offset]
 const Instr kLdrPCImmedMask = 15 * B24 | 7 * B20 | 15 * B16;
-const Instr kLdrPCImmedPattern = 5 * B24 | L | Register::kCode_pc * B16;
+const Instr kLdrPCImmedPattern = 5 * B24 | L | kRegister_pc_Code * B16;
 // ldr rd, [pp, #offset]
 const Instr kLdrPpImmedMask = 15 * B24 | 7 * B20 | 15 * B16;
-const Instr kLdrPpImmedPattern = 5 * B24 | L | Register::kCode_r8 * B16;
+const Instr kLdrPpImmedPattern = 5 * B24 | L | kRegister_r8_Code * B16;
 // ldr rd, [pp, rn]
 const Instr kLdrPpRegMask = 15 * B24 | 7 * B20 | 15 * B16;
-const Instr kLdrPpRegPattern = 7 * B24 | L | Register::kCode_r8 * B16;
+const Instr kLdrPpRegPattern = 7 * B24 | L | kRegister_r8_Code * B16;
 // vldr dd, [pc, #offset]
 const Instr kVldrDPCMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8;
-const Instr kVldrDPCPattern = 13 * B24 | L | Register::kCode_pc * B16 | 11 * B8;
+const Instr kVldrDPCPattern = 13 * B24 | L | kRegister_pc_Code * B16 | 11 * B8;
 // vldr dd, [pp, #offset]
 const Instr kVldrDPpMask = 15 * B24 | 3 * B20 | 15 * B16 | 15 * B8;
-const Instr kVldrDPpPattern = 13 * B24 | L | Register::kCode_r8 * B16 | 11 * B8;
+const Instr kVldrDPpPattern = 13 * B24 | L | kRegister_r8_Code * B16 | 11 * B8;
 // blxcc rm
 const Instr kBlxRegMask =
     15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4;
@@ -425,13 +437,13 @@ const Instr kAndBicFlip = 0xe * B21;
 
 // A mask for the Rd register for push, pop, ldr, str instructions.
 const Instr kLdrRegFpOffsetPattern =
-    al | B26 | L | Offset | Register::kCode_fp * B16;
+    al | B26 | L | Offset | kRegister_fp_Code * B16;
 const Instr kStrRegFpOffsetPattern =
-    al | B26 | Offset | Register::kCode_fp * B16;
+    al | B26 | Offset | kRegister_fp_Code * B16;
 const Instr kLdrRegFpNegOffsetPattern =
-    al | B26 | L | NegOffset | Register::kCode_fp * B16;
+    al | B26 | L | NegOffset | kRegister_fp_Code * B16;
 const Instr kStrRegFpNegOffsetPattern =
-    al | B26 | NegOffset | Register::kCode_fp * B16;
+    al | B26 | NegOffset | kRegister_fp_Code * B16;
 const Instr kLdrStrInstrTypeMask = 0xffff0000;
 
 
@@ -607,21 +619,21 @@ Instr Assembler::SetAddRegisterImmediateOffset(Instr instr, int offset) {
 
 Register Assembler::GetRd(Instr instr) {
   Register reg;
-  reg.reg_code = Instruction::RdValue(instr);
+  reg.code_ = Instruction::RdValue(instr);
   return reg;
 }
 
 
 Register Assembler::GetRn(Instr instr) {
   Register reg;
-  reg.reg_code = Instruction::RnValue(instr);
+  reg.code_ = Instruction::RnValue(instr);
   return reg;
 }
 
 
 Register Assembler::GetRm(Instr instr) {
   Register reg;
-  reg.reg_code = Instruction::RmValue(instr);
+  reg.code_ = Instruction::RmValue(instr);
   return reg;
 }
 
index aa13a828461d5fbc05994eacc4c61003a95c723e..c54e51df78cb57c146f1f9f815214ca899057e49 100644 (file)
 namespace v8 {
 namespace internal {
 
-// clang-format off
-#define GENERAL_REGISTERS(V)                              \
-  V(r0)  V(r1)  V(r2)  V(r3)  V(r4)  V(r5)  V(r6)  V(r7)  \
-  V(r8)  V(r9)  V(r10) V(fp)  V(ip)  V(sp)  V(lr)  V(pc)
-
-#define ALLOCATABLE_GENERAL_REGISTERS(V) \
-  V(r0)  V(r1)  V(r2)  V(r3)  V(r4)  V(r5)  V(r6)  V(r7)  V(r8)
-
-#define DOUBLE_REGISTERS(V)                               \
-  V(d0)  V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)  \
-  V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d13) V(d14) V(d15) \
-  V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
-  V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
-
-#define ALLOCATABLE_DOUBLE_REGISTERS(V)                   \
-  V(d0)  V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)  \
-  V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d13)               \
-  V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
-  V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
-
-#define ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(V)          \
-  V(d0)  V(d1)  V(d2)  V(d3)  V(d4)  V(d5)  V(d6)  V(d7)  \
-  V(d8)  V(d9)  V(d10) V(d11) V(d12) V(d13)               \
-// clang-format on
-
 // CPU Registers.
 //
 // 1) We would prefer to use an enum, but enum values are assignment-
@@ -96,123 +71,190 @@ namespace internal {
 // mode. This way we get the compile-time error checking in debug mode
 // and best performance in optimized code.
 
+// These constants are used in several locations, including static initializers
+const int kRegister_no_reg_Code = -1;
+const int kRegister_r0_Code = 0;
+const int kRegister_r1_Code = 1;
+const int kRegister_r2_Code = 2;
+const int kRegister_r3_Code = 3;
+const int kRegister_r4_Code = 4;
+const int kRegister_r5_Code = 5;
+const int kRegister_r6_Code = 6;
+const int kRegister_r7_Code = 7;
+const int kRegister_r8_Code = 8;
+const int kRegister_r9_Code = 9;
+const int kRegister_r10_Code = 10;
+const int kRegister_fp_Code = 11;
+const int kRegister_ip_Code = 12;
+const int kRegister_sp_Code = 13;
+const int kRegister_lr_Code = 14;
+const int kRegister_pc_Code = 15;
+
+// Core register
 struct Register {
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    GENERAL_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
+  static const int kNumRegisters = 16;
+  static const int kMaxNumAllocatableRegisters =
+      FLAG_enable_embedded_constant_pool ? 8 : 9;
+  static const int kSizeInBytes = 4;
+
+  inline static int NumAllocatableRegisters();
 
-  static const int kNumRegisters = Code::kAfterLast;
+  static int ToAllocationIndex(Register reg) {
+    DCHECK(reg.code() < kMaxNumAllocatableRegisters);
+    return reg.code();
+  }
+
+  static Register FromAllocationIndex(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    return from_code(index);
+  }
+
+  static const char* AllocationIndexToString(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    const char* const names[] = {
+      "r0",
+      "r1",
+      "r2",
+      "r3",
+      "r4",
+      "r5",
+      "r6",
+      "r7",
+      "r8",
+    };
+    if (FLAG_enable_embedded_constant_pool && (index >= 7)) {
+      return names[index + 1];
+    }
+    return names[index];
+  }
 
   static Register from_code(int code) {
-    DCHECK(code >= 0);
-    DCHECK(code < kNumRegisters);
-    Register r = {code};
+    Register r = { code };
     return r;
   }
-  const char* ToString();
-  bool IsAllocatable() const;
-  bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
-  bool is(Register reg) const { return reg_code == reg.reg_code; }
+
+  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
+  bool is(Register reg) const { return code_ == reg.code_; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
     DCHECK(is_valid());
-    return 1 << reg_code;
+    return 1 << code_;
   }
+
   void set_code(int code) {
-    reg_code = code;
+    code_ = code;
     DCHECK(is_valid());
   }
 
   // Unfortunately we can't make this private in a struct.
-  int reg_code;
+  int code_;
 };
 
-// r7: context register
-// r8: constant pool pointer register if FLAG_enable_embedded_constant_pool.
-// r9: lithium scratch
-#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
-GENERAL_REGISTERS(DECLARE_REGISTER)
-#undef DECLARE_REGISTER
-const Register no_reg = {Register::kCode_no_reg};
+const Register no_reg = { kRegister_no_reg_Code };
+
+const Register r0  = { kRegister_r0_Code };
+const Register r1  = { kRegister_r1_Code };
+const Register r2  = { kRegister_r2_Code };
+const Register r3  = { kRegister_r3_Code };
+const Register r4  = { kRegister_r4_Code };
+const Register r5  = { kRegister_r5_Code };
+const Register r6  = { kRegister_r6_Code };
+// Used as context register.
+const Register r7 = {kRegister_r7_Code};
+// Used as constant pool pointer register if FLAG_enable_embedded_constant_pool.
+const Register r8  = { kRegister_r8_Code };
+// Used as lithium codegen scratch register.
+const Register r9  = { kRegister_r9_Code };
+// Used as roots register.
+const Register r10 = { kRegister_r10_Code };
+const Register fp  = { kRegister_fp_Code };
+const Register ip  = { kRegister_ip_Code };
+const Register sp  = { kRegister_sp_Code };
+const Register lr  = { kRegister_lr_Code };
+const Register pc  = { kRegister_pc_Code };
 
 // Single word VFP register.
 struct SwVfpRegister {
   static const int kSizeInBytes = 4;
-  bool is_valid() const { return 0 <= reg_code && reg_code < 32; }
-  bool is(SwVfpRegister reg) const { return reg_code == reg.reg_code; }
+  bool is_valid() const { return 0 <= code_ && code_ < 32; }
+  bool is(SwVfpRegister reg) const { return code_ == reg.code_; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
     DCHECK(is_valid());
-    return 1 << reg_code;
+    return 1 << code_;
   }
   void split_code(int* vm, int* m) const {
     DCHECK(is_valid());
-    *m = reg_code & 0x1;
-    *vm = reg_code >> 1;
+    *m = code_ & 0x1;
+    *vm = code_ >> 1;
   }
 
-  int reg_code;
+  int code_;
 };
 
 
 // Double word VFP register.
-struct DoubleRegister {
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    DOUBLE_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
-
-  static const int kMaxNumRegisters = Code::kAfterLast;
-
-  inline static int NumRegisters();
-
+struct DwVfpRegister {
+  static const int kMaxNumRegisters = 32;
   // A few double registers are reserved: one as a scratch register and one to
   // hold 0.0, that does not fit in the immediate field of vmov instructions.
   //  d14: 0.0
   //  d15: scratch register.
+  static const int kNumReservedRegisters = 2;
+  static const int kMaxNumAllocatableRegisters = kMaxNumRegisters -
+      kNumReservedRegisters;
   static const int kSizeInBytes = 8;
 
-  const char* ToString();
-  bool IsAllocatable() const;
-  bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
-  bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
+  // Note: the number of registers can be different at snapshot and run-time.
+  // Any code included in the snapshot must be able to run both with 16 or 32
+  // registers.
+  inline static int NumRegisters();
+  inline static int NumReservedRegisters();
+  inline static int NumAllocatableRegisters();
+
+  // TODO(turbofan): This is a temporary work-around required because our
+  // register allocator does not yet support the aliasing of single/double
+  // registers on ARM.
+  inline static int NumAllocatableAliasedRegisters();
+
+  inline static int ToAllocationIndex(DwVfpRegister reg);
+  static const char* AllocationIndexToString(int index);
+  inline static DwVfpRegister FromAllocationIndex(int index);
+
+  static DwVfpRegister from_code(int code) {
+    DwVfpRegister r = { code };
+    return r;
+  }
+
+  bool is_valid() const {
+    return 0 <= code_ && code_ < kMaxNumRegisters;
+  }
+  bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
     DCHECK(is_valid());
-    return 1 << reg_code;
-  }
-
-  static DoubleRegister from_code(int code) {
-    DoubleRegister r = {code};
-    return r;
+    return 1 << code_;
   }
   void split_code(int* vm, int* m) const {
     DCHECK(is_valid());
-    *m = (reg_code & 0x10) >> 4;
-    *vm = reg_code & 0x0F;
+    *m = (code_ & 0x10) >> 4;
+    *vm = code_ & 0x0F;
   }
 
-  int reg_code;
+  int code_;
 };
 
 
-typedef DoubleRegister DwVfpRegister;
+typedef DwVfpRegister DoubleRegister;
 
 
 // Double word VFP register d0-15.
@@ -220,7 +262,7 @@ struct LowDwVfpRegister {
  public:
   static const int kMaxNumLowRegisters = 16;
   operator DwVfpRegister() const {
-    DwVfpRegister r = { reg_code };
+    DwVfpRegister r = { code_ };
     return r;
   }
   static LowDwVfpRegister from_code(int code) {
@@ -229,30 +271,30 @@ struct LowDwVfpRegister {
   }
 
   bool is_valid() const {
-    return 0 <= reg_code && reg_code < kMaxNumLowRegisters;
+    return 0 <= code_ && code_ < kMaxNumLowRegisters;
   }
-  bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; }
-  bool is(LowDwVfpRegister reg) const { return reg_code == reg.reg_code; }
+  bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
+  bool is(LowDwVfpRegister reg) const { return code_ == reg.code_; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   SwVfpRegister low() const {
     SwVfpRegister reg;
-    reg.reg_code = reg_code * 2;
+    reg.code_ = code_ * 2;
 
     DCHECK(reg.is_valid());
     return reg;
   }
   SwVfpRegister high() const {
     SwVfpRegister reg;
-    reg.reg_code = (reg_code * 2) + 1;
+    reg.code_ = (code_ * 2) + 1;
 
     DCHECK(reg.is_valid());
     return reg;
   }
 
-  int reg_code;
+  int code_;
 };
 
 
@@ -266,21 +308,21 @@ struct QwNeonRegister {
   }
 
   bool is_valid() const {
-    return (0 <= reg_code) && (reg_code < kMaxNumRegisters);
+    return (0 <= code_) && (code_ < kMaxNumRegisters);
   }
-  bool is(QwNeonRegister reg) const { return reg_code == reg.reg_code; }
+  bool is(QwNeonRegister reg) const { return code_ == reg.code_; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   void split_code(int* vm, int* m) const {
     DCHECK(is_valid());
-    int encoded_code = reg_code << 1;
+    int encoded_code = code_ << 1;
     *m = (encoded_code & 0x10) >> 4;
     *vm = encoded_code & 0x0F;
   }
 
-  int reg_code;
+  int code_;
 };
 
 
@@ -385,19 +427,19 @@ const QwNeonRegister q15 = { 15 };
 
 // Coprocessor register
 struct CRegister {
-  bool is_valid() const { return 0 <= reg_code && reg_code < 16; }
-  bool is(CRegister creg) const { return reg_code == creg.reg_code; }
+  bool is_valid() const { return 0 <= code_ && code_ < 16; }
+  bool is(CRegister creg) const { return code_ == creg.code_; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
     DCHECK(is_valid());
-    return 1 << reg_code;
+    return 1 << code_;
   }
 
   // Unfortunately we can't make this private in a struct.
-  int reg_code;
+  int code_;
 };
 
 
index 915d9030e8922a6f8c4e433a1936b692540d5090..9fefc3140a999429d0a1853bf75ae08ce59224ca 100644 (file)
@@ -51,6 +51,17 @@ const Registers::RegisterAlias Registers::aliases_[] = {
 };
 
 
+const char* Registers::Name(int reg) {
+  const char* result;
+  if ((0 <= reg) && (reg < kNumRegisters)) {
+    result = names_[reg];
+  } else {
+    result = "noreg";
+  }
+  return result;
+}
+
+
 // Support for VFP registers s0 to s31 (d0 to d15) and d16-d31.
 // Note that "sN:sM" is the same as "dN/2" up to d15.
 // These register names are defined in a way to match the native disassembler
index 91faa28bc7dfdf07f12a40897aaf2e3092aa7622..312bb00df3243ba54788b65927c66554cf6c8abc 100644 (file)
@@ -5,7 +5,6 @@
 #include "src/codegen.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
-#include "src/register-configuration.h"
 #include "src/safepoint-table.h"
 
 namespace v8 {
@@ -94,7 +93,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
   }
   input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
   input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
-  for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
+  for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
     input_->SetDoubleRegister(i, 0.0);
   }
 
@@ -143,7 +142,8 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   // Everything but pc, lr and ip which will be saved but not restored.
   RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit();
 
-  const int kDoubleRegsSize = kDoubleSize * DwVfpRegister::kMaxNumRegisters;
+  const int kDoubleRegsSize =
+      kDoubleSize * DwVfpRegister::kMaxNumAllocatableRegisters;
 
   // Save all allocatable VFP registers before messing with them.
   DCHECK(kDoubleRegZero.code() == 14);
@@ -152,11 +152,11 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   // Check CPU flags for number of registers, setting the Z condition flag.
   __ CheckFor32DRegs(ip);
 
-  // Push registers d0-d15, and possibly d16-d31, on the stack.
+  // Push registers d0-d13, and possibly d16-d31, on the stack.
   // If d16-d31 are not pushed, decrease the stack pointer instead.
   __ vstm(db_w, sp, d16, d31, ne);
   __ sub(sp, sp, Operand(16 * kDoubleSize), LeaveCC, eq);
-  __ vstm(db_w, sp, d0, d15);
+  __ vstm(db_w, sp, d0, d13);
 
   // Push all 16 registers (needed to populate FrameDescription::registers_).
   // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps
@@ -211,11 +211,9 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   // Copy VFP registers to
   // double_registers_[DoubleRegister::kMaxNumAllocatableRegisters]
   int double_regs_offset = FrameDescription::double_registers_offset();
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    int dst_offset = code * kDoubleSize + double_regs_offset;
-    int src_offset = code * kDoubleSize + kNumberOfRegisters * kPointerSize;
+  for (int i = 0; i < DwVfpRegister::kMaxNumAllocatableRegisters; ++i) {
+    int dst_offset = i * kDoubleSize + double_regs_offset;
+    int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
     __ vldr(d0, sp, src_offset);
     __ vstr(d0, r1, dst_offset);
   }
index 9d86579f288ccb313881b83c5cebfb9b4beda316..0cc24e00af0b8e87c15568edb7a6a0d8d16eee7f 100644 (file)
@@ -1923,7 +1923,7 @@ const char* NameConverter::NameOfConstant(byte* addr) const {
 
 
 const char* NameConverter::NameOfCPURegister(int reg) const {
-  return v8::internal::Register::from_code(reg).ToString();
+  return v8::internal::Registers::Name(reg);
 }
 
 
index 87cbf0996c59ff640356a410bf01b53bd686d255..4ccb02099569aee044ec33830c78530edf620b48 100644 (file)
@@ -444,13 +444,14 @@ LPlatformChunk* LChunkBuilder::Build() {
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
-  return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
+                                  Register::ToAllocationIndex(reg));
 }
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(DoubleRegister reg) {
-  return new (zone())
-      LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
+                                  DoubleRegister::ToAllocationIndex(reg));
 }
 
 
index 80153ae7fc2e2ba507bf06b740174a41b0029e99..b163061458ec1376cfd4623c957df2138a0df90c 100644 (file)
@@ -72,7 +72,7 @@ void LCodeGen::SaveCallerDoubles() {
   BitVector* doubles = chunk()->allocated_double_registers();
   BitVector::Iterator save_iterator(doubles);
   while (!save_iterator.Done()) {
-    __ vstr(DoubleRegister::from_code(save_iterator.Current()),
+    __ vstr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()),
             MemOperand(sp, count * kDoubleSize));
     save_iterator.Advance();
     count++;
@@ -88,8 +88,8 @@ void LCodeGen::RestoreCallerDoubles() {
   BitVector::Iterator save_iterator(doubles);
   int count = 0;
   while (!save_iterator.Done()) {
-    __ vldr(DoubleRegister::from_code(save_iterator.Current()),
-            MemOperand(sp, count * kDoubleSize));
+    __ vldr(DwVfpRegister::FromAllocationIndex(save_iterator.Current()),
+             MemOperand(sp, count * kDoubleSize));
     save_iterator.Advance();
     count++;
   }
@@ -405,13 +405,13 @@ bool LCodeGen::GenerateSafepointTable() {
 }
 
 
-Register LCodeGen::ToRegister(int code) const {
-  return Register::from_code(code);
+Register LCodeGen::ToRegister(int index) const {
+  return Register::FromAllocationIndex(index);
 }
 
 
-DwVfpRegister LCodeGen::ToDoubleRegister(int code) const {
-  return DwVfpRegister::from_code(code);
+DwVfpRegister LCodeGen::ToDoubleRegister(int index) const {
+  return DwVfpRegister::FromAllocationIndex(index);
 }
 
 
index 1e2df8046272b66da3a22b1d4743977e6fc8b741..da467ccc835eacbbcffbbd6a47e40fe63c5a65db 100644 (file)
@@ -12,7 +12,6 @@
 #include "src/codegen.h"
 #include "src/cpu-profiler.h"
 #include "src/debug/debug.h"
-#include "src/register-configuration.h"
 #include "src/runtime/runtime.h"
 
 #include "src/arm/macro-assembler-arm.h"
@@ -761,8 +760,7 @@ MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) {
   // Number of d-regs not known at snapshot time.
   DCHECK(!serializer_enabled());
   // General purpose registers are pushed last on the stack.
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  int doubles_size = config->num_allocatable_double_registers() * kDoubleSize;
+  int doubles_size = DwVfpRegister::NumAllocatableRegisters() * kDoubleSize;
   int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
   return MemOperand(sp, doubles_size + register_offset);
 }
@@ -3573,10 +3571,8 @@ Register GetRegisterThatIsNotOneOf(Register reg1,
   if (reg5.is_valid()) regs |= reg5.bit();
   if (reg6.is_valid()) regs |= reg6.bit();
 
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_general_registers(); ++i) {
-    int code = config->GetAllocatableGeneralCode(i);
-    Register candidate = Register::from_code(code);
+  for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
+    Register candidate = Register::FromAllocationIndex(i);
     if (regs & candidate.bit()) continue;
     return candidate;
   }
index 5c596f2e3f4a70793120ac9eb747d6406b7037ee..8bb573f65eee82acef9610c3dd6c08fda373f867 100644 (file)
@@ -14,17 +14,17 @@ namespace v8 {
 namespace internal {
 
 // Give alias names to registers for calling conventions.
-const Register kReturnRegister0 = {Register::kCode_r0};
-const Register kReturnRegister1 = {Register::kCode_r1};
-const Register kJSFunctionRegister = {Register::kCode_r1};
-const Register kContextRegister = {Register::kCode_r7};
-const Register kInterpreterAccumulatorRegister = {Register::kCode_r0};
-const Register kInterpreterRegisterFileRegister = {Register::kCode_r4};
-const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_r5};
-const Register kInterpreterBytecodeArrayRegister = {Register::kCode_r6};
-const Register kInterpreterDispatchTableRegister = {Register::kCode_r8};
-const Register kRuntimeCallFunctionRegister = {Register::kCode_r1};
-const Register kRuntimeCallArgCountRegister = {Register::kCode_r0};
+const Register kReturnRegister0 = {kRegister_r0_Code};
+const Register kReturnRegister1 = {kRegister_r1_Code};
+const Register kJSFunctionRegister = {kRegister_r1_Code};
+const Register kContextRegister = {kRegister_r7_Code};
+const Register kInterpreterAccumulatorRegister = {kRegister_r0_Code};
+const Register kInterpreterRegisterFileRegister = {kRegister_r4_Code};
+const Register kInterpreterBytecodeOffsetRegister = {kRegister_r5_Code};
+const Register kInterpreterBytecodeArrayRegister = {kRegister_r6_Code};
+const Register kInterpreterDispatchTableRegister = {kRegister_r8_Code};
+const Register kRuntimeCallFunctionRegister = {kRegister_r1_Code};
+const Register kRuntimeCallArgCountRegister = {kRegister_r0_Code};
 
 // ----------------------------------------------------------------------------
 // Static helper functions
@@ -36,9 +36,9 @@ inline MemOperand FieldMemOperand(Register object, int offset) {
 
 
 // Give alias names to registers
-const Register cp = {Register::kCode_r7};  // JavaScript context pointer.
-const Register pp = {Register::kCode_r8};  // Constant pool pointer.
-const Register kRootRegister = {Register::kCode_r10};  // Roots array pointer.
+const Register cp = { kRegister_r7_Code };  // JavaScript context pointer.
+const Register pp = { kRegister_r8_Code };  // Constant pool pointer.
+const Register kRootRegister = { kRegister_r10_Code };  // Roots array pointer.
 
 // Flags used for AllocateHeapNumber
 enum TaggingMode {
index 716e804e3a37986d72eab2ea1a98695d8c306817..5da6204050b926f056d06b8dd576a3ff9514eec3 100644 (file)
@@ -298,8 +298,7 @@ void ArmDebugger::Debug() {
           if (strcmp(arg1, "all") == 0) {
             for (int i = 0; i < kNumRegisters; i++) {
               value = GetRegisterValue(i);
-              PrintF("%3s: 0x%08x %10d", Register::from_code(i).ToString(),
-                     value, value);
+              PrintF("%3s: 0x%08x %10d", Registers::Name(i), value, value);
               if ((argc == 3 && strcmp(arg2, "fp") == 0) &&
                   i < 8 &&
                   (i % 2) == 0) {
index 0a1ecda9aa9b7c7883ef4eced453dd3035bd18f8..37a2f5a29d006f1c753b2a0bb07a1183c1276893 100644 (file)
@@ -35,7 +35,6 @@
 #include "src/arm64/frames-arm64.h"
 #include "src/base/bits.h"
 #include "src/base/cpu.h"
-#include "src/register-configuration.h"
 
 namespace v8 {
 namespace internal {
@@ -193,10 +192,8 @@ bool RelocInfo::IsInConstantPool() {
 Register GetAllocatableRegisterThatIsNotOneOf(Register reg1, Register reg2,
                                               Register reg3, Register reg4) {
   CPURegList regs(reg1, reg2, reg3, reg4);
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    Register candidate = Register::from_code(code);
+  for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
+    Register candidate = Register::FromAllocationIndex(i);
     if (regs.IncludesAliasOf(candidate)) continue;
     return candidate;
   }
index 95aabd0c8da480b354d0a742fb4772dd03bd8a60..f20be8315e2f0bfb4c12ca1ab1175253feae85b4 100644 (file)
@@ -23,36 +23,12 @@ namespace internal {
 
 // -----------------------------------------------------------------------------
 // Registers.
-// clang-format off
-#define GENERAL_REGISTER_CODE_LIST(R)                     \
-  R(0)  R(1)  R(2)  R(3)  R(4)  R(5)  R(6)  R(7)          \
-  R(8)  R(9)  R(10) R(11) R(12) R(13) R(14) R(15)         \
-  R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23)         \
-  R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
-
-#define GENERAL_REGISTERS(R)                              \
-  R(x0)  R(x1)  R(x2)  R(x3)  R(x4)  R(x5)  R(x6)  R(x7)  \
-  R(x8)  R(x9)  R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \
-  R(x16) R(x17) R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) \
-  R(x24) R(x25) R(x26) R(x27) R(x28) R(x29) R(x30) R(x31)
-
-#define ALLOCATABLE_GENERAL_REGISTERS(R)                  \
-  R(x0)  R(x1)  R(x2)  R(x3)  R(x4)  R(x5)  R(x6)  R(x7)  \
-  R(x8)  R(x9)  R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \
-  R(x18) R(x19) R(x20) R(x21) R(x22) R(x23) R(x24) R(x27)
-
-#define DOUBLE_REGISTERS(R)                               \
-  R(d0)  R(d1)  R(d2)  R(d3)  R(d4)  R(d5)  R(d6)  R(d7)  \
-  R(d8)  R(d9)  R(d10) R(d11) R(d12) R(d13) R(d14) R(d15) \
-  R(d16) R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) \
-  R(d24) R(d25) R(d26) R(d27) R(d28) R(d29) R(d30) R(d31)
-
-#define ALLOCATABLE_DOUBLE_REGISTERS(R)                   \
-  R(d0)  R(d1)  R(d2)  R(d3)  R(d4)  R(d5)  R(d6)  R(d7)  \
-  R(d8)  R(d9)  R(d10) R(d11) R(d12) R(d13) R(d14) R(d16) \
-  R(d17) R(d18) R(d19) R(d20) R(d21) R(d22) R(d23) R(d24) \
-  R(d25) R(d26) R(d27) R(d28)
-// clang-format on
+#define REGISTER_CODE_LIST(R)                                                  \
+R(0)  R(1)  R(2)  R(3)  R(4)  R(5)  R(6)  R(7)                                 \
+R(8)  R(9)  R(10) R(11) R(12) R(13) R(14) R(15)                                \
+R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23)                                \
+R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
+
 
 static const int kRegListSizeInBits = sizeof(RegList) * kBitsPerByte;
 
@@ -64,14 +40,6 @@ struct FPRegister;
 
 
 struct CPURegister {
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    GENERAL_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
-
   enum RegisterType {
     // The kInvalid value is used to detect uninitialized static instances,
     // which are always zero-initialized before any constructors are called.
@@ -149,8 +117,6 @@ struct Register : public CPURegister {
     DCHECK(IsValidOrNone());
   }
 
-  const char* ToString();
-  bool IsAllocatable() const;
   bool IsValid() const {
     DCHECK(IsRegister() || IsNone());
     return IsValidRegister();
@@ -164,7 +130,6 @@ struct Register : public CPURegister {
   // A few of them may be unused for now.
 
   static const int kNumRegisters = kNumberOfRegisters;
-  STATIC_ASSERT(kNumRegisters == Code::kAfterLast);
   static int NumRegisters() { return kNumRegisters; }
 
   // We allow crankshaft to use the following registers:
@@ -181,6 +146,70 @@ struct Register : public CPURegister {
   //   - "low range"
   //   - "high range"
   //   - "context"
+  static const unsigned kAllocatableLowRangeBegin = 0;
+  static const unsigned kAllocatableLowRangeEnd = 15;
+  static const unsigned kAllocatableHighRangeBegin = 18;
+  static const unsigned kAllocatableHighRangeEnd = 24;
+  static const unsigned kAllocatableContext = 27;
+
+  // Gap between low and high ranges.
+  static const int kAllocatableRangeGapSize =
+      (kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1;
+
+  static const int kMaxNumAllocatableRegisters =
+      (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) +
+      (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1) + 1;  // cp
+  static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
+
+  // Return true if the register is one that crankshaft can allocate.
+  bool IsAllocatable() const {
+    return ((reg_code == kAllocatableContext) ||
+            (reg_code <= kAllocatableLowRangeEnd) ||
+            ((reg_code >= kAllocatableHighRangeBegin) &&
+             (reg_code <= kAllocatableHighRangeEnd)));
+  }
+
+  static Register FromAllocationIndex(unsigned index) {
+    DCHECK(index < static_cast<unsigned>(NumAllocatableRegisters()));
+    // cp is the last allocatable register.
+    if (index == (static_cast<unsigned>(NumAllocatableRegisters() - 1))) {
+      return from_code(kAllocatableContext);
+    }
+
+    // Handle low and high ranges.
+    return (index <= kAllocatableLowRangeEnd)
+        ? from_code(index)
+        : from_code(index + kAllocatableRangeGapSize);
+  }
+
+  static const char* AllocationIndexToString(int index) {
+    DCHECK((index >= 0) && (index < NumAllocatableRegisters()));
+    DCHECK((kAllocatableLowRangeBegin == 0) &&
+           (kAllocatableLowRangeEnd == 15) &&
+           (kAllocatableHighRangeBegin == 18) &&
+           (kAllocatableHighRangeEnd == 24) &&
+           (kAllocatableContext == 27));
+    const char* const names[] = {
+      "x0", "x1", "x2", "x3", "x4",
+      "x5", "x6", "x7", "x8", "x9",
+      "x10", "x11", "x12", "x13", "x14",
+      "x15", "x18", "x19", "x20", "x21",
+      "x22", "x23", "x24", "x27",
+    };
+    return names[index];
+  }
+
+  static int ToAllocationIndex(Register reg) {
+    DCHECK(reg.IsAllocatable());
+    unsigned code = reg.code();
+    if (code == kAllocatableContext) {
+      return NumAllocatableRegisters() - 1;
+    }
+
+    return (code <= kAllocatableLowRangeEnd)
+        ? code
+        : code - kAllocatableRangeGapSize;
+  }
 
   static Register from_code(int code) {
     // Always return an X register.
@@ -192,14 +221,6 @@ struct Register : public CPURegister {
 
 
 struct FPRegister : public CPURegister {
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    DOUBLE_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
-
   static FPRegister Create(unsigned code, unsigned size) {
     return FPRegister(
         CPURegister::Create(code, size, CPURegister::kFPRegister));
@@ -225,8 +246,6 @@ struct FPRegister : public CPURegister {
     DCHECK(IsValidOrNone());
   }
 
-  const char* ToString();
-  bool IsAllocatable() const;
   bool IsValid() const {
     DCHECK(IsFPRegister() || IsNone());
     return IsValidFPRegister();
@@ -237,12 +256,69 @@ struct FPRegister : public CPURegister {
 
   // Start of V8 compatibility section ---------------------
   static const int kMaxNumRegisters = kNumberOfFPRegisters;
-  STATIC_ASSERT(kMaxNumRegisters == Code::kAfterLast);
 
   // Crankshaft can use all the FP registers except:
   //   - d15 which is used to keep the 0 double value
   //   - d30 which is used in crankshaft as a double scratch register
   //   - d31 which is used in the MacroAssembler as a double scratch register
+  static const unsigned kAllocatableLowRangeBegin = 0;
+  static const unsigned kAllocatableLowRangeEnd = 14;
+  static const unsigned kAllocatableHighRangeBegin = 16;
+  static const unsigned kAllocatableHighRangeEnd = 28;
+
+  static const RegList kAllocatableFPRegisters = 0x1fff7fff;
+
+  // Gap between low and high ranges.
+  static const int kAllocatableRangeGapSize =
+      (kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1;
+
+  static const int kMaxNumAllocatableRegisters =
+      (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) +
+      (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1);
+  static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
+
+  // TODO(turbofan): Proper float32 support.
+  static int NumAllocatableAliasedRegisters() {
+    return NumAllocatableRegisters();
+  }
+
+  // Return true if the register is one that crankshaft can allocate.
+  bool IsAllocatable() const {
+    return (Bit() & kAllocatableFPRegisters) != 0;
+  }
+
+  static FPRegister FromAllocationIndex(unsigned int index) {
+    DCHECK(index < static_cast<unsigned>(NumAllocatableRegisters()));
+
+    return (index <= kAllocatableLowRangeEnd)
+        ? from_code(index)
+        : from_code(index + kAllocatableRangeGapSize);
+  }
+
+  static const char* AllocationIndexToString(int index) {
+    DCHECK((index >= 0) && (index < NumAllocatableRegisters()));
+    DCHECK((kAllocatableLowRangeBegin == 0) &&
+           (kAllocatableLowRangeEnd == 14) &&
+           (kAllocatableHighRangeBegin == 16) &&
+           (kAllocatableHighRangeEnd == 28));
+    const char* const names[] = {
+      "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
+      "d8", "d9", "d10", "d11", "d12", "d13", "d14",
+      "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
+      "d24", "d25", "d26", "d27", "d28"
+    };
+    return names[index];
+  }
+
+  static int ToAllocationIndex(FPRegister reg) {
+    DCHECK(reg.IsAllocatable());
+    unsigned code = reg.code();
+
+    return (code <= kAllocatableLowRangeEnd)
+        ? code
+        : code - kAllocatableRangeGapSize;
+  }
+
   static FPRegister from_code(int code) {
     // Always return a D register.
     return FPRegister::Create(code, kDRegSizeInBits);
@@ -285,7 +361,7 @@ INITIALIZE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister);
                       kWRegSizeInBits, CPURegister::kRegister);              \
   INITIALIZE_REGISTER(Register, x##N, N,                                     \
                       kXRegSizeInBits, CPURegister::kRegister);
-GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS)
+REGISTER_CODE_LIST(DEFINE_REGISTERS)
 #undef DEFINE_REGISTERS
 
 INITIALIZE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSizeInBits,
@@ -298,7 +374,7 @@ INITIALIZE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSizeInBits,
                       kSRegSizeInBits, CPURegister::kFPRegister);              \
   INITIALIZE_REGISTER(FPRegister, d##N, N,                                     \
                       kDRegSizeInBits, CPURegister::kFPRegister);
-GENERAL_REGISTER_CODE_LIST(DEFINE_FPREGISTERS)
+REGISTER_CODE_LIST(DEFINE_FPREGISTERS)
 #undef DEFINE_FPREGISTERS
 
 #undef INITIALIZE_REGISTER
index b419a6e85668e6fc503c96cf5c4491607ab9c7e0..1529c647ff75c8ce6a81b5b94a82c9161b402da1 100644 (file)
@@ -118,6 +118,12 @@ const unsigned kDoubleExponentBias = 1023;
 const unsigned kFloatMantissaBits = 23;
 const unsigned kFloatExponentBits = 8;
 
+#define REGISTER_CODE_LIST(R)                                                  \
+R(0)  R(1)  R(2)  R(3)  R(4)  R(5)  R(6)  R(7)                                 \
+R(8)  R(9)  R(10) R(11) R(12) R(13) R(14) R(15)                                \
+R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23)                                \
+R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
+
 #define INSTRUCTION_FIELDS_LIST(V_)                                            \
 /* Register fields */                                                          \
 V_(Rd, 4, 0, Bits)                        /* Destination register.     */      \
index 60409f6d267e0268e039ef62f9813979227c4081..65fb93e53cfa2e87d555e3a937d6f5ffc8b99761 100644 (file)
@@ -6,7 +6,6 @@
 #include "src/codegen.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
-#include "src/register-configuration.h"
 #include "src/safepoint-table.h"
 
 
@@ -76,7 +75,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
   input_->SetRegister(jssp.code(), reinterpret_cast<intptr_t>(frame->sp()));
   input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
 
-  for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
+  for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
     input_->SetDoubleRegister(i, 0.0);
   }
 
@@ -123,9 +122,8 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   // in the input frame.
 
   // Save all allocatable floating point registers.
-  CPURegList saved_fp_registers(
-      CPURegister::kFPRegister, kDRegSizeInBits,
-      RegisterConfiguration::ArchDefault()->allocatable_double_codes_mask());
+  CPURegList saved_fp_registers(CPURegister::kFPRegister, kDRegSizeInBits,
+                                FPRegister::kAllocatableFPRegisters);
   __ PushCPURegList(saved_fp_registers);
 
   // We save all the registers expcept jssp, sp and lr.
index 5cc5b9d592eedc19a49ed4a2315a42f862d047e0..e623718a1a323b59e9f672d335e08d22533f6ab3 100644 (file)
@@ -375,13 +375,14 @@ const char* LArithmeticT::Mnemonic() const {
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
-  return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
+                                  Register::ToAllocationIndex(reg));
 }
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(DoubleRegister reg) {
-  return new (zone())
-      LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
+                                  DoubleRegister::ToAllocationIndex(reg));
 }
 
 
index 0067abfe240b671b6174fd227b0736cebdbc3fc3..488e14f82c5b7ba974f099fddeb7344c9648583f 100644 (file)
@@ -593,7 +593,7 @@ void LCodeGen::SaveCallerDoubles() {
   while (!iterator.Done()) {
     // TODO(all): Is this supposed to save just the callee-saved doubles? It
     // looks like it's saving all of them.
-    FPRegister value = FPRegister::from_code(iterator.Current());
+    FPRegister value = FPRegister::FromAllocationIndex(iterator.Current());
     __ Poke(value, count * kDoubleSize);
     iterator.Advance();
     count++;
@@ -611,7 +611,7 @@ void LCodeGen::RestoreCallerDoubles() {
   while (!iterator.Done()) {
     // TODO(all): Is this supposed to restore just the callee-saved doubles? It
     // looks like it's restoring all of them.
-    FPRegister value = FPRegister::from_code(iterator.Current());
+    FPRegister value = FPRegister::FromAllocationIndex(iterator.Current());
     __ Peek(value, count * kDoubleSize);
     iterator.Advance();
     count++;
@@ -1158,7 +1158,7 @@ void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
 Register LCodeGen::ToRegister(LOperand* op) const {
   // TODO(all): support zero register results, as ToRegister32.
   DCHECK((op != NULL) && op->IsRegister());
-  return Register::from_code(op->index());
+  return Register::FromAllocationIndex(op->index());
 }
 
 
@@ -1182,7 +1182,7 @@ Smi* LCodeGen::ToSmi(LConstantOperand* op) const {
 
 DoubleRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
   DCHECK((op != NULL) && op->IsDoubleRegister());
-  return DoubleRegister::from_code(op->index());
+  return DoubleRegister::FromAllocationIndex(op->index());
 }
 
 
index 7aed57853bea070cd9a4d8a3be174ec93384ee9d..3c42194e0102fd4ee38a3b1cf46126557243f3d9 100644 (file)
@@ -10,7 +10,6 @@
 #include "src/codegen.h"
 #include "src/cpu-profiler.h"
 #include "src/debug/debug.h"
-#include "src/register-configuration.h"
 #include "src/runtime/runtime.h"
 
 #include "src/arm64/frames-arm64.h"
@@ -3978,16 +3977,14 @@ void MacroAssembler::PushSafepointRegisters() {
 
 void MacroAssembler::PushSafepointRegistersAndDoubles() {
   PushSafepointRegisters();
-  PushCPURegList(CPURegList(
-      CPURegister::kFPRegister, kDRegSizeInBits,
-      RegisterConfiguration::ArchDefault()->allocatable_double_codes_mask()));
+  PushCPURegList(CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
+                            FPRegister::kAllocatableFPRegisters));
 }
 
 
 void MacroAssembler::PopSafepointRegistersAndDoubles() {
-  PopCPURegList(CPURegList(
-      CPURegister::kFPRegister, kDRegSizeInBits,
-      RegisterConfiguration::ArchDefault()->allocatable_double_codes_mask()));
+  PopCPURegList(CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
+                           FPRegister::kAllocatableFPRegisters));
   PopSafepointRegisters();
 }
 
index ae7a91d3ed981880244463731da69cd82a5cad43..e4d9a81ffdbe3d04305726efa911a83a8faaea37 100644 (file)
 #include "src/globals.h"
 #include "src/utils.h"
 
+#define REGISTER_CODE_LIST(R)                                                  \
+R(0)  R(1)  R(2)  R(3)  R(4)  R(5)  R(6)  R(7)                                 \
+R(8)  R(9)  R(10) R(11) R(12) R(13) R(14) R(15)                                \
+R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23)                                \
+R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
+
 namespace v8 {
 namespace internal {
 
index cbc920b9c5f5c9eebb36cb0dcd6371c687128a87..da91fd5d6000aea74b6532b9233c58beebf852d3 100644 (file)
@@ -9,6 +9,12 @@
 
 #include "src/arm64/constants-arm64.h"
 
+#define REGISTER_CODE_LIST(R)                                                  \
+R(0)  R(1)  R(2)  R(3)  R(4)  R(5)  R(6)  R(7)                                 \
+R(8)  R(9)  R(10) R(11) R(12) R(13) R(14) R(15)                                \
+R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23)                                \
+R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
+
 namespace v8 {
 namespace internal {
 
index b312915dfb7aa6e7bd6238d9dc3e5a564b2489c4..c81cdc2b78a39c4dc0f7a5cb5effdc661529ab48 100644 (file)
@@ -53,7 +53,6 @@
 #include "src/regexp/jsregexp.h"
 #include "src/regexp/regexp-macro-assembler.h"
 #include "src/regexp/regexp-stack.h"
-#include "src/register-configuration.h"
 #include "src/runtime/runtime.h"
 #include "src/simulator.h"  // For flushing instruction cache.
 #include "src/snapshot/serialize.h"
 namespace v8 {
 namespace internal {
 
-// -----------------------------------------------------------------------------
-// Common register code.
-
-const char* Register::ToString() {
-  // This is the mapping of allocation indices to registers.
-  DCHECK(reg_code >= 0 && reg_code < kNumRegisters);
-  return RegisterConfiguration::ArchDefault()->GetGeneralRegisterName(reg_code);
-}
-
-
-bool Register::IsAllocatable() const {
-  return ((1 << reg_code) &
-          RegisterConfiguration::ArchDefault()
-              ->allocatable_general_codes_mask()) != 0;
-}
-
-
-const char* DoubleRegister::ToString() {
-  // This is the mapping of allocation indices to registers.
-  DCHECK(reg_code >= 0 && reg_code < kMaxNumRegisters);
-  return RegisterConfiguration::ArchDefault()->GetDoubleRegisterName(reg_code);
-}
-
-
-bool DoubleRegister::IsAllocatable() const {
-  return ((1 << reg_code) &
-          RegisterConfiguration::ArchDefault()
-              ->allocatable_double_codes_mask()) != 0;
-}
-
-
 // -----------------------------------------------------------------------------
 // Common double constants.
 
index 9810e5beb568d09853a7332269b0584f275d56c6..433b9b8456dc869ad6774e166b0bb9f8509c9c03 100644 (file)
@@ -1276,6 +1276,7 @@ class ConstantPoolBuilder BASE_EMBEDDED {
   PerTypeEntryInfo info_[ConstantPoolEntry::NUMBER_OF_TYPES];
 };
 
+
 } }  // namespace v8::internal
 
 #endif  // V8_ASSEMBLER_H_
index 59e8c86d88589e9e6c79b0bb39557596d515087c..76ddd2ed7d1d2cd26e8b3e218170f56d2494891c 100644 (file)
@@ -15,7 +15,7 @@ namespace compiler {
 
 namespace {
 LinkageLocation regloc(Register reg) {
-  return LinkageLocation::ForRegister(reg.code());
+  return LinkageLocation::ForRegister(Register::ToAllocationIndex(reg));
 }
 
 
index 2e95bec0cc17188fbfc8d1997bbba90771d7fc3a..83cbd22604a9fb921f6d58746f1d32128c4a0334 100644 (file)
@@ -96,11 +96,12 @@ class InstructionOperandConverter {
   }
 
   Register ToRegister(InstructionOperand* op) {
-    return RegisterOperand::cast(op)->GetRegister();
+    return Register::FromAllocationIndex(RegisterOperand::cast(op)->index());
   }
 
   DoubleRegister ToDoubleRegister(InstructionOperand* op) {
-    return DoubleRegisterOperand::cast(op)->GetDoubleRegister();
+    return DoubleRegister::FromAllocationIndex(
+        DoubleRegisterOperand::cast(op)->index());
   }
 
   Constant ToConstant(InstructionOperand* op) {
index f702cce1c3c9b801849fa97e1e5d2958c47170a0..91602a02a3cde1de9f76bd20cd6ba8698c24012d 100644 (file)
@@ -227,7 +227,8 @@ void CodeGenerator::RecordSafepoint(ReferenceMap* references,
       index -= stackSlotToSpillSlotDelta;
       safepoint.DefinePointerSlot(index, zone());
     } else if (operand.IsRegister() && (kind & Safepoint::kWithRegisters)) {
-      Register reg = RegisterOperand::cast(operand).GetRegister();
+      Register reg =
+          Register::FromAllocationIndex(RegisterOperand::cast(operand).index());
       safepoint.DefinePointerRegister(reg, zone());
     }
   }
index 47ca259e74dc7f96f9a9faa1ef2df92f960e5e00..07ca04532bcaa3c94c95ea9d3b380d8167569f7c 100644 (file)
@@ -719,13 +719,13 @@ void GraphC1Visualizer::PrintLiveRange(LiveRange* range, const char* type,
     os_ << vreg << ":" << range->relative_id() << " " << type;
     if (range->HasRegisterAssigned()) {
       AllocatedOperand op = AllocatedOperand::cast(range->GetAssignedOperand());
+      int assigned_reg = op.index();
       if (op.IsDoubleRegister()) {
-        DoubleRegister assigned_reg = op.GetDoubleRegister();
-        os_ << " \"" << assigned_reg.ToString() << "\"";
+        os_ << " \"" << DoubleRegister::AllocationIndexToString(assigned_reg)
+            << "\"";
       } else {
         DCHECK(op.IsRegister());
-        Register assigned_reg = op.GetRegister();
-        os_ << " \"" << assigned_reg.ToString() << "\"";
+        os_ << " \"" << Register::AllocationIndexToString(assigned_reg) << "\"";
       }
     } else if (range->spilled()) {
       auto top = range->TopLevel();
index 2ee099f9a8721df845a9640446632a67d0e050f7..88283d489877caeef91ed8e431c82e19a007d9fa 100644 (file)
@@ -51,13 +51,15 @@ class OperandGenerator {
 
   InstructionOperand DefineAsFixed(Node* node, Register reg) {
     return Define(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
-                                           reg.code(), GetVReg(node)));
+                                           Register::ToAllocationIndex(reg),
+                                           GetVReg(node)));
   }
 
   InstructionOperand DefineAsFixed(Node* node, DoubleRegister reg) {
     return Define(node,
                   UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
-                                     reg.code(), GetVReg(node)));
+                                     DoubleRegister::ToAllocationIndex(reg),
+                                     GetVReg(node)));
   }
 
   InstructionOperand DefineAsConstant(Node* node) {
@@ -105,13 +107,15 @@ class OperandGenerator {
 
   InstructionOperand UseFixed(Node* node, Register reg) {
     return Use(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
-                                        reg.code(), GetVReg(node)));
+                                        Register::ToAllocationIndex(reg),
+                                        GetVReg(node)));
   }
 
   InstructionOperand UseFixed(Node* node, DoubleRegister reg) {
     return Use(node,
                UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
-                                  reg.code(), GetVReg(node)));
+                                  DoubleRegister::ToAllocationIndex(reg),
+                                  GetVReg(node)));
   }
 
   InstructionOperand UseImmediate(Node* node) {
@@ -138,7 +142,8 @@ class OperandGenerator {
   }
 
   InstructionOperand TempRegister(Register reg) {
-    return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, reg.code(),
+    return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
+                              Register::ToAllocationIndex(reg),
                               InstructionOperand::kInvalidVirtualRegister);
   }
 
index a7ed0e5f236f7bae334f7810ee41efc80bcf624e..0fbb94979e41522d4df8d2472372559f4dab5160 100644 (file)
@@ -74,15 +74,11 @@ std::ostream& operator<<(std::ostream& os,
         case UnallocatedOperand::NONE:
           return os;
         case UnallocatedOperand::FIXED_REGISTER:
-          return os << "(="
-                    << conf->GetGeneralRegisterName(
-                           unalloc->fixed_register_index())
-                    << ")";
+          return os << "(=" << conf->general_register_name(
+                                   unalloc->fixed_register_index()) << ")";
         case UnallocatedOperand::FIXED_DOUBLE_REGISTER:
-          return os << "(="
-                    << conf->GetDoubleRegisterName(
-                           unalloc->fixed_register_index())
-                    << ")";
+          return os << "(=" << conf->double_register_name(
+                                   unalloc->fixed_register_index()) << ")";
         case UnallocatedOperand::MUST_HAVE_REGISTER:
           return os << "(R)";
         case UnallocatedOperand::MUST_HAVE_SLOT:
@@ -115,12 +111,14 @@ std::ostream& operator<<(std::ostream& os,
           os << "[double_stack:" << DoubleStackSlotOperand::cast(op).index();
           break;
         case AllocatedOperand::REGISTER:
-          os << "[" << RegisterOperand::cast(op).GetRegister().ToString()
+          os << "["
+             << conf->general_register_name(RegisterOperand::cast(op).index())
              << "|R";
           break;
         case AllocatedOperand::DOUBLE_REGISTER:
-          os << "[" << DoubleRegisterOperand::cast(op).GetRegister().ToString()
-             << "|R";
+          os << "["
+             << conf->double_register_name(
+                    DoubleRegisterOperand::cast(op).index()) << "|R";
           break;
       }
       switch (allocated.machine_type()) {
index fab184adf8090681b2aec00dcc2cfb4964a6a8b4..a0718f3c215a023a1c204b9d6b0ae746ee37c596 100644 (file)
@@ -14,9 +14,8 @@
 #include "src/compiler/frame.h"
 #include "src/compiler/instruction-codes.h"
 #include "src/compiler/opcodes.h"
+#include "src/compiler/register-configuration.h"
 #include "src/compiler/source-position.h"
-#include "src/macro-assembler.h"
-#include "src/register-configuration.h"
 #include "src/zone-allocator.h"
 
 namespace v8 {
@@ -374,23 +373,9 @@ class AllocatedOperand : public InstructionOperand {
   }
 
   int index() const {
-    DCHECK(STACK_SLOT == allocated_kind() ||
-           DOUBLE_STACK_SLOT == allocated_kind());
     return static_cast<int64_t>(value_) >> IndexField::kShift;
   }
 
-  Register GetRegister() const {
-    DCHECK(REGISTER == allocated_kind() || DOUBLE_REGISTER == allocated_kind());
-    return Register::from_code(static_cast<int64_t>(value_) >>
-                               IndexField::kShift);
-  }
-
-  DoubleRegister GetDoubleRegister() const {
-    DCHECK(REGISTER == allocated_kind() || DOUBLE_REGISTER == allocated_kind());
-    return DoubleRegister::from_code(static_cast<int64_t>(value_) >>
-                                     IndexField::kShift);
-  }
-
   AllocatedKind allocated_kind() const {
     return AllocatedKindField::decode(value_);
   }
index fd8aedc15da063fb5b8c940ee4eab62c520c2c15..1def1d99b58f6abb8e53792d7c07a1d4409296c5 100644 (file)
@@ -18,7 +18,7 @@ namespace compiler {
 
 namespace {
 LinkageLocation regloc(Register reg) {
-  return LinkageLocation::ForRegister(reg.code());
+  return LinkageLocation::ForRegister(Register::ToAllocationIndex(reg));
 }
 
 
index f767bd3cf3d6107878eeb82d643da2a11c072d33..fd79a865e2403b423ab819043bdceb7443dfda8c 100644 (file)
@@ -57,7 +57,6 @@
 #include "src/compiler/verifier.h"
 #include "src/compiler/zone-pool.h"
 #include "src/ostreams.h"
-#include "src/register-configuration.h"
 #include "src/type-info.h"
 #include "src/utils.h"
 
index d437c7e585b1f4f2862820ba82894eb173d2548c..90c223f67ea6ef0529f934d264d1cd706a40cb9a 100644 (file)
@@ -11,9 +11,6 @@
 
 namespace v8 {
 namespace internal {
-
-class RegisterConfiguration;
-
 namespace compiler {
 
 class CallDescriptor;
@@ -21,6 +18,7 @@ class Graph;
 class InstructionSequence;
 class Linkage;
 class PipelineData;
+class RegisterConfiguration;
 class Schedule;
 
 class Pipeline {
index 3b595b3b45d98d6222a8d44bb04e991db46f9695..0b775d29e1d83620eb1bc9504a5e8dd315f2dbbb 100644 (file)
@@ -218,16 +218,14 @@ void RegisterAllocatorVerifier::CheckConstraint(
       return;
     case kFixedRegister:
       CHECK(op->IsRegister());
-      CHECK_EQ(RegisterOperand::cast(op)->GetDoubleRegister().code(),
-               constraint->value_);
+      CHECK_EQ(RegisterOperand::cast(op)->index(), constraint->value_);
       return;
     case kDoubleRegister:
       CHECK(op->IsDoubleRegister());
       return;
     case kFixedDoubleRegister:
       CHECK(op->IsDoubleRegister());
-      CHECK_EQ(DoubleRegisterOperand::cast(op)->GetDoubleRegister().code(),
-               constraint->value_);
+      CHECK_EQ(DoubleRegisterOperand::cast(op)->index(), constraint->value_);
       return;
     case kFixedSlot:
       CHECK(op->IsStackSlot());
index 64af331ade04cd2dfeaeb529939e1f206187c304..840c13b1a779aacef537cdd85e94949feaed8a9f 100644 (file)
@@ -27,26 +27,11 @@ void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) {
 
 
 int GetRegisterCount(const RegisterConfiguration* cfg, RegisterKind kind) {
-  return kind == DOUBLE_REGISTERS ? cfg->num_double_registers()
+  return kind == DOUBLE_REGISTERS ? cfg->num_aliased_double_registers()
                                   : cfg->num_general_registers();
 }
 
 
-int GetAllocatableRegisterCount(const RegisterConfiguration* cfg,
-                                RegisterKind kind) {
-  return kind == DOUBLE_REGISTERS
-             ? cfg->num_allocatable_aliased_double_registers()
-             : cfg->num_allocatable_general_registers();
-}
-
-
-const int* GetAllocatableRegisterCodes(const RegisterConfiguration* cfg,
-                                       RegisterKind kind) {
-  return kind == DOUBLE_REGISTERS ? cfg->allocatable_double_codes()
-                                  : cfg->allocatable_general_codes();
-}
-
-
 const InstructionBlock* GetContainingLoop(const InstructionSequence* sequence,
                                           const InstructionBlock* block) {
   auto index = block->loop_header();
@@ -67,11 +52,11 @@ Instruction* GetLastInstruction(InstructionSequence* code,
 }
 
 
-bool IsOutputRegisterOf(Instruction* instr, Register reg) {
+bool IsOutputRegisterOf(Instruction* instr, int index) {
   for (size_t i = 0; i < instr->OutputCount(); i++) {
     auto output = instr->OutputAt(i);
     if (output->IsRegister() &&
-        RegisterOperand::cast(output)->GetRegister().is(reg)) {
+        RegisterOperand::cast(output)->index() == index) {
       return true;
     }
   }
@@ -79,11 +64,11 @@ bool IsOutputRegisterOf(Instruction* instr, Register reg) {
 }
 
 
-bool IsOutputDoubleRegisterOf(Instruction* instr, DoubleRegister reg) {
+bool IsOutputDoubleRegisterOf(Instruction* instr, int index) {
   for (size_t i = 0; i < instr->OutputCount(); i++) {
     auto output = instr->OutputAt(i);
     if (output->IsDoubleRegister() &&
-        DoubleRegisterOperand::cast(output)->GetDoubleRegister().is(reg)) {
+        DoubleRegisterOperand::cast(output)->index() == index) {
       return true;
     }
   }
@@ -144,7 +129,7 @@ bool UsePosition::HasHint() const {
 }
 
 
-bool UsePosition::HintRegister(int* register_code) const {
+bool UsePosition::HintRegister(int* register_index) const {
   if (hint_ == nullptr) return false;
   switch (HintTypeField::decode(flags_)) {
     case UsePositionHintType::kNone:
@@ -154,25 +139,20 @@ bool UsePosition::HintRegister(int* register_code) const {
       auto use_pos = reinterpret_cast<UsePosition*>(hint_);
       int assigned_register = AssignedRegisterField::decode(use_pos->flags_);
       if (assigned_register == kUnassignedRegister) return false;
-      *register_code = assigned_register;
+      *register_index = assigned_register;
       return true;
     }
     case UsePositionHintType::kOperand: {
       auto operand = reinterpret_cast<InstructionOperand*>(hint_);
-      int assigned_register =
-          operand->IsRegister()
-              ? RegisterOperand::cast(operand)->GetRegister().code()
-              : DoubleRegisterOperand::cast(operand)
-                    ->GetDoubleRegister()
-                    .code();
-      *register_code = assigned_register;
+      int assigned_register = AllocatedOperand::cast(operand)->index();
+      *register_index = assigned_register;
       return true;
     }
     case UsePositionHintType::kPhi: {
       auto phi = reinterpret_cast<RegisterAllocationData::PhiMapValue*>(hint_);
       int assigned_register = phi->assigned_register();
       if (assigned_register == kUnassignedRegister) return false;
-      *register_code = assigned_register;
+      *register_index = assigned_register;
       return true;
     }
   }
@@ -1233,10 +1213,6 @@ RegisterAllocationData::RegisterAllocationData(
       debug_name_(debug_name),
       config_(config),
       phi_map_(allocation_zone()),
-      allocatable_codes_(this->config()->num_general_registers(), -1,
-                         allocation_zone()),
-      allocatable_double_codes_(this->config()->num_double_registers(), -1,
-                                allocation_zone()),
       live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
       live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
       live_ranges_(code->VirtualRegisterCount() * 2, nullptr,
@@ -1257,7 +1233,7 @@ RegisterAllocationData::RegisterAllocationData(
   assigned_registers_ = new (code_zone())
       BitVector(this->config()->num_general_registers(), code_zone());
   assigned_double_registers_ = new (code_zone())
-      BitVector(this->config()->num_double_registers(), code_zone());
+      BitVector(this->config()->num_aliased_double_registers(), code_zone());
   this->frame()->SetAllocatedRegisters(assigned_registers_);
   this->frame()->SetAllocatedDoubleRegisters(assigned_double_registers_);
 }
@@ -1796,7 +1772,7 @@ TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
 
 
 TopLevelLiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) {
-  DCHECK(index < config()->num_double_registers());
+  DCHECK(index < config()->num_aliased_double_registers());
   auto result = data()->fixed_double_live_ranges()[index];
   if (result == nullptr) {
     result = data()->NewLiveRange(FixedDoubleLiveRangeID(index), kRepFloat64);
@@ -1817,11 +1793,10 @@ TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
     return data()->GetOrCreateLiveRangeFor(
         ConstantOperand::cast(operand)->virtual_register());
   } else if (operand->IsRegister()) {
-    return FixedLiveRangeFor(
-        RegisterOperand::cast(operand)->GetRegister().code());
+    return FixedLiveRangeFor(RegisterOperand::cast(operand)->index());
   } else if (operand->IsDoubleRegister()) {
     return FixedDoubleLiveRangeFor(
-        DoubleRegisterOperand::cast(operand)->GetDoubleRegister().code());
+        DoubleRegisterOperand::cast(operand)->index());
   } else {
     return nullptr;
   }
@@ -1911,10 +1886,9 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
     }
 
     if (instr->ClobbersRegisters()) {
-      for (int i = 0; i < config()->num_allocatable_general_registers(); ++i) {
-        int code = config()->GetAllocatableGeneralCode(i);
-        if (!IsOutputRegisterOf(instr, Register::from_code(code))) {
-          auto range = FixedLiveRangeFor(code);
+      for (int i = 0; i < config()->num_general_registers(); ++i) {
+        if (!IsOutputRegisterOf(instr, i)) {
+          auto range = FixedLiveRangeFor(i);
           range->AddUseInterval(curr_position, curr_position.End(),
                                 allocation_zone());
         }
@@ -1922,11 +1896,9 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
     }
 
     if (instr->ClobbersDoubleRegisters()) {
-      for (int i = 0; i < config()->num_allocatable_aliased_double_registers();
-           ++i) {
-        int code = config()->GetAllocatableDoubleCode(i);
-        if (!IsOutputDoubleRegisterOf(instr, DoubleRegister::from_code(code))) {
-          auto range = FixedDoubleLiveRangeFor(code);
+      for (int i = 0; i < config()->num_aliased_double_registers(); ++i) {
+        if (!IsOutputDoubleRegisterOf(instr, i)) {
+          auto range = FixedDoubleLiveRangeFor(i);
           range->AddUseInterval(curr_position, curr_position.End(),
                                 allocation_zone());
         }
@@ -2172,11 +2144,7 @@ RegisterAllocator::RegisterAllocator(RegisterAllocationData* data,
                                      RegisterKind kind)
     : data_(data),
       mode_(kind),
-      num_registers_(GetRegisterCount(data->config(), kind)),
-      num_allocatable_registers_(
-          GetAllocatableRegisterCount(data->config(), kind)),
-      allocatable_register_codes_(
-          GetAllocatableRegisterCodes(data->config(), kind)) {}
+      num_registers_(GetRegisterCount(data->config(), kind)) {}
 
 
 LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range,
@@ -2299,11 +2267,11 @@ const ZoneVector<TopLevelLiveRange*>& RegisterAllocator::GetFixedRegisters()
 }
 
 
-const char* RegisterAllocator::RegisterName(int register_code) const {
+const char* RegisterAllocator::RegisterName(int allocation_index) const {
   if (mode() == GENERAL_REGISTERS) {
-    return data()->config()->GetGeneralRegisterName(register_code);
+    return data()->config()->general_register_name(allocation_index);
   } else {
-    return data()->config()->GetDoubleRegisterName(register_code);
+    return data()->config()->double_register_name(allocation_index);
   }
 }
 
@@ -2542,9 +2510,6 @@ bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
   for (auto cur_active : active_live_ranges()) {
     free_until_pos[cur_active->assigned_register()] =
         LifetimePosition::GapFromInstructionIndex(0);
-    TRACE("Register %s is free until pos %d (1)\n",
-          RegisterName(cur_active->assigned_register()),
-          LifetimePosition::GapFromInstructionIndex(0).value());
   }
 
   for (auto cur_inactive : inactive_live_ranges()) {
@@ -2553,8 +2518,6 @@ bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
     if (!next_intersection.IsValid()) continue;
     int cur_reg = cur_inactive->assigned_register();
     free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
-    TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
-          Min(free_until_pos[cur_reg], next_intersection).value());
   }
 
   int hint_register;
@@ -2576,11 +2539,10 @@ bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
   }
 
   // Find the register which stays free for the longest time.
-  int reg = allocatable_register_code(0);
-  for (int i = 1; i < num_alloctable_registers(); ++i) {
-    int code = allocatable_register_code(i);
-    if (free_until_pos[code] > free_until_pos[reg]) {
-      reg = code;
+  int reg = 0;
+  for (int i = 1; i < num_registers(); ++i) {
+    if (free_until_pos[i] > free_until_pos[reg]) {
+      reg = i;
     }
   }
 
@@ -2655,11 +2617,10 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
     }
   }
 
-  int reg = allocatable_register_code(0);
-  for (int i = 1; i < num_alloctable_registers(); ++i) {
-    int code = allocatable_register_code(i);
-    if (use_pos[code] > use_pos[reg]) {
-      reg = code;
+  int reg = 0;
+  for (int i = 1; i < num_registers(); ++i) {
+    if (use_pos[i] > use_pos[reg]) {
+      reg = i;
     }
   }
 
index c0b4fd57d004d1e2d80acd61a0e53de76fb5ea1f..117ddedbcd2a586337b9f68aee239af3333d4c4c 100644 (file)
@@ -7,7 +7,6 @@
 
 #include "src/compiler/instruction.h"
 #include "src/ostreams.h"
-#include "src/register-configuration.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
@@ -242,15 +241,15 @@ class UsePosition final : public ZoneObject {
   void set_next(UsePosition* next) { next_ = next; }
 
   // For hinting only.
-  void set_assigned_register(int register_code) {
-    flags_ = AssignedRegisterField::update(flags_, register_code);
+  void set_assigned_register(int register_index) {
+    flags_ = AssignedRegisterField::update(flags_, register_index);
   }
 
   UsePositionHintType hint_type() const {
     return HintTypeField::decode(flags_);
   }
   bool HasHint() const;
-  bool HintRegister(int* register_code) const;
+  bool HintRegister(int* register_index) const;
   void ResolveHint(UsePosition* use_pos);
   bool IsResolved() const {
     return hint_type() != UsePositionHintType::kUnresolved;
@@ -667,9 +666,9 @@ class RegisterAllocationData final : public ZoneObject {
 
     // For hinting.
     int assigned_register() const { return assigned_register_; }
-    void set_assigned_register(int register_code) {
+    void set_assigned_register(int register_index) {
       DCHECK_EQ(assigned_register_, kUnassignedRegister);
-      assigned_register_ = register_code;
+      assigned_register_ = register_index;
     }
     void UnsetAssignedRegister() { assigned_register_ = kUnassignedRegister; }
 
@@ -770,8 +769,6 @@ class RegisterAllocationData final : public ZoneObject {
   const char* const debug_name_;
   const RegisterConfiguration* const config_;
   PhiMap phi_map_;
-  ZoneVector<int> allocatable_codes_;
-  ZoneVector<int> allocatable_double_codes_;
   ZoneVector<BitVector*> live_in_sets_;
   ZoneVector<BitVector*> live_out_sets_;
   ZoneVector<TopLevelLiveRange*> live_ranges_;
@@ -889,10 +886,6 @@ class RegisterAllocator : public ZoneObject {
   InstructionSequence* code() const { return data()->code(); }
   RegisterKind mode() const { return mode_; }
   int num_registers() const { return num_registers_; }
-  int num_alloctable_registers() const { return num_allocatable_registers_; }
-  int allocatable_register_code(int allocatable_index) const {
-    return allocatable_register_codes_[allocatable_index];
-  }
 
   Zone* allocation_zone() const { return data()->allocation_zone(); }
 
@@ -928,8 +921,6 @@ class RegisterAllocator : public ZoneObject {
   RegisterAllocationData* const data_;
   const RegisterKind mode_;
   const int num_registers_;
-  int num_allocatable_registers_;
-  const int* allocatable_register_codes_;
 
   DISALLOW_COPY_AND_ASSIGN(RegisterAllocator);
 };
diff --git a/src/compiler/register-configuration.cc b/src/compiler/register-configuration.cc
new file mode 100644 (file)
index 0000000..ebe6cfe
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/register-configuration.h"
+#include "src/globals.h"
+#include "src/macro-assembler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
+              Register::kNumRegisters);
+STATIC_ASSERT(RegisterConfiguration::kMaxDoubleRegisters >=
+              DoubleRegister::kMaxNumRegisters);
+
+class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
+ public:
+  ArchDefaultRegisterConfiguration()
+      : RegisterConfiguration(Register::kMaxNumAllocatableRegisters,
+#if V8_TARGET_ARCH_X87
+                              1,
+                              1,
+#else
+                              DoubleRegister::NumAllocatableRegisters(),
+                              DoubleRegister::NumAllocatableAliasedRegisters(),
+#endif
+                              general_register_name_table_,
+                              double_register_name_table_) {
+    DCHECK_EQ(Register::kMaxNumAllocatableRegisters,
+              Register::NumAllocatableRegisters());
+    for (int i = 0; i < Register::kMaxNumAllocatableRegisters; ++i) {
+      general_register_name_table_[i] = Register::AllocationIndexToString(i);
+    }
+    DCHECK_GE(DoubleRegister::kMaxNumAllocatableRegisters,
+              DoubleRegister::NumAllocatableRegisters());
+    for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) {
+      double_register_name_table_[i] =
+          DoubleRegister::AllocationIndexToString(i);
+    }
+  }
+
+  const char*
+      general_register_name_table_[Register::kMaxNumAllocatableRegisters];
+  const char*
+      double_register_name_table_[DoubleRegister::kMaxNumAllocatableRegisters];
+};
+
+
+static base::LazyInstance<ArchDefaultRegisterConfiguration>::type
+    kDefaultRegisterConfiguration = LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
+
+const RegisterConfiguration* RegisterConfiguration::ArchDefault() {
+  return &kDefaultRegisterConfiguration.Get();
+}
+
+RegisterConfiguration::RegisterConfiguration(
+    int num_general_registers, int num_double_registers,
+    int num_aliased_double_registers, const char* const* general_register_names,
+    const char* const* double_register_names)
+    : num_general_registers_(num_general_registers),
+      num_double_registers_(num_double_registers),
+      num_aliased_double_registers_(num_aliased_double_registers),
+      general_register_names_(general_register_names),
+      double_register_names_(double_register_names) {}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/register-configuration.h b/src/compiler/register-configuration.h
new file mode 100644 (file)
index 0000000..f0d5873
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_REGISTER_CONFIGURATION_H_
+#define V8_COMPILER_REGISTER_CONFIGURATION_H_
+
+#include "src/base/macros.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// An architecture independent representation of the sets of registers available
+// for instruction creation.
+class RegisterConfiguration {
+ public:
+  // Architecture independent maxes.
+  static const int kMaxGeneralRegisters = 32;
+  static const int kMaxDoubleRegisters = 32;
+
+  static const RegisterConfiguration* ArchDefault();
+
+  RegisterConfiguration(int num_general_registers, int num_double_registers,
+                        int num_aliased_double_registers,
+                        const char* const* general_register_name,
+                        const char* const* double_register_name);
+
+  int num_general_registers() const { return num_general_registers_; }
+  int num_double_registers() const { return num_double_registers_; }
+  int num_aliased_double_registers() const {
+    return num_aliased_double_registers_;
+  }
+
+  const char* general_register_name(int offset) const {
+    DCHECK(offset >= 0 && offset < kMaxGeneralRegisters);
+    return general_register_names_[offset];
+  }
+  const char* double_register_name(int offset) const {
+    DCHECK(offset >= 0 && offset < kMaxDoubleRegisters);
+    return double_register_names_[offset];
+  }
+
+ private:
+  const int num_general_registers_;
+  const int num_double_registers_;
+  const int num_aliased_double_registers_;
+  const char* const* general_register_names_;
+  const char* const* double_register_names_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_REGISTER_CONFIGURATION_H_
index 786a46640e758cd1a37399b11744db483c33a595..b1f1576081153338d2359f47a10eb8c2c07e3c69 100644 (file)
@@ -2072,7 +2072,7 @@ void Translation::StoreBoolRegister(Register reg) {
 
 void Translation::StoreDoubleRegister(DoubleRegister reg) {
   buffer_->Add(DOUBLE_REGISTER, zone());
-  buffer_->Add(reg.code(), zone());
+  buffer_->Add(DoubleRegister::ToAllocationIndex(reg), zone());
 }
 
 
@@ -2925,7 +2925,7 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
       double value = registers->GetDoubleRegister(input_reg);
       if (trace_file != nullptr) {
         PrintF(trace_file, "%e ; %s (bool)", value,
-               DoubleRegister::from_code(input_reg).ToString());
+               DoubleRegister::AllocationIndexToString(input_reg));
       }
       return TranslatedValue::NewDouble(this, value);
     }
index 99736aaf76163573464b107e077f991e349f941a..76118dce23d6a40feaf1b97bc65c6d9570b2d5b7 100644 (file)
@@ -11,7 +11,6 @@
 #include "src/deoptimizer.h"
 #include "src/frames-inl.h"
 #include "src/full-codegen/full-codegen.h"
-#include "src/register-configuration.h"
 #include "src/safepoint-table.h"
 #include "src/scopeinfo.h"
 #include "src/string-stream.h"
@@ -659,9 +658,8 @@ void StandardFrame::IterateCompiledFrame(ObjectVisitor* v) const {
   if (safepoint_entry.has_doubles()) {
     // Number of doubles not known at snapshot time.
     DCHECK(!isolate()->serializer_enabled());
-    parameters_base += RegisterConfiguration::ArchDefault()
-                           ->num_allocatable_double_registers() *
-                       kDoubleSize / kPointerSize;
+    parameters_base += DoubleRegister::NumAllocatableRegisters() *
+        kDoubleSize / kPointerSize;
   }
 
   // Visit the registers that contain pointers if any.
index ea4ca5e1c8504bc93f248828788e1bb90ceb32db..87f8ce9541495a9623642ccd0fd3e8e3eb5d8b72 100644 (file)
@@ -13462,10 +13462,10 @@ void HTracer::TraceLiveRange(LiveRange* range, const char* type,
       int assigned_reg = op->index();
       if (op->IsDoubleRegister()) {
         trace_.Add(" \"%s\"",
-                   DoubleRegister::from_code(assigned_reg).ToString());
+                   DoubleRegister::AllocationIndexToString(assigned_reg));
       } else {
         DCHECK(op->IsRegister());
-        trace_.Add(" \"%s\"", Register::from_code(assigned_reg).ToString());
+        trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg));
       }
     } else if (range->IsSpilled()) {
       LOperand* op = range->TopLevel()->GetSpillOperand();
index 38ad433fc850ff25d146faa6bb2e2e601b3de666..57987bc7513c6337ae1dff885ddb9fba162f6430 100644 (file)
 #include "src/assembler.h"
 #include "src/compiler.h"
 #include "src/isolate.h"
-#include "src/utils.h"
 
 namespace v8 {
 namespace internal {
 
-#define GENERAL_REGISTERS(V) \
-  V(eax)                     \
-  V(ecx)                     \
-  V(edx)                     \
-  V(ebx)                     \
-  V(esp)                     \
-  V(ebp)                     \
-  V(esi)                     \
-  V(edi)
-
-#define ALLOCATABLE_GENERAL_REGISTERS(V) \
-  V(eax)                                 \
-  V(ecx)                                 \
-  V(edx)                                 \
-  V(ebx)                                 \
-  V(esi)                                 \
-  V(edi)
-
-#define DOUBLE_REGISTERS(V) \
-  V(xmm0)                   \
-  V(xmm1)                   \
-  V(xmm2)                   \
-  V(xmm3)                   \
-  V(xmm4)                   \
-  V(xmm5)                   \
-  V(xmm6)                   \
-  V(xmm7)
-
-#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
-  V(xmm1)                               \
-  V(xmm2)                               \
-  V(xmm3)                               \
-  V(xmm4)                               \
-  V(xmm5)                               \
-  V(xmm6)                               \
-  V(xmm7)
-
 // CPU Registers.
 //
 // 1) We would prefer to use an enum, but enum values are assignment-
@@ -106,86 +68,151 @@ namespace internal {
 // and best performance in optimized code.
 //
 struct Register {
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    GENERAL_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
+  static const int kMaxNumAllocatableRegisters = 6;
+  static int NumAllocatableRegisters() {
+    return kMaxNumAllocatableRegisters;
+  }
+  static const int kNumRegisters = 8;
+
+  static inline const char* AllocationIndexToString(int index);
 
-  static const int kNumRegisters = Code::kAfterLast;
+  static inline int ToAllocationIndex(Register reg);
+
+  static inline Register FromAllocationIndex(int index);
 
   static Register from_code(int code) {
     DCHECK(code >= 0);
     DCHECK(code < kNumRegisters);
-    Register r = {code};
+    Register r = { code };
     return r;
   }
-  const char* ToString();
-  bool IsAllocatable() const;
-  bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
-  bool is(Register reg) const { return reg_code == reg.reg_code; }
+  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
+  bool is(Register reg) const { return code_ == reg.code_; }
+  // eax, ebx, ecx and edx are byte registers, the rest are not.
+  bool is_byte_register() const { return code_ <= 3; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
     DCHECK(is_valid());
-    return 1 << reg_code;
+    return 1 << code_;
   }
 
-  bool is_byte_register() const { return reg_code <= 3; }
-
   // Unfortunately we can't make this private in a struct.
-  int reg_code;
+  int code_;
 };
 
+const int kRegister_eax_Code = 0;
+const int kRegister_ecx_Code = 1;
+const int kRegister_edx_Code = 2;
+const int kRegister_ebx_Code = 3;
+const int kRegister_esp_Code = 4;
+const int kRegister_ebp_Code = 5;
+const int kRegister_esi_Code = 6;
+const int kRegister_edi_Code = 7;
+const int kRegister_no_reg_Code = -1;
+
+const Register eax = { kRegister_eax_Code };
+const Register ecx = { kRegister_ecx_Code };
+const Register edx = { kRegister_edx_Code };
+const Register ebx = { kRegister_ebx_Code };
+const Register esp = { kRegister_esp_Code };
+const Register ebp = { kRegister_ebp_Code };
+const Register esi = { kRegister_esi_Code };
+const Register edi = { kRegister_edi_Code };
+const Register no_reg = { kRegister_no_reg_Code };
+
+
+inline const char* Register::AllocationIndexToString(int index) {
+  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+  // This is the mapping of allocation indices to registers.
+  const char* const kNames[] = { "eax", "ecx", "edx", "ebx", "esi", "edi" };
+  return kNames[index];
+}
+
+
+inline int Register::ToAllocationIndex(Register reg) {
+  DCHECK(reg.is_valid() && !reg.is(esp) && !reg.is(ebp));
+  return (reg.code() >= 6) ? reg.code() - 2 : reg.code();
+}
+
+
+inline Register Register::FromAllocationIndex(int index)  {
+  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+  return (index >= 4) ? from_code(index + 2) : from_code(index);
+}
+
 
-#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
-GENERAL_REGISTERS(DECLARE_REGISTER)
-#undef DECLARE_REGISTER
-const Register no_reg = {Register::kCode_no_reg};
+struct XMMRegister {
+  static const int kMaxNumAllocatableRegisters = 7;
+  static const int kMaxNumRegisters = 8;
+  static int NumAllocatableRegisters() {
+    return kMaxNumAllocatableRegisters;
+  }
 
+  // TODO(turbofan): Proper support for float32.
+  static int NumAllocatableAliasedRegisters() {
+    return NumAllocatableRegisters();
+  }
 
-struct DoubleRegister {
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    DOUBLE_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
+  static int ToAllocationIndex(XMMRegister reg) {
+    DCHECK(reg.code() != 0);
+    return reg.code() - 1;
+  }
 
-  static const int kMaxNumRegisters = Code::kAfterLast;
+  static XMMRegister FromAllocationIndex(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    return from_code(index + 1);
+  }
 
-  static DoubleRegister from_code(int code) {
-    DoubleRegister result = {code};
+  static XMMRegister from_code(int code) {
+    XMMRegister result = { code };
     return result;
   }
 
-  bool IsAllocatable() const;
-  bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
+  bool is_valid() const {
+    return 0 <= code_ && code_ < kMaxNumRegisters;
+  }
 
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
 
-  bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
+  bool is(XMMRegister reg) const { return code_ == reg.code_; }
 
-  const char* ToString();
+  static const char* AllocationIndexToString(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    const char* const names[] = {
+      "xmm1",
+      "xmm2",
+      "xmm3",
+      "xmm4",
+      "xmm5",
+      "xmm6",
+      "xmm7"
+    };
+    return names[index];
+  }
 
-  int reg_code;
+  int code_;
 };
 
-#define DECLARE_REGISTER(R) \
-  const DoubleRegister R = {DoubleRegister::kCode_##R};
-DOUBLE_REGISTERS(DECLARE_REGISTER)
-#undef DECLARE_REGISTER
-const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
 
-typedef DoubleRegister XMMRegister;
+typedef XMMRegister DoubleRegister;
+
+
+const XMMRegister xmm0 = { 0 };
+const XMMRegister xmm1 = { 1 };
+const XMMRegister xmm2 = { 2 };
+const XMMRegister xmm3 = { 3 };
+const XMMRegister xmm4 = { 4 };
+const XMMRegister xmm5 = { 5 };
+const XMMRegister xmm6 = { 6 };
+const XMMRegister xmm7 = { 7 };
+const XMMRegister no_xmm_reg = { -1 };
+
 
 enum Condition {
   // any value < 0 is considered no_condition
index dabd9c08f3850a66013bd169f605539ca056db20..c09b27b773e2a538fa16498d380bbe1e78f5a75f 100644 (file)
@@ -320,15 +320,13 @@ class RecordWriteStub: public PlatformCodeStub {
     Register GetRegThatIsNotEcxOr(Register r1,
                                   Register r2,
                                   Register r3) {
-      for (int i = 0; i < Register::kNumRegisters; i++) {
-        Register candidate = Register::from_code(i);
-        if (candidate.IsAllocatable()) {
-          if (candidate.is(ecx)) continue;
-          if (candidate.is(r1)) continue;
-          if (candidate.is(r2)) continue;
-          if (candidate.is(r3)) continue;
-          return candidate;
-        }
+      for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
+        Register candidate = Register::FromAllocationIndex(i);
+        if (candidate.is(ecx)) continue;
+        if (candidate.is(r1)) continue;
+        if (candidate.is(r2)) continue;
+        if (candidate.is(r3)) continue;
+        return candidate;
       }
       UNREACHABLE();
       return no_reg;
index 756922a1cedf2fb1a8475ab4aca0e3746db7dc50..d804f630ea8e5fa6f5744d1e6b78fe334b9a3efb 100644 (file)
@@ -8,7 +8,6 @@
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
 #include "src/ia32/frames-ia32.h"
-#include "src/register-configuration.h"
 #include "src/safepoint-table.h"
 
 namespace v8 {
@@ -182,7 +181,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
   }
   input_->SetRegister(esp.code(), reinterpret_cast<intptr_t>(frame->sp()));
   input_->SetRegister(ebp.code(), reinterpret_cast<intptr_t>(frame->fp()));
-  for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
+  for (int i = 0; i < XMMRegister::kMaxNumAllocatableRegisters; i++) {
     input_->SetDoubleRegister(i, 0.0);
   }
 
@@ -204,7 +203,7 @@ void Deoptimizer::SetPlatformCompiledStubRegisters(
 
 
 void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
-  for (int i = 0; i < XMMRegister::kMaxNumRegisters; ++i) {
+  for (int i = 0; i < XMMRegister::kMaxNumAllocatableRegisters; ++i) {
     double double_value = input_->GetDoubleRegister(i);
     output_frame->SetDoubleRegister(i, double_value);
   }
@@ -234,13 +233,12 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   // Save all general purpose registers before messing with them.
   const int kNumberOfRegisters = Register::kNumRegisters;
 
-  const int kDoubleRegsSize = kDoubleSize * XMMRegister::kMaxNumRegisters;
+  const int kDoubleRegsSize = kDoubleSize *
+                              XMMRegister::kMaxNumAllocatableRegisters;
   __ sub(esp, Immediate(kDoubleRegsSize));
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    XMMRegister xmm_reg = XMMRegister::from_code(code);
-    int offset = code * kDoubleSize;
+  for (int i = 0; i < XMMRegister::kMaxNumAllocatableRegisters; ++i) {
+    XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
+    int offset = i * kDoubleSize;
     __ movsd(Operand(esp, offset), xmm_reg);
   }
 
@@ -290,10 +288,9 @@ void Deoptimizer::TableEntryGenerator::Generate() {
 
   int double_regs_offset = FrameDescription::double_registers_offset();
   // Fill in the double input registers.
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    int dst_offset = code * kDoubleSize + double_regs_offset;
-    int src_offset = code * kDoubleSize;
+  for (int i = 0; i < XMMRegister::kMaxNumAllocatableRegisters; ++i) {
+    int dst_offset = i * kDoubleSize + double_regs_offset;
+    int src_offset = i * kDoubleSize;
     __ movsd(xmm0, Operand(esp, src_offset));
     __ movsd(Operand(ebx, dst_offset), xmm0);
   }
@@ -374,10 +371,9 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   __ j(below, &outer_push_loop);
 
   // In case of a failed STUB, we have to restore the XMM registers.
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    XMMRegister xmm_reg = XMMRegister::from_code(code);
-    int src_offset = code * kDoubleSize + double_regs_offset;
+  for (int i = 0; i < XMMRegister::kMaxNumAllocatableRegisters; ++i) {
+    XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
+    int src_offset = i * kDoubleSize + double_regs_offset;
     __ movsd(xmm_reg, Operand(ebx, src_offset));
   }
 
index 55438ad888620a2275c897b1e6b719f27739f34e..99c0938b6a4b5110d0b28a7f70c61c2c9ac9c732 100644 (file)
@@ -101,7 +101,7 @@ void LCodeGen::SaveCallerDoubles() {
   BitVector::Iterator save_iterator(doubles);
   while (!save_iterator.Done()) {
     __ movsd(MemOperand(esp, count * kDoubleSize),
-             XMMRegister::from_code(save_iterator.Current()));
+              XMMRegister::FromAllocationIndex(save_iterator.Current()));
     save_iterator.Advance();
     count++;
   }
@@ -116,8 +116,8 @@ void LCodeGen::RestoreCallerDoubles() {
   BitVector::Iterator save_iterator(doubles);
   int count = 0;
   while (!save_iterator.Done()) {
-    __ movsd(XMMRegister::from_code(save_iterator.Current()),
-             MemOperand(esp, count * kDoubleSize));
+    __ movsd(XMMRegister::FromAllocationIndex(save_iterator.Current()),
+              MemOperand(esp, count * kDoubleSize));
     save_iterator.Advance();
     count++;
   }
@@ -515,13 +515,13 @@ bool LCodeGen::GenerateSafepointTable() {
 }
 
 
-Register LCodeGen::ToRegister(int code) const {
-  return Register::from_code(code);
+Register LCodeGen::ToRegister(int index) const {
+  return Register::FromAllocationIndex(index);
 }
 
 
-XMMRegister LCodeGen::ToDoubleRegister(int code) const {
-  return XMMRegister::from_code(code);
+XMMRegister LCodeGen::ToDoubleRegister(int index) const {
+  return XMMRegister::FromAllocationIndex(index);
 }
 
 
index 655f4a2efb71e633fe62b2d06b9d91c7817a5145..0926a0f21a1d4b0a873998232e3a8d501a880d1a 100644 (file)
@@ -6,7 +6,6 @@
 
 #include "src/ia32/lithium-codegen-ia32.h"
 #include "src/ia32/lithium-gap-resolver-ia32.h"
-#include "src/register-configuration.h"
 
 namespace v8 {
 namespace internal {
@@ -166,13 +165,10 @@ int LGapResolver::CountSourceUses(LOperand* operand) {
 
 
 Register LGapResolver::GetFreeRegisterNot(Register reg) {
-  int skip_index = reg.is(no_reg) ? -1 : reg.code();
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_general_registers(); ++i) {
-    int code = config->GetAllocatableGeneralCode(i);
-    if (source_uses_[code] == 0 && destination_uses_[code] > 0 &&
-        code != skip_index) {
-      return Register::from_code(code);
+  int skip_index = reg.is(no_reg) ? -1 : Register::ToAllocationIndex(reg);
+  for (int i = 0; i < Register::NumAllocatableRegisters(); ++i) {
+    if (source_uses_[i] == 0 && destination_uses_[i] > 0 && i != skip_index) {
+      return Register::FromAllocationIndex(i);
     }
   }
   return no_reg;
@@ -182,11 +178,10 @@ Register LGapResolver::GetFreeRegisterNot(Register reg) {
 bool LGapResolver::HasBeenReset() {
   if (!moves_.is_empty()) return false;
   if (spilled_register_ >= 0) return false;
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_general_registers(); ++i) {
-    int code = config->GetAllocatableGeneralCode(i);
-    if (source_uses_[code] != 0) return false;
-    if (destination_uses_[code] != 0) return false;
+
+  for (int i = 0; i < Register::NumAllocatableRegisters(); ++i) {
+    if (source_uses_[i] != 0) return false;
+    if (destination_uses_[i] != 0) return false;
   }
   return true;
 }
@@ -209,7 +204,7 @@ void LGapResolver::Verify() {
 
 void LGapResolver::Finish() {
   if (spilled_register_ >= 0) {
-    __ pop(Register::from_code(spilled_register_));
+    __ pop(Register::FromAllocationIndex(spilled_register_));
     spilled_register_ = -1;
   }
   moves_.Rewind(0);
@@ -218,7 +213,7 @@ void LGapResolver::Finish() {
 
 void LGapResolver::EnsureRestored(LOperand* operand) {
   if (operand->IsRegister() && operand->index() == spilled_register_) {
-    __ pop(Register::from_code(spilled_register_));
+    __ pop(Register::FromAllocationIndex(spilled_register_));
     spilled_register_ = -1;
   }
 }
@@ -227,7 +222,7 @@ void LGapResolver::EnsureRestored(LOperand* operand) {
 Register LGapResolver::EnsureTempRegister() {
   // 1. We may have already spilled to create a temp register.
   if (spilled_register_ >= 0) {
-    return Register::from_code(spilled_register_);
+    return Register::FromAllocationIndex(spilled_register_);
   }
 
   // 2. We may have a free register that we can use without spilling.
@@ -236,21 +231,19 @@ Register LGapResolver::EnsureTempRegister() {
 
   // 3. Prefer to spill a register that is not used in any remaining move
   // because it will not need to be restored until the end.
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_general_registers(); ++i) {
-    int code = config->GetAllocatableGeneralCode(i);
-    if (source_uses_[code] == 0 && destination_uses_[code] == 0) {
-      Register scratch = Register::from_code(code);
+  for (int i = 0; i < Register::NumAllocatableRegisters(); ++i) {
+    if (source_uses_[i] == 0 && destination_uses_[i] == 0) {
+      Register scratch = Register::FromAllocationIndex(i);
       __ push(scratch);
-      spilled_register_ = code;
+      spilled_register_ = i;
       return scratch;
     }
   }
 
   // 4. Use an arbitrary register.  Register 0 is as arbitrary as any other.
-  spilled_register_ = config->GetAllocatableGeneralCode(0);
-  Register scratch = Register::from_code(spilled_register_);
+  Register scratch = Register::FromAllocationIndex(0);
   __ push(scratch);
+  spilled_register_ = 0;
   return scratch;
 }
 
index f9921450c044442dddecabb6d1c24f49b9d6ebe0..d36e78b5f668c2d461fdeb4f73fcae7298bbea50 100644 (file)
@@ -72,8 +72,8 @@ class LGapResolver final BASE_EMBEDDED {
   ZoneList<LMoveOperands> moves_;
 
   // Source and destination use counts for the general purpose registers.
-  int source_uses_[Register::kNumRegisters];
-  int destination_uses_[DoubleRegister::kMaxNumRegisters];
+  int source_uses_[Register::kMaxNumAllocatableRegisters];
+  int destination_uses_[Register::kMaxNumAllocatableRegisters];
 
   // If we had to spill on demand, the currently spilled register's
   // allocation index.
index 262e16bcbd8c5230ce5f8bcc7d5c3af3df379fde..884067b776e417e086b948c93d52d9d362d78083 100644 (file)
@@ -482,13 +482,14 @@ LPlatformChunk* LChunkBuilder::Build() {
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
-  return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
+                                  Register::ToAllocationIndex(reg));
 }
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(XMMRegister reg) {
-  return new (zone())
-      LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
+                                  XMMRegister::ToAllocationIndex(reg));
 }
 
 
index d2f04317f2acf6f4eb944827bd0595da2a58cf8b..2a2338dc07f20b3cca39bfdab6531baa3d64db7d 100644 (file)
@@ -14,17 +14,17 @@ namespace v8 {
 namespace internal {
 
 // Give alias names to registers for calling conventions.
-const Register kReturnRegister0 = {Register::kCode_eax};
-const Register kReturnRegister1 = {Register::kCode_edx};
-const Register kJSFunctionRegister = {Register::kCode_edi};
-const Register kContextRegister = {Register::kCode_esi};
-const Register kInterpreterAccumulatorRegister = {Register::kCode_eax};
-const Register kInterpreterRegisterFileRegister = {Register::kCode_edx};
-const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_ecx};
-const Register kInterpreterBytecodeArrayRegister = {Register::kCode_edi};
-const Register kInterpreterDispatchTableRegister = {Register::kCode_ebx};
-const Register kRuntimeCallFunctionRegister = {Register::kCode_ebx};
-const Register kRuntimeCallArgCountRegister = {Register::kCode_eax};
+const Register kReturnRegister0 = {kRegister_eax_Code};
+const Register kReturnRegister1 = {kRegister_edx_Code};
+const Register kJSFunctionRegister = {kRegister_edi_Code};
+const Register kContextRegister = {kRegister_esi_Code};
+const Register kInterpreterAccumulatorRegister = {kRegister_eax_Code};
+const Register kInterpreterRegisterFileRegister = {kRegister_edx_Code};
+const Register kInterpreterBytecodeOffsetRegister = {kRegister_ecx_Code};
+const Register kInterpreterBytecodeArrayRegister = {kRegister_edi_Code};
+const Register kInterpreterDispatchTableRegister = {kRegister_ebx_Code};
+const Register kRuntimeCallFunctionRegister = {kRegister_ebx_Code};
+const Register kRuntimeCallArgCountRegister = {kRegister_eax_Code};
 
 // Spill slots used by interpreter dispatch calling convention.
 const int kInterpreterContextSpillSlot = -1;
index 7e34daab411dba2f93ff19e838c511fca1b83236..36a12e75b3bcde312b01fc0564212fb4fc60f839 100644 (file)
@@ -7,7 +7,6 @@
 #include "src/hydrogen.h"
 #include "src/lithium-inl.h"
 #include "src/lithium-allocator-inl.h"
-#include "src/register-configuration.h"
 #include "src/string-stream.h"
 
 namespace v8 {
@@ -586,7 +585,7 @@ void LAllocator::AddInitialIntervals(HBasicBlock* block,
 
 
 int LAllocator::FixedDoubleLiveRangeID(int index) {
-  return -index - 1 - Register::kNumRegisters;
+  return -index - 1 - Register::kMaxNumAllocatableRegisters;
 }
 
 
@@ -618,7 +617,7 @@ LOperand* LAllocator::AllocateFixed(LUnallocated* operand,
 
 
 LiveRange* LAllocator::FixedLiveRangeFor(int index) {
-  DCHECK(index < Register::kNumRegisters);
+  DCHECK(index < Register::kMaxNumAllocatableRegisters);
   LiveRange* result = fixed_live_ranges_[index];
   if (result == NULL) {
     result = new(zone()) LiveRange(FixedLiveRangeID(index), chunk()->zone());
@@ -632,7 +631,7 @@ LiveRange* LAllocator::FixedLiveRangeFor(int index) {
 
 
 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) {
-  DCHECK(index < DoubleRegister::kMaxNumRegisters);
+  DCHECK(index < DoubleRegister::NumAllocatableRegisters());
   LiveRange* result = fixed_double_live_ranges_[index];
   if (result == NULL) {
     result = new(zone()) LiveRange(FixedDoubleLiveRangeID(index),
@@ -940,27 +939,25 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
         }
 
         if (instr->ClobbersRegisters()) {
-          for (int i = 0; i < Register::kNumRegisters; ++i) {
-            if (Register::from_code(i).IsAllocatable()) {
-              if (output == NULL || !output->IsRegister() ||
-                  output->index() != i) {
-                LiveRange* range = FixedLiveRangeFor(i);
-                range->AddUseInterval(curr_position,
-                                      curr_position.InstructionEnd(), zone());
-              }
+          for (int i = 0; i < Register::kMaxNumAllocatableRegisters; ++i) {
+            if (output == NULL || !output->IsRegister() ||
+                output->index() != i) {
+              LiveRange* range = FixedLiveRangeFor(i);
+              range->AddUseInterval(curr_position,
+                                    curr_position.InstructionEnd(),
+                                    zone());
             }
           }
         }
 
         if (instr->ClobbersDoubleRegisters(isolate())) {
-          for (int i = 0; i < DoubleRegister::kMaxNumRegisters; ++i) {
-            if (DoubleRegister::from_code(i).IsAllocatable()) {
-              if (output == NULL || !output->IsDoubleRegister() ||
-                  output->index() != i) {
-                LiveRange* range = FixedDoubleLiveRangeFor(i);
-                range->AddUseInterval(curr_position,
-                                      curr_position.InstructionEnd(), zone());
-              }
+          for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) {
+            if (output == NULL || !output->IsDoubleRegister() ||
+                output->index() != i) {
+              LiveRange* range = FixedDoubleLiveRangeFor(i);
+              range->AddUseInterval(curr_position,
+                                    curr_position.InstructionEnd(),
+                                    zone());
             }
           }
         }
@@ -1072,9 +1069,11 @@ bool LAllocator::Allocate(LChunk* chunk) {
   DCHECK(chunk_ == NULL);
   chunk_ = static_cast<LPlatformChunk*>(chunk);
   assigned_registers_ =
-      new (chunk->zone()) BitVector(Register::kNumRegisters, chunk->zone());
-  assigned_double_registers_ = new (chunk->zone())
-      BitVector(DoubleRegister::kMaxNumRegisters, chunk->zone());
+      new(chunk->zone()) BitVector(Register::NumAllocatableRegisters(),
+                                   chunk->zone());
+  assigned_double_registers_ =
+      new(chunk->zone()) BitVector(DoubleRegister::NumAllocatableRegisters(),
+                                   chunk->zone());
   MeetRegisterConstraints();
   if (!AllocationOk()) return false;
   ResolvePhis();
@@ -1461,10 +1460,7 @@ void LAllocator::PopulatePointerMaps() {
 
 void LAllocator::AllocateGeneralRegisters() {
   LAllocatorPhase phase("L_Allocate general registers", this);
-  num_registers_ =
-      RegisterConfiguration::ArchDefault()->num_allocatable_general_registers();
-  allocatable_register_codes_ =
-      RegisterConfiguration::ArchDefault()->allocatable_general_codes();
+  num_registers_ = Register::NumAllocatableRegisters();
   mode_ = GENERAL_REGISTERS;
   AllocateRegisters();
 }
@@ -1472,10 +1468,7 @@ void LAllocator::AllocateGeneralRegisters() {
 
 void LAllocator::AllocateDoubleRegisters() {
   LAllocatorPhase phase("L_Allocate double registers", this);
-  num_registers_ =
-      RegisterConfiguration::ArchDefault()->num_allocatable_double_registers();
-  allocatable_register_codes_ =
-      RegisterConfiguration::ArchDefault()->allocatable_double_codes();
+  num_registers_ = DoubleRegister::NumAllocatableRegisters();
   mode_ = DOUBLE_REGISTERS;
   AllocateRegisters();
 }
@@ -1499,7 +1492,7 @@ void LAllocator::AllocateRegisters() {
   DCHECK(inactive_live_ranges_.is_empty());
 
   if (mode_ == DOUBLE_REGISTERS) {
-    for (int i = 0; i < fixed_double_live_ranges_.length(); ++i) {
+    for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) {
       LiveRange* current = fixed_double_live_ranges_.at(i);
       if (current != NULL) {
         AddToInactive(current);
@@ -1593,9 +1586,9 @@ void LAllocator::AllocateRegisters() {
 
 const char* LAllocator::RegisterName(int allocation_index) {
   if (mode_ == GENERAL_REGISTERS) {
-    return Register::from_code(allocation_index).ToString();
+    return Register::AllocationIndexToString(allocation_index);
   } else {
-    return DoubleRegister::from_code(allocation_index).ToString();
+    return DoubleRegister::AllocationIndexToString(allocation_index);
   }
 }
 
@@ -1757,12 +1750,16 @@ void LAllocator::InactiveToActive(LiveRange* range) {
 }
 
 
-bool LAllocator::TryAllocateFreeReg(LiveRange* current) {
-  DCHECK(DoubleRegister::kMaxNumRegisters >= Register::kNumRegisters);
+// TryAllocateFreeReg and AllocateBlockedReg assume this
+// when allocating local arrays.
+STATIC_ASSERT(DoubleRegister::kMaxNumAllocatableRegisters >=
+              Register::kMaxNumAllocatableRegisters);
 
-  LifetimePosition free_until_pos[DoubleRegister::kMaxNumRegisters];
 
-  for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
+bool LAllocator::TryAllocateFreeReg(LiveRange* current) {
+  LifetimePosition free_until_pos[DoubleRegister::kMaxNumAllocatableRegisters];
+
+  for (int i = 0; i < num_registers_; i++) {
     free_until_pos[i] = LifetimePosition::MaxPosition();
   }
 
@@ -1803,11 +1800,10 @@ bool LAllocator::TryAllocateFreeReg(LiveRange* current) {
   }
 
   // Find the register which stays free for the longest time.
-  int reg = allocatable_register_codes_[0];
+  int reg = 0;
   for (int i = 1; i < RegisterCount(); ++i) {
-    int code = allocatable_register_codes_[i];
-    if (free_until_pos[code].Value() > free_until_pos[reg].Value()) {
-      reg = code;
+    if (free_until_pos[i].Value() > free_until_pos[reg].Value()) {
+      reg = i;
     }
   }
 
@@ -1849,10 +1845,10 @@ void LAllocator::AllocateBlockedReg(LiveRange* current) {
   }
 
 
-  LifetimePosition use_pos[DoubleRegister::kMaxNumRegisters];
-  LifetimePosition block_pos[DoubleRegister::kMaxNumRegisters];
+  LifetimePosition use_pos[DoubleRegister::kMaxNumAllocatableRegisters];
+  LifetimePosition block_pos[DoubleRegister::kMaxNumAllocatableRegisters];
 
-  for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
+  for (int i = 0; i < num_registers_; i++) {
     use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
   }
 
@@ -1887,11 +1883,10 @@ void LAllocator::AllocateBlockedReg(LiveRange* current) {
     }
   }
 
-  int reg = allocatable_register_codes_[0];
+  int reg = 0;
   for (int i = 1; i < RegisterCount(); ++i) {
-    int code = allocatable_register_codes_[i];
-    if (use_pos[code].Value() > use_pos[reg].Value()) {
-      reg = code;
+    if (use_pos[i].Value() > use_pos[reg].Value()) {
+      reg = i;
     }
   }
 
index 476f6f45c08ab3b2047539b03c043cf8159f4572..7c947724509da266c0dd342f1f53d20073cacce4 100644 (file)
@@ -520,8 +520,9 @@ class LAllocator BASE_EMBEDDED {
   ZoneList<LiveRange*> live_ranges_;
 
   // Lists of live ranges
-  EmbeddedVector<LiveRange*, Register::kNumRegisters> fixed_live_ranges_;
-  EmbeddedVector<LiveRange*, DoubleRegister::kMaxNumRegisters>
+  EmbeddedVector<LiveRange*, Register::kMaxNumAllocatableRegisters>
+      fixed_live_ranges_;
+  EmbeddedVector<LiveRange*, DoubleRegister::kMaxNumAllocatableRegisters>
       fixed_double_live_ranges_;
   ZoneList<LiveRange*> unhandled_live_ranges_;
   ZoneList<LiveRange*> active_live_ranges_;
@@ -535,7 +536,6 @@ class LAllocator BASE_EMBEDDED {
 
   RegisterKind mode_;
   int num_registers_;
-  const int* allocatable_register_codes_;
 
   BitVector* assigned_registers_;
   BitVector* assigned_double_registers_;
index bc48a0a16389e3f505ebba26fba867726f45e271..7d37532ace71140d61bf42f20937aac91ac3088d 100644 (file)
@@ -56,22 +56,24 @@ void LOperand::PrintTo(StringStream* stream) {
           break;
         case LUnallocated::FIXED_REGISTER: {
           int reg_index = unalloc->fixed_register_index();
-          if (reg_index < 0 || reg_index >= Register::kNumRegisters) {
+          if (reg_index < 0 ||
+              reg_index >= Register::kMaxNumAllocatableRegisters) {
             stream->Add("(=invalid_reg#%d)", reg_index);
           } else {
             const char* register_name =
-                Register::from_code(reg_index).ToString();
+                Register::AllocationIndexToString(reg_index);
             stream->Add("(=%s)", register_name);
           }
           break;
         }
         case LUnallocated::FIXED_DOUBLE_REGISTER: {
           int reg_index = unalloc->fixed_register_index();
-          if (reg_index < 0 || reg_index >= DoubleRegister::kMaxNumRegisters) {
+          if (reg_index < 0 ||
+              reg_index >= DoubleRegister::kMaxNumAllocatableRegisters) {
             stream->Add("(=invalid_double_reg#%d)", reg_index);
           } else {
             const char* double_register_name =
-                DoubleRegister::from_code(reg_index).ToString();
+                DoubleRegister::AllocationIndexToString(reg_index);
             stream->Add("(=%s)", double_register_name);
           }
           break;
@@ -104,19 +106,21 @@ void LOperand::PrintTo(StringStream* stream) {
       break;
     case REGISTER: {
       int reg_index = index();
-      if (reg_index < 0 || reg_index >= Register::kNumRegisters) {
+      if (reg_index < 0 || reg_index >= Register::kMaxNumAllocatableRegisters) {
         stream->Add("(=invalid_reg#%d|R)", reg_index);
       } else {
-        stream->Add("[%s|R]", Register::from_code(reg_index).ToString());
+        stream->Add("[%s|R]", Register::AllocationIndexToString(reg_index));
       }
       break;
     }
     case DOUBLE_REGISTER: {
       int reg_index = index();
-      if (reg_index < 0 || reg_index >= DoubleRegister::kMaxNumRegisters) {
+      if (reg_index < 0 ||
+          reg_index >= DoubleRegister::kMaxNumAllocatableRegisters) {
         stream->Add("(=invalid_double_reg#%d|R)", reg_index);
       } else {
-        stream->Add("[%s|R]", DoubleRegister::from_code(reg_index).ToString());
+        stream->Add("[%s|R]",
+                    DoubleRegister::AllocationIndexToString(reg_index));
       }
       break;
     }
index 8e7a1f5e9167bb14b6c8e2d9d64f1c406797012c..f4bddf54613731d9d5a002e09412bf3c62fd1ef3 100644 (file)
@@ -84,6 +84,36 @@ bool Operand::is_reg() const {
 }
 
 
+int Register::NumAllocatableRegisters() {
+    return kMaxNumAllocatableRegisters;
+}
+
+
+int DoubleRegister::NumRegisters() {
+    return FPURegister::kMaxNumRegisters;
+}
+
+
+int DoubleRegister::NumAllocatableRegisters() {
+    return FPURegister::kMaxNumAllocatableRegisters;
+}
+
+
+int DoubleRegister::NumAllocatableAliasedRegisters() {
+  return NumAllocatableRegisters();
+}
+
+
+int FPURegister::ToAllocationIndex(FPURegister reg) {
+  DCHECK(reg.code() % 2 == 0);
+  DCHECK(reg.code() / 2 < kMaxNumAllocatableRegisters);
+  DCHECK(reg.is_valid());
+  DCHECK(!reg.is(kDoubleRegZero));
+  DCHECK(!reg.is(kLithiumScratchDouble));
+  return (reg.code() / 2);
+}
+
+
 // -----------------------------------------------------------------------------
 // RelocInfo.
 
index 87abbe1b4d1ea6ba01a2d7f697d5042baa7bb73c..7fa4d5d66a5c2fe2c97f67c480811c189c6e99d0 100644 (file)
@@ -64,6 +64,28 @@ static unsigned CpuFeaturesImpliedByCompiler() {
 }
 
 
+const char* DoubleRegister::AllocationIndexToString(int index) {
+  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+  const char* const names[] = {
+    "f0",
+    "f2",
+    "f4",
+    "f6",
+    "f8",
+    "f10",
+    "f12",
+    "f14",
+    "f16",
+    "f18",
+    "f20",
+    "f22",
+    "f24",
+    "f26"
+  };
+  return names[index];
+}
+
+
 void CpuFeatures::ProbeImpl(bool cross_compile) {
   supported_ |= CpuFeaturesImpliedByCompiler();
 
@@ -228,31 +250,31 @@ MemOperand::MemOperand(Register rm, int32_t unit, int32_t multiplier,
 static const int kNegOffset = 0x00008000;
 // addiu(sp, sp, 4) aka Pop() operation or part of Pop(r)
 // operations as post-increment of sp.
-const Instr kPopInstruction = ADDIU | (Register::kCode_sp << kRsShift) |
-                              (Register::kCode_sp << kRtShift) |
-                              (kPointerSize & kImm16Mask);  // NOLINT
+const Instr kPopInstruction = ADDIU | (kRegister_sp_Code << kRsShift)
+      | (kRegister_sp_Code << kRtShift)
+      | (kPointerSize & kImm16Mask);  // NOLINT
 // addiu(sp, sp, -4) part of Push(r) operation as pre-decrement of sp.
-const Instr kPushInstruction = ADDIU | (Register::kCode_sp << kRsShift) |
-                               (Register::kCode_sp << kRtShift) |
-                               (-kPointerSize & kImm16Mask);  // NOLINT
+const Instr kPushInstruction = ADDIU | (kRegister_sp_Code << kRsShift)
+      | (kRegister_sp_Code << kRtShift)
+      | (-kPointerSize & kImm16Mask);  // NOLINT
 // sw(r, MemOperand(sp, 0))
-const Instr kPushRegPattern =
-    SW | (Register::kCode_sp << kRsShift) | (0 & kImm16Mask);  // NOLINT
+const Instr kPushRegPattern = SW | (kRegister_sp_Code << kRsShift)
+      | (0 & kImm16Mask);  // NOLINT
 //  lw(r, MemOperand(sp, 0))
-const Instr kPopRegPattern =
-    LW | (Register::kCode_sp << kRsShift) | (0 & kImm16Mask);  // NOLINT
+const Instr kPopRegPattern = LW | (kRegister_sp_Code << kRsShift)
+      | (0 & kImm16Mask);  // NOLINT
 
-const Instr kLwRegFpOffsetPattern =
-    LW | (Register::kCode_fp << kRsShift) | (0 & kImm16Mask);  // NOLINT
+const Instr kLwRegFpOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
+      | (0 & kImm16Mask);  // NOLINT
 
-const Instr kSwRegFpOffsetPattern =
-    SW | (Register::kCode_fp << kRsShift) | (0 & kImm16Mask);  // NOLINT
+const Instr kSwRegFpOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
+      | (0 & kImm16Mask);  // NOLINT
 
-const Instr kLwRegFpNegOffsetPattern = LW | (Register::kCode_fp << kRsShift) |
-                                       (kNegOffset & kImm16Mask);  // NOLINT
+const Instr kLwRegFpNegOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
+      | (kNegOffset & kImm16Mask);  // NOLINT
 
-const Instr kSwRegFpNegOffsetPattern = SW | (Register::kCode_fp << kRsShift) |
-                                       (kNegOffset & kImm16Mask);  // NOLINT
+const Instr kSwRegFpNegOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
+      | (kNegOffset & kImm16Mask);  // NOLINT
 // A mask for the Rt register for push, pop, lw, sw instructions.
 const Instr kRtMask = kRtFieldMask;
 const Instr kLwSwInstrTypeMask = 0xffe00000;
@@ -312,21 +334,21 @@ void Assembler::CodeTargetAlign() {
 
 Register Assembler::GetRtReg(Instr instr) {
   Register rt;
-  rt.reg_code = (instr & kRtFieldMask) >> kRtShift;
+  rt.code_ = (instr & kRtFieldMask) >> kRtShift;
   return rt;
 }
 
 
 Register Assembler::GetRsReg(Instr instr) {
   Register rs;
-  rs.reg_code = (instr & kRsFieldMask) >> kRsShift;
+  rs.code_ = (instr & kRsFieldMask) >> kRsShift;
   return rs;
 }
 
 
 Register Assembler::GetRdReg(Instr instr) {
   Register rd;
-  rd.reg_code = (instr & kRdFieldMask) >> kRdShift;
+  rd.code_ = (instr & kRdFieldMask) >> kRdShift;
   return rd;
 }
 
@@ -1920,14 +1942,14 @@ void Assembler::movn(Register rd, Register rs, Register rt) {
 
 void Assembler::movt(Register rd, Register rs, uint16_t cc) {
   Register rt;
-  rt.reg_code = (cc & 0x0007) << 2 | 1;
+  rt.code_ = (cc & 0x0007) << 2 | 1;
   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
 }
 
 
 void Assembler::movf(Register rd, Register rs, uint16_t cc) {
   Register rt;
-  rt.reg_code = (cc & 0x0007) << 2 | 0;
+  rt.code_ = (cc & 0x0007) << 2 | 0;
   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
 }
 
@@ -2211,7 +2233,7 @@ void Assembler::movz_d(FPURegister fd, FPURegister fs, Register rt) {
 void Assembler::movt_s(FPURegister fd, FPURegister fs, uint16_t cc) {
   DCHECK(IsMipsArchVariant(kMips32r2));
   FPURegister ft;
-  ft.reg_code = (cc & 0x0007) << 2 | 1;
+  ft.code_ = (cc & 0x0007) << 2 | 1;
   GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
 }
 
@@ -2219,7 +2241,7 @@ void Assembler::movt_s(FPURegister fd, FPURegister fs, uint16_t cc) {
 void Assembler::movt_d(FPURegister fd, FPURegister fs, uint16_t cc) {
   DCHECK(IsMipsArchVariant(kMips32r2));
   FPURegister ft;
-  ft.reg_code = (cc & 0x0007) << 2 | 1;
+  ft.code_ = (cc & 0x0007) << 2 | 1;
   GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
 }
 
@@ -2227,7 +2249,7 @@ void Assembler::movt_d(FPURegister fd, FPURegister fs, uint16_t cc) {
 void Assembler::movf_s(FPURegister fd, FPURegister fs, uint16_t cc) {
   DCHECK(IsMipsArchVariant(kMips32r2));
   FPURegister ft;
-  ft.reg_code = (cc & 0x0007) << 2 | 0;
+  ft.code_ = (cc & 0x0007) << 2 | 0;
   GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
 }
 
@@ -2235,7 +2257,7 @@ void Assembler::movf_s(FPURegister fd, FPURegister fs, uint16_t cc) {
 void Assembler::movf_d(FPURegister fd, FPURegister fs, uint16_t cc) {
   DCHECK(IsMipsArchVariant(kMips32r2));
   FPURegister ft;
-  ft.reg_code = (cc & 0x0007) << 2 | 0;
+  ft.code_ = (cc & 0x0007) << 2 | 0;
   GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
 }
 
index 53fc8315d241e59b5c2754a58c0127f27df5d11a..c47f6d3abe2760997039c195e584ce6276a9440d 100644 (file)
 namespace v8 {
 namespace internal {
 
-// clang-format off
-#define GENERAL_REGISTERS(V)                              \
-  V(zero_reg)  V(at)  V(v0)  V(v1)  V(a0)  V(a1)  V(a2)  V(a3)  \
-  V(t0)  V(t1)  V(t2)  V(t3)  V(t4)  V(t5)  V(t6)  V(t7)  \
-  V(s0)  V(s1)  V(s2)  V(s3)  V(s4)  V(s5)  V(s6)  V(s7)  V(t8)  V(t9) \
-  V(k0)  V(k1)  V(gp)  V(sp)  V(fp)  V(ra)
-
-#define ALLOCATABLE_GENERAL_REGISTERS(V) \
-  V(v0)  V(v1)  V(a0)  V(a1)  V(a2)  V(a3) \
-  V(t0)  V(t1)  V(t2)  V(t3)  V(t4)  V(t5)  V(t6) V(s7)
-
-#define DOUBLE_REGISTERS(V)                               \
-  V(f0)  V(f1)  V(f2)  V(f3)  V(f4)  V(f5)  V(f6)  V(f7)  \
-  V(f8)  V(f9)  V(f10) V(f11) V(f12) V(f13) V(f14) V(f15) \
-  V(f16) V(f17) V(f18) V(f19) V(f20) V(f21) V(f22) V(f23) \
-  V(f24) V(f25) V(f26) V(f27) V(f28) V(f29) V(f30) V(f31)
-
-#define ALLOCATABLE_DOUBLE_REGISTERS(V)                   \
-  V(f0)  V(f2)  V(f4)  V(f6)  V(f8)  V(f10) V(f12) V(f14) \
-  V(f16) V(f18) V(f20) V(f22) V(f24) V(f26)
-// clang-format on
-
 // CPU Registers.
 //
 // 1) We would prefer to use an enum, but enum values are assignment-
@@ -94,19 +72,13 @@ namespace internal {
 // -----------------------------------------------------------------------------
 // Implementation of Register and FPURegister.
 
+// Core register.
 struct Register {
+  static const int kNumRegisters = v8::internal::kNumRegisters;
+  static const int kMaxNumAllocatableRegisters = 14;  // v0 through t6 and cp.
+  static const int kSizeInBytes = 4;
   static const int kCpRegister = 23;  // cp (s7) is the 23rd register.
 
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    GENERAL_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
-
-  static const int kNumRegisters = Code::kAfterLast;
-
 #if defined(V8_TARGET_LITTLE_ENDIAN)
   static const int kMantissaOffset = 0;
   static const int kExponentOffset = 4;
@@ -117,37 +89,117 @@ struct Register {
 #error Unknown endianness
 #endif
 
+  inline static int NumAllocatableRegisters();
+
+  static int ToAllocationIndex(Register reg) {
+    DCHECK((reg.code() - 2) < (kMaxNumAllocatableRegisters - 1) ||
+           reg.is(from_code(kCpRegister)));
+    return reg.is(from_code(kCpRegister)) ?
+           kMaxNumAllocatableRegisters - 1 :  // Return last index for 'cp'.
+           reg.code() - 2;  // zero_reg and 'at' are skipped.
+  }
+
+  static Register FromAllocationIndex(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    return index == kMaxNumAllocatableRegisters - 1 ?
+           from_code(kCpRegister) :  // Last index is always the 'cp' register.
+           from_code(index + 2);  // zero_reg and 'at' are skipped.
+  }
+
+  static const char* AllocationIndexToString(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    const char* const names[] = {
+      "v0",
+      "v1",
+      "a0",
+      "a1",
+      "a2",
+      "a3",
+      "t0",
+      "t1",
+      "t2",
+      "t3",
+      "t4",
+      "t5",
+      "t6",
+      "s7",
+    };
+    return names[index];
+  }
 
   static Register from_code(int code) {
-    DCHECK(code >= 0);
-    DCHECK(code < kNumRegisters);
-    Register r = {code};
+    Register r = { code };
     return r;
   }
-  const char* ToString();
-  bool IsAllocatable() const;
-  bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
-  bool is(Register reg) const { return reg_code == reg.reg_code; }
+
+  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
+  bool is(Register reg) const { return code_ == reg.code_; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
     DCHECK(is_valid());
-    return 1 << reg_code;
+    return 1 << code_;
   }
 
   // Unfortunately we can't make this private in a struct.
-  int reg_code;
+  int code_;
 };
 
-// s7: context register
-// s3: lithium scratch
-// s4: lithium scratch2
-#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
-GENERAL_REGISTERS(DECLARE_REGISTER)
-#undef DECLARE_REGISTER
-const Register no_reg = {Register::kCode_no_reg};
+#define REGISTER(N, C) \
+  const int kRegister_ ## N ## _Code = C; \
+  const Register N = { C }
+
+REGISTER(no_reg, -1);
+// Always zero.
+REGISTER(zero_reg, 0);
+// at: Reserved for synthetic instructions.
+REGISTER(at, 1);
+// v0, v1: Used when returning multiple values from subroutines.
+REGISTER(v0, 2);
+REGISTER(v1, 3);
+// a0 - a4: Used to pass non-FP parameters.
+REGISTER(a0, 4);
+REGISTER(a1, 5);
+REGISTER(a2, 6);
+REGISTER(a3, 7);
+// t0 - t9: Can be used without reservation, act as temporary registers and are
+// allowed to be destroyed by subroutines.
+REGISTER(t0, 8);
+REGISTER(t1, 9);
+REGISTER(t2, 10);
+REGISTER(t3, 11);
+REGISTER(t4, 12);
+REGISTER(t5, 13);
+REGISTER(t6, 14);
+REGISTER(t7, 15);
+// s0 - s7: Subroutine register variables. Subroutines that write to these
+// registers must restore their values before exiting so that the caller can
+// expect the values to be preserved.
+REGISTER(s0, 16);
+REGISTER(s1, 17);
+REGISTER(s2, 18);
+REGISTER(s3, 19);
+REGISTER(s4, 20);
+REGISTER(s5, 21);
+REGISTER(s6, 22);
+REGISTER(s7, 23);
+REGISTER(t8, 24);
+REGISTER(t9, 25);
+// k0, k1: Reserved for system calls and interrupt handlers.
+REGISTER(k0, 26);
+REGISTER(k1, 27);
+// gp: Reserved.
+REGISTER(gp, 28);
+// sp: Stack pointer.
+REGISTER(sp, 29);
+// fp: Frame pointer.
+REGISTER(fp, 30);
+// ra: Return address pointer.
+REGISTER(ra, 31);
+
+#undef REGISTER
 
 
 int ToNumber(Register reg);
@@ -155,70 +207,75 @@ int ToNumber(Register reg);
 Register ToRegister(int num);
 
 // Coprocessor register.
-struct DoubleRegister {
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    DOUBLE_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
-
-  static const int kMaxNumRegisters = Code::kAfterLast;
-
-  inline static int NumRegisters();
+struct FPURegister {
+  static const int kMaxNumRegisters = v8::internal::kNumFPURegisters;
 
   // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers
   // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to
   // number of Double regs (64-bit regs, or FPU-reg-pairs).
 
-  const char* ToString();
-  bool IsAllocatable() const;
-  bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
-  bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
-  DoubleRegister low() const {
+  // A few double registers are reserved: one as a scratch register and one to
+  // hold 0.0.
+  //  f28: 0.0
+  //  f30: scratch register.
+  static const int kNumReservedRegisters = 2;
+  static const int kMaxNumAllocatableRegisters = kMaxNumRegisters / 2 -
+      kNumReservedRegisters;
+
+  inline static int NumRegisters();
+  inline static int NumAllocatableRegisters();
+
+  // TODO(turbofan): Proper support for float32.
+  inline static int NumAllocatableAliasedRegisters();
+
+  inline static int ToAllocationIndex(FPURegister reg);
+  static const char* AllocationIndexToString(int index);
+
+  static FPURegister FromAllocationIndex(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    return from_code(index * 2);
+  }
+
+  static FPURegister from_code(int code) {
+    FPURegister r = { code };
+    return r;
+  }
+
+  bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters ; }
+  bool is(FPURegister creg) const { return code_ == creg.code_; }
+  FPURegister low() const {
     // Find low reg of a Double-reg pair, which is the reg itself.
-    DCHECK(reg_code % 2 == 0);  // Specified Double reg must be even.
-    DoubleRegister reg;
-    reg.reg_code = reg_code;
+    DCHECK(code_ % 2 == 0);  // Specified Double reg must be even.
+    FPURegister reg;
+    reg.code_ = code_;
     DCHECK(reg.is_valid());
     return reg;
   }
-  DoubleRegister high() const {
+  FPURegister high() const {
     // Find high reg of a Doubel-reg pair, which is reg + 1.
-    DCHECK(reg_code % 2 == 0);  // Specified Double reg must be even.
-    DoubleRegister reg;
-    reg.reg_code = reg_code + 1;
+    DCHECK(code_ % 2 == 0);  // Specified Double reg must be even.
+    FPURegister reg;
+    reg.code_ = code_ + 1;
     DCHECK(reg.is_valid());
     return reg;
   }
 
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
     DCHECK(is_valid());
-    return 1 << reg_code;
-  }
-
-  static DoubleRegister from_code(int code) {
-    DoubleRegister r = {code};
-    return r;
+    return 1 << code_;
   }
   void setcode(int f) {
-    reg_code = f;
+    code_ = f;
     DCHECK(is_valid());
   }
   // Unfortunately we can't make this private in a struct.
-  int reg_code;
+  int code_;
 };
 
-// A few double registers are reserved: one as a scratch register and one to
-// hold 0.0.
-//  f28: 0.0
-//  f30: scratch register.
-
 // V8 now supports the O32 ABI, and the FPU Registers are organized as 32
 // 32-bit registers, f0 through f31. When used as 'double' they are used
 // in pairs, starting with the even numbered register. So a double operation
@@ -228,43 +285,43 @@ struct DoubleRegister {
 // but it is not in common use. Someday we will want to support this in v8.)
 
 // For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers.
-typedef DoubleRegister FPURegister;
-typedef DoubleRegister FloatRegister;
-
-const DoubleRegister no_freg = {-1};
-
-const DoubleRegister f0 = {0};  // Return value in hard float mode.
-const DoubleRegister f1 = {1};
-const DoubleRegister f2 = {2};
-const DoubleRegister f3 = {3};
-const DoubleRegister f4 = {4};
-const DoubleRegister f5 = {5};
-const DoubleRegister f6 = {6};
-const DoubleRegister f7 = {7};
-const DoubleRegister f8 = {8};
-const DoubleRegister f9 = {9};
-const DoubleRegister f10 = {10};
-const DoubleRegister f11 = {11};
-const DoubleRegister f12 = {12};  // Arg 0 in hard float mode.
-const DoubleRegister f13 = {13};
-const DoubleRegister f14 = {14};  // Arg 1 in hard float mode.
-const DoubleRegister f15 = {15};
-const DoubleRegister f16 = {16};
-const DoubleRegister f17 = {17};
-const DoubleRegister f18 = {18};
-const DoubleRegister f19 = {19};
-const DoubleRegister f20 = {20};
-const DoubleRegister f21 = {21};
-const DoubleRegister f22 = {22};
-const DoubleRegister f23 = {23};
-const DoubleRegister f24 = {24};
-const DoubleRegister f25 = {25};
-const DoubleRegister f26 = {26};
-const DoubleRegister f27 = {27};
-const DoubleRegister f28 = {28};
-const DoubleRegister f29 = {29};
-const DoubleRegister f30 = {30};
-const DoubleRegister f31 = {31};
+typedef FPURegister DoubleRegister;
+typedef FPURegister FloatRegister;
+
+const FPURegister no_freg = { -1 };
+
+const FPURegister f0 = { 0 };  // Return value in hard float mode.
+const FPURegister f1 = { 1 };
+const FPURegister f2 = { 2 };
+const FPURegister f3 = { 3 };
+const FPURegister f4 = { 4 };
+const FPURegister f5 = { 5 };
+const FPURegister f6 = { 6 };
+const FPURegister f7 = { 7 };
+const FPURegister f8 = { 8 };
+const FPURegister f9 = { 9 };
+const FPURegister f10 = { 10 };
+const FPURegister f11 = { 11 };
+const FPURegister f12 = { 12 };  // Arg 0 in hard float mode.
+const FPURegister f13 = { 13 };
+const FPURegister f14 = { 14 };  // Arg 1 in hard float mode.
+const FPURegister f15 = { 15 };
+const FPURegister f16 = { 16 };
+const FPURegister f17 = { 17 };
+const FPURegister f18 = { 18 };
+const FPURegister f19 = { 19 };
+const FPURegister f20 = { 20 };
+const FPURegister f21 = { 21 };
+const FPURegister f22 = { 22 };
+const FPURegister f23 = { 23 };
+const FPURegister f24 = { 24 };
+const FPURegister f25 = { 25 };
+const FPURegister f26 = { 26 };
+const FPURegister f27 = { 27 };
+const FPURegister f28 = { 28 };
+const FPURegister f29 = { 29 };
+const FPURegister f30 = { 30 };
+const FPURegister f31 = { 31 };
 
 // Register aliases.
 // cp is assumed to be a callee saved register.
@@ -284,22 +341,22 @@ const DoubleRegister f31 = {31};
 // FPU (coprocessor 1) control registers.
 // Currently only FCSR (#31) is implemented.
 struct FPUControlRegister {
-  bool is_valid() const { return reg_code == kFCSRRegister; }
-  bool is(FPUControlRegister creg) const { return reg_code == creg.reg_code; }
+  bool is_valid() const { return code_ == kFCSRRegister; }
+  bool is(FPUControlRegister creg) const { return code_ == creg.code_; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
     DCHECK(is_valid());
-    return 1 << reg_code;
+    return 1 << code_;
   }
   void setcode(int f) {
-    reg_code = f;
+    code_ = f;
     DCHECK(is_valid());
   }
   // Unfortunately we can't make this private in a struct.
-  int reg_code;
+  int code_;
 };
 
 const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister };
index 10cab306a29d2ca3c24d008ba3acd2ae96f81138..974692495a24e9d31fd0c166576b80fb8a9c10c6 100644 (file)
@@ -5,7 +5,6 @@
 #include "src/codegen.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
-#include "src/register-configuration.h"
 #include "src/safepoint-table.h"
 
 namespace v8 {
@@ -89,7 +88,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
   }
   input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
   input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
-  for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
+  for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
     input_->SetDoubleRegister(i, 0.0);
   }
 
@@ -140,15 +139,14 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   RegList restored_regs = kJSCallerSaved | kCalleeSaved;
   RegList saved_regs = restored_regs | sp.bit() | ra.bit();
 
-  const int kDoubleRegsSize = kDoubleSize * DoubleRegister::kMaxNumRegisters;
+  const int kDoubleRegsSize =
+      kDoubleSize * FPURegister::kMaxNumAllocatableRegisters;
 
   // Save all FPU registers before messing with them.
   __ Subu(sp, sp, Operand(kDoubleRegsSize));
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    const DoubleRegister fpu_reg = DoubleRegister::from_code(code);
-    int offset = code * kDoubleSize;
+  for (int i = 0; i < FPURegister::kMaxNumAllocatableRegisters; ++i) {
+    FPURegister fpu_reg = FPURegister::FromAllocationIndex(i);
+    int offset = i * kDoubleSize;
     __ sdc1(fpu_reg, MemOperand(sp, offset));
   }
 
@@ -217,10 +215,9 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   int double_regs_offset = FrameDescription::double_registers_offset();
   // Copy FPU registers to
   // double_registers_[DoubleRegister::kNumAllocatableRegisters]
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    int dst_offset = code * kDoubleSize + double_regs_offset;
-    int src_offset = code * kDoubleSize + kNumberOfRegisters * kPointerSize;
+  for (int i = 0; i < FPURegister::NumAllocatableRegisters(); ++i) {
+    int dst_offset = i * kDoubleSize + double_regs_offset;
+    int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
     __ ldc1(f0, MemOperand(sp, src_offset));
     __ sdc1(f0, MemOperand(a1, dst_offset));
   }
@@ -287,10 +284,9 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   __ BranchShort(&outer_push_loop, lt, t0, Operand(a1));
 
   __ lw(a1, MemOperand(a0, Deoptimizer::input_offset()));
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    const DoubleRegister fpu_reg = DoubleRegister::from_code(code);
-    int src_offset = code * kDoubleSize + double_regs_offset;
+  for (int i = 0; i < FPURegister::kMaxNumAllocatableRegisters; ++i) {
+    const FPURegister fpu_reg = FPURegister::FromAllocationIndex(i);
+    int src_offset = i * kDoubleSize + double_regs_offset;
     __ ldc1(fpu_reg, MemOperand(a1, src_offset));
   }
 
index 36eb821c0aa0cebd59ee6bc9f6e6b9fa5a8fde8f..9e45868f8ed67c69814b94a765a303adeba2eafd 100644 (file)
@@ -96,7 +96,7 @@ void LCodeGen::SaveCallerDoubles() {
   BitVector* doubles = chunk()->allocated_double_registers();
   BitVector::Iterator save_iterator(doubles);
   while (!save_iterator.Done()) {
-    __ sdc1(DoubleRegister::from_code(save_iterator.Current()),
+    __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
             MemOperand(sp, count * kDoubleSize));
     save_iterator.Advance();
     count++;
@@ -112,7 +112,7 @@ void LCodeGen::RestoreCallerDoubles() {
   BitVector::Iterator save_iterator(doubles);
   int count = 0;
   while (!save_iterator.Done()) {
-    __ ldc1(DoubleRegister::from_code(save_iterator.Current()),
+    __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
             MemOperand(sp, count * kDoubleSize));
     save_iterator.Advance();
     count++;
@@ -403,12 +403,12 @@ bool LCodeGen::GenerateSafepointTable() {
 
 
 Register LCodeGen::ToRegister(int index) const {
-  return Register::from_code(index);
+  return Register::FromAllocationIndex(index);
 }
 
 
 DoubleRegister LCodeGen::ToDoubleRegister(int index) const {
-  return DoubleRegister::from_code(index);
+  return DoubleRegister::FromAllocationIndex(index);
 }
 
 
index cafa4cfdbc22858b42e26a15b36f161aef7722dc..42ecab4b8e3c205724760b97bf5bfbd269c0d7a8 100644 (file)
@@ -451,13 +451,14 @@ LPlatformChunk* LChunkBuilder::Build() {
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
-  return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
+                                  Register::ToAllocationIndex(reg));
 }
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(DoubleRegister reg) {
-  return new (zone())
-      LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
+                                  DoubleRegister::ToAllocationIndex(reg));
 }
 
 
index 6b078f2f2ae1499b1175e4a9019e245eebebe3d3..e66fad9092c7a1e62f74c35e44308a29d7573a28 100644 (file)
@@ -14,7 +14,6 @@
 #include "src/cpu-profiler.h"
 #include "src/debug/debug.h"
 #include "src/mips/macro-assembler-mips.h"
-#include "src/register-configuration.h"
 #include "src/runtime/runtime.h"
 
 namespace v8 {
@@ -148,7 +147,7 @@ MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) {
 MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) {
   UNIMPLEMENTED_MIPS();
   // General purpose registers are pushed last on the stack.
-  int doubles_size = DoubleRegister::kMaxNumRegisters * kDoubleSize;
+  int doubles_size = FPURegister::NumAllocatableRegisters() * kDoubleSize;
   int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
   return MemOperand(sp, doubles_size + register_offset);
 }
@@ -3683,7 +3682,7 @@ void MacroAssembler::CopyFields(Register dst,
   // Find a temp register in temps list.
   for (int i = 0; i < kNumRegisters; i++) {
     if ((temps & (1 << i)) != 0) {
-      tmp.reg_code = i;
+      tmp.code_ = i;
       break;
     }
   }
@@ -5772,10 +5771,8 @@ Register GetRegisterThatIsNotOneOf(Register reg1,
   if (reg5.is_valid()) regs |= reg5.bit();
   if (reg6.is_valid()) regs |= reg6.bit();
 
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_general_registers(); ++i) {
-    int code = config->GetAllocatableGeneralCode(i);
-    Register candidate = Register::from_code(code);
+  for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
+    Register candidate = Register::FromAllocationIndex(i);
     if (regs & candidate.bit()) continue;
     return candidate;
   }
index a6a474e7bcad445349ce13d6f45e8f929b534cfa..1b715a3a732892a98111aceb0e7d594c1060314b 100644 (file)
@@ -13,17 +13,17 @@ namespace v8 {
 namespace internal {
 
 // Give alias names to registers for calling conventions.
-const Register kReturnRegister0 = {Register::kCode_v0};
-const Register kReturnRegister1 = {Register::kCode_v1};
-const Register kJSFunctionRegister = {Register::kCode_a1};
+const Register kReturnRegister0 = {kRegister_v0_Code};
+const Register kReturnRegister1 = {kRegister_v1_Code};
+const Register kJSFunctionRegister = {kRegister_a1_Code};
 const Register kContextRegister = {Register::kCpRegister};
-const Register kInterpreterAccumulatorRegister = {Register::kCode_v0};
-const Register kInterpreterRegisterFileRegister = {Register::kCode_t3};
-const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_t4};
-const Register kInterpreterBytecodeArrayRegister = {Register::kCode_t5};
-const Register kInterpreterDispatchTableRegister = {Register::kCode_t6};
-const Register kRuntimeCallFunctionRegister = {Register::kCode_a1};
-const Register kRuntimeCallArgCountRegister = {Register::kCode_a0};
+const Register kInterpreterAccumulatorRegister = {kRegister_v0_Code};
+const Register kInterpreterRegisterFileRegister = {kRegister_t3_Code};
+const Register kInterpreterBytecodeOffsetRegister = {kRegister_t4_Code};
+const Register kInterpreterBytecodeArrayRegister = {kRegister_t5_Code};
+const Register kInterpreterDispatchTableRegister = {kRegister_t6_Code};
+const Register kRuntimeCallFunctionRegister = {kRegister_a1_Code};
+const Register kRuntimeCallArgCountRegister = {kRegister_a0_Code};
 
 // Forward declaration.
 class JumpTarget;
index cb41c9f65a48ab98cc1c97ddd1ec41fcaa9d2047..16ca33a9f3440c6de6a40f2d266c2eecf21af456 100644 (file)
@@ -84,6 +84,36 @@ bool Operand::is_reg() const {
 }
 
 
+int Register::NumAllocatableRegisters() {
+    return kMaxNumAllocatableRegisters;
+}
+
+
+int DoubleRegister::NumRegisters() {
+    return FPURegister::kMaxNumRegisters;
+}
+
+
+int DoubleRegister::NumAllocatableRegisters() {
+    return FPURegister::kMaxNumAllocatableRegisters;
+}
+
+
+int DoubleRegister::NumAllocatableAliasedRegisters() {
+  return NumAllocatableRegisters();
+}
+
+
+int FPURegister::ToAllocationIndex(FPURegister reg) {
+  DCHECK(reg.code() % 2 == 0);
+  DCHECK(reg.code() / 2 < kMaxNumAllocatableRegisters);
+  DCHECK(reg.is_valid());
+  DCHECK(!reg.is(kDoubleRegZero));
+  DCHECK(!reg.is(kLithiumScratchDouble));
+  return (reg.code() / 2);
+}
+
+
 // -----------------------------------------------------------------------------
 // RelocInfo.
 
index d5acd8d95560f73e7f0d8a62a4ffe87b705a2f9b..cb5e164ff9ce3fae978c5250fbffacea82da7d68 100644 (file)
@@ -64,6 +64,28 @@ static unsigned CpuFeaturesImpliedByCompiler() {
 }
 
 
+const char* DoubleRegister::AllocationIndexToString(int index) {
+  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+  const char* const names[] = {
+    "f0",
+    "f2",
+    "f4",
+    "f6",
+    "f8",
+    "f10",
+    "f12",
+    "f14",
+    "f16",
+    "f18",
+    "f20",
+    "f22",
+    "f24",
+    "f26"
+  };
+  return names[index];
+}
+
+
 void CpuFeatures::ProbeImpl(bool cross_compile) {
   supported_ |= CpuFeaturesImpliedByCompiler();
 
@@ -207,31 +229,31 @@ MemOperand::MemOperand(Register rm, int32_t unit, int32_t multiplier,
 static const int kNegOffset = 0x00008000;
 // daddiu(sp, sp, 8) aka Pop() operation or part of Pop(r)
 // operations as post-increment of sp.
-const Instr kPopInstruction = DADDIU | (Register::kCode_sp << kRsShift) |
-                              (Register::kCode_sp << kRtShift) |
-                              (kPointerSize & kImm16Mask);  // NOLINT
+const Instr kPopInstruction = DADDIU | (kRegister_sp_Code << kRsShift)
+      | (kRegister_sp_Code << kRtShift)
+      | (kPointerSize & kImm16Mask);  // NOLINT
 // daddiu(sp, sp, -8) part of Push(r) operation as pre-decrement of sp.
-const Instr kPushInstruction = DADDIU | (Register::kCode_sp << kRsShift) |
-                               (Register::kCode_sp << kRtShift) |
-                               (-kPointerSize & kImm16Mask);  // NOLINT
+const Instr kPushInstruction = DADDIU | (kRegister_sp_Code << kRsShift)
+      | (kRegister_sp_Code << kRtShift)
+      | (-kPointerSize & kImm16Mask);  // NOLINT
 // sd(r, MemOperand(sp, 0))
-const Instr kPushRegPattern =
-    SD | (Register::kCode_sp << kRsShift) | (0 & kImm16Mask);  // NOLINT
+const Instr kPushRegPattern = SD | (kRegister_sp_Code << kRsShift)
+      |  (0 & kImm16Mask);  // NOLINT
 //  ld(r, MemOperand(sp, 0))
-const Instr kPopRegPattern =
-    LD | (Register::kCode_sp << kRsShift) | (0 & kImm16Mask);  // NOLINT
+const Instr kPopRegPattern = LD | (kRegister_sp_Code << kRsShift)
+      |  (0 & kImm16Mask);  // NOLINT
 
-const Instr kLwRegFpOffsetPattern =
-    LW | (Register::kCode_fp << kRsShift) | (0 & kImm16Mask);  // NOLINT
+const Instr kLwRegFpOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
+      |  (0 & kImm16Mask);  // NOLINT
 
-const Instr kSwRegFpOffsetPattern =
-    SW | (Register::kCode_fp << kRsShift) | (0 & kImm16Mask);  // NOLINT
+const Instr kSwRegFpOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
+      |  (0 & kImm16Mask);  // NOLINT
 
-const Instr kLwRegFpNegOffsetPattern = LW | (Register::kCode_fp << kRsShift) |
-                                       (kNegOffset & kImm16Mask);  // NOLINT
+const Instr kLwRegFpNegOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
+      |  (kNegOffset & kImm16Mask);  // NOLINT
 
-const Instr kSwRegFpNegOffsetPattern = SW | (Register::kCode_fp << kRsShift) |
-                                       (kNegOffset & kImm16Mask);  // NOLINT
+const Instr kSwRegFpNegOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
+      |  (kNegOffset & kImm16Mask);  // NOLINT
 // A mask for the Rt register for push, pop, lw, sw instructions.
 const Instr kRtMask = kRtFieldMask;
 const Instr kLwSwInstrTypeMask = 0xffe00000;
@@ -292,21 +314,21 @@ void Assembler::CodeTargetAlign() {
 
 Register Assembler::GetRtReg(Instr instr) {
   Register rt;
-  rt.reg_code = (instr & kRtFieldMask) >> kRtShift;
+  rt.code_ = (instr & kRtFieldMask) >> kRtShift;
   return rt;
 }
 
 
 Register Assembler::GetRsReg(Instr instr) {
   Register rs;
-  rs.reg_code = (instr & kRsFieldMask) >> kRsShift;
+  rs.code_ = (instr & kRsFieldMask) >> kRsShift;
   return rs;
 }
 
 
 Register Assembler::GetRdReg(Instr instr) {
   Register rd;
-  rd.reg_code = (instr & kRdFieldMask) >> kRdShift;
+  rd.code_ = (instr & kRdFieldMask) >> kRdShift;
   return rd;
 }
 
@@ -2189,14 +2211,14 @@ void Assembler::movn(Register rd, Register rs, Register rt) {
 
 void Assembler::movt(Register rd, Register rs, uint16_t cc) {
   Register rt;
-  rt.reg_code = (cc & 0x0007) << 2 | 1;
+  rt.code_ = (cc & 0x0007) << 2 | 1;
   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
 }
 
 
 void Assembler::movf(Register rd, Register rs, uint16_t cc) {
   Register rt;
-  rt.reg_code = (cc & 0x0007) << 2 | 0;
+  rt.code_ = (cc & 0x0007) << 2 | 0;
   GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
 }
 
@@ -2498,7 +2520,7 @@ void Assembler::movz_d(FPURegister fd, FPURegister fs, Register rt) {
 void Assembler::movt_s(FPURegister fd, FPURegister fs, uint16_t cc) {
   DCHECK(kArchVariant == kMips64r2);
   FPURegister ft;
-  ft.reg_code = (cc & 0x0007) << 2 | 1;
+  ft.code_ = (cc & 0x0007) << 2 | 1;
   GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
 }
 
@@ -2506,7 +2528,7 @@ void Assembler::movt_s(FPURegister fd, FPURegister fs, uint16_t cc) {
 void Assembler::movt_d(FPURegister fd, FPURegister fs, uint16_t cc) {
   DCHECK(kArchVariant == kMips64r2);
   FPURegister ft;
-  ft.reg_code = (cc & 0x0007) << 2 | 1;
+  ft.code_ = (cc & 0x0007) << 2 | 1;
   GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
 }
 
@@ -2514,7 +2536,7 @@ void Assembler::movt_d(FPURegister fd, FPURegister fs, uint16_t cc) {
 void Assembler::movf_s(FPURegister fd, FPURegister fs, uint16_t cc) {
   DCHECK(kArchVariant == kMips64r2);
   FPURegister ft;
-  ft.reg_code = (cc & 0x0007) << 2 | 0;
+  ft.code_ = (cc & 0x0007) << 2 | 0;
   GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
 }
 
@@ -2522,7 +2544,7 @@ void Assembler::movf_s(FPURegister fd, FPURegister fs, uint16_t cc) {
 void Assembler::movf_d(FPURegister fd, FPURegister fs, uint16_t cc) {
   DCHECK(kArchVariant == kMips64r2);
   FPURegister ft;
-  ft.reg_code = (cc & 0x0007) << 2 | 0;
+  ft.code_ = (cc & 0x0007) << 2 | 0;
   GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
 }
 
index 074827e53e5ad6084a6045c2c26c27512b46509d..2036aa796397f05009804038c2e504659fa24b8e 100644 (file)
 namespace v8 {
 namespace internal {
 
-// clang-format off
-#define GENERAL_REGISTERS(V)                              \
-  V(zero_reg)  V(at)  V(v0)  V(v1)  V(a0)  V(a1)  V(a2)  V(a3)  \
-  V(a4)  V(a5)  V(a6)  V(a7)  V(t0)  V(t1)  V(t2)  V(t3)  \
-  V(s0)  V(s1)  V(s2)  V(s3)  V(s4)  V(s5)  V(s6)  V(s7)  V(t8)  V(t9) \
-  V(k0)  V(k1)  V(gp)  V(sp)  V(fp)  V(ra)
-
-#define ALLOCATABLE_GENERAL_REGISTERS(V) \
-  V(v0)  V(v1)  V(a0)  V(a1)  V(a2)  V(a3) \
-  V(a4)  V(a5)  V(a6)  V(a7)  V(t0)  V(t1)  V(t2) V(s7)
-
-#define DOUBLE_REGISTERS(V)                               \
-  V(f0)  V(f1)  V(f2)  V(f3)  V(f4)  V(f5)  V(f6)  V(f7)  \
-  V(f8)  V(f9)  V(f10) V(f11) V(f12) V(f13) V(f14) V(f15) \
-  V(f16) V(f17) V(f18) V(f19) V(f20) V(f21) V(f22) V(f23) \
-  V(f24) V(f25) V(f26) V(f27) V(f28) V(f29) V(f30) V(f31)
-
-#define ALLOCATABLE_DOUBLE_REGISTERS(V)                   \
-  V(f0)  V(f2)  V(f4)  V(f6)  V(f8)  V(f10) V(f12) V(f14) \
-  V(f16) V(f18) V(f20) V(f22) V(f24) V(f26)
-// clang-format on
-
 // CPU Registers.
 //
 // 1) We would prefer to use an enum, but enum values are assignment-
@@ -94,50 +72,124 @@ namespace internal {
 // -----------------------------------------------------------------------------
 // Implementation of Register and FPURegister.
 
+// Core register.
 struct Register {
+  static const int kNumRegisters = v8::internal::kNumRegisters;
+  static const int kMaxNumAllocatableRegisters = 14;  // v0 through t2 and cp.
+  static const int kSizeInBytes = 8;
   static const int kCpRegister = 23;  // cp (s7) is the 23rd register.
 
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    GENERAL_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
-
-  static const int kNumRegisters = Code::kAfterLast;
+  inline static int NumAllocatableRegisters();
+
+  static int ToAllocationIndex(Register reg) {
+    DCHECK((reg.code() - 2) < (kMaxNumAllocatableRegisters - 1) ||
+           reg.is(from_code(kCpRegister)));
+    return reg.is(from_code(kCpRegister)) ?
+           kMaxNumAllocatableRegisters - 1 :  // Return last index for 'cp'.
+           reg.code() - 2;  // zero_reg and 'at' are skipped.
+  }
+
+  static Register FromAllocationIndex(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    return index == kMaxNumAllocatableRegisters - 1 ?
+           from_code(kCpRegister) :  // Last index is always the 'cp' register.
+           from_code(index + 2);  // zero_reg and 'at' are skipped.
+  }
+
+  static const char* AllocationIndexToString(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    const char* const names[] = {
+      "v0",
+      "v1",
+      "a0",
+      "a1",
+      "a2",
+      "a3",
+      "a4",
+      "a5",
+      "a6",
+      "a7",
+      "t0",
+      "t1",
+      "t2",
+      "s7",
+    };
+    return names[index];
+  }
 
   static Register from_code(int code) {
-    DCHECK(code >= 0);
-    DCHECK(code < kNumRegisters);
     Register r = { code };
     return r;
   }
 
-  const char* ToString();
-  bool IsAllocatable() const;
-  bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
-  bool is(Register reg) const { return reg_code == reg.reg_code; }
+  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
+  bool is(Register reg) const { return code_ == reg.code_; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
     DCHECK(is_valid());
-    return 1 << reg_code;
+    return 1 << code_;
   }
 
   // Unfortunately we can't make this private in a struct.
-  int reg_code;
+  int code_;
 };
 
-// s7: context register
-// s3: lithium scratch
-// s4: lithium scratch2
-#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
-GENERAL_REGISTERS(DECLARE_REGISTER)
-#undef DECLARE_REGISTER
-const Register no_reg = {Register::kCode_no_reg};
+#define REGISTER(N, C) \
+  const int kRegister_ ## N ## _Code = C; \
+  const Register N = { C }
+
+REGISTER(no_reg, -1);
+// Always zero.
+REGISTER(zero_reg, 0);
+// at: Reserved for synthetic instructions.
+REGISTER(at, 1);
+// v0, v1: Used when returning multiple values from subroutines.
+REGISTER(v0, 2);
+REGISTER(v1, 3);
+// a0 - a4: Used to pass non-FP parameters.
+REGISTER(a0, 4);
+REGISTER(a1, 5);
+REGISTER(a2, 6);
+REGISTER(a3, 7);
+// a4 - a7 t0 - t3: Can be used without reservation, act as temporary registers
+// and are allowed to be destroyed by subroutines.
+REGISTER(a4, 8);
+REGISTER(a5, 9);
+REGISTER(a6, 10);
+REGISTER(a7, 11);
+REGISTER(t0, 12);
+REGISTER(t1, 13);
+REGISTER(t2, 14);
+REGISTER(t3, 15);
+// s0 - s7: Subroutine register variables. Subroutines that write to these
+// registers must restore their values before exiting so that the caller can
+// expect the values to be preserved.
+REGISTER(s0, 16);
+REGISTER(s1, 17);
+REGISTER(s2, 18);
+REGISTER(s3, 19);
+REGISTER(s4, 20);
+REGISTER(s5, 21);
+REGISTER(s6, 22);
+REGISTER(s7, 23);
+REGISTER(t8, 24);
+REGISTER(t9, 25);
+// k0, k1: Reserved for system calls and interrupt handlers.
+REGISTER(k0, 26);
+REGISTER(k1, 27);
+// gp: Reserved.
+REGISTER(gp, 28);
+// sp: Stack pointer.
+REGISTER(sp, 29);
+// fp: Frame pointer.
+REGISTER(fp, 30);
+// ra: Return address pointer.
+REGISTER(ra, 31);
+
+#undef REGISTER
 
 
 int ToNumber(Register reg);
@@ -145,72 +197,77 @@ int ToNumber(Register reg);
 Register ToRegister(int num);
 
 // Coprocessor register.
-struct DoubleRegister {
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    DOUBLE_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
-
-  static const int kMaxNumRegisters = Code::kAfterLast;
-
-  inline static int NumRegisters();
+struct FPURegister {
+  static const int kMaxNumRegisters = v8::internal::kNumFPURegisters;
 
   // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers
   // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to
   // number of Double regs (64-bit regs, or FPU-reg-pairs).
 
-  const char* ToString();
-  bool IsAllocatable() const;
-  bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
-  bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
-  DoubleRegister low() const {
+  // A few double registers are reserved: one as a scratch register and one to
+  // hold 0.0.
+  //  f28: 0.0
+  //  f30: scratch register.
+  static const int kNumReservedRegisters = 2;
+  static const int kMaxNumAllocatableRegisters = kMaxNumRegisters / 2 -
+      kNumReservedRegisters;
+
+  inline static int NumRegisters();
+  inline static int NumAllocatableRegisters();
+
+  // TODO(turbofan): Proper support for float32.
+  inline static int NumAllocatableAliasedRegisters();
+
+  inline static int ToAllocationIndex(FPURegister reg);
+  static const char* AllocationIndexToString(int index);
+
+  static FPURegister FromAllocationIndex(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    return from_code(index * 2);
+  }
+
+  static FPURegister from_code(int code) {
+    FPURegister r = { code };
+    return r;
+  }
+
+  bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters ; }
+  bool is(FPURegister creg) const { return code_ == creg.code_; }
+  FPURegister low() const {
     // TODO(plind): Create DCHECK for FR=0 mode. This usage suspect for FR=1.
     // Find low reg of a Double-reg pair, which is the reg itself.
-    DCHECK(reg_code % 2 == 0);  // Specified Double reg must be even.
-    DoubleRegister reg;
-    reg.reg_code = reg_code;
+    DCHECK(code_ % 2 == 0);  // Specified Double reg must be even.
+    FPURegister reg;
+    reg.code_ = code_;
     DCHECK(reg.is_valid());
     return reg;
   }
-  DoubleRegister high() const {
+  FPURegister high() const {
     // TODO(plind): Create DCHECK for FR=0 mode. This usage illegal in FR=1.
     // Find high reg of a Doubel-reg pair, which is reg + 1.
-    DCHECK(reg_code % 2 == 0);  // Specified Double reg must be even.
-    DoubleRegister reg;
-    reg.reg_code = reg_code + 1;
+    DCHECK(code_ % 2 == 0);  // Specified Double reg must be even.
+    FPURegister reg;
+    reg.code_ = code_ + 1;
     DCHECK(reg.is_valid());
     return reg;
   }
 
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
     DCHECK(is_valid());
-    return 1 << reg_code;
-  }
-
-  static DoubleRegister from_code(int code) {
-    DoubleRegister r = {code};
-    return r;
+    return 1 << code_;
   }
   void setcode(int f) {
-    reg_code = f;
+    code_ = f;
     DCHECK(is_valid());
   }
   // Unfortunately we can't make this private in a struct.
-  int reg_code;
+  int code_;
 };
 
-// A few double registers are reserved: one as a scratch register and one to
-// hold 0.0.
-//  f28: 0.0
-//  f30: scratch register.
-
 // V8 now supports the O32 ABI, and the FPU Registers are organized as 32
 // 32-bit registers, f0 through f31. When used as 'double' they are used
 // in pairs, starting with the even numbered register. So a double operation
@@ -220,43 +277,43 @@ struct DoubleRegister {
 // but it is not in common use. Someday we will want to support this in v8.)
 
 // For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers.
-typedef DoubleRegister FPURegister;
-typedef DoubleRegister FloatRegister;
-
-const DoubleRegister no_freg = {-1};
-
-const DoubleRegister f0 = {0};  // Return value in hard float mode.
-const DoubleRegister f1 = {1};
-const DoubleRegister f2 = {2};
-const DoubleRegister f3 = {3};
-const DoubleRegister f4 = {4};
-const DoubleRegister f5 = {5};
-const DoubleRegister f6 = {6};
-const DoubleRegister f7 = {7};
-const DoubleRegister f8 = {8};
-const DoubleRegister f9 = {9};
-const DoubleRegister f10 = {10};
-const DoubleRegister f11 = {11};
-const DoubleRegister f12 = {12};  // Arg 0 in hard float mode.
-const DoubleRegister f13 = {13};
-const DoubleRegister f14 = {14};  // Arg 1 in hard float mode.
-const DoubleRegister f15 = {15};
-const DoubleRegister f16 = {16};
-const DoubleRegister f17 = {17};
-const DoubleRegister f18 = {18};
-const DoubleRegister f19 = {19};
-const DoubleRegister f20 = {20};
-const DoubleRegister f21 = {21};
-const DoubleRegister f22 = {22};
-const DoubleRegister f23 = {23};
-const DoubleRegister f24 = {24};
-const DoubleRegister f25 = {25};
-const DoubleRegister f26 = {26};
-const DoubleRegister f27 = {27};
-const DoubleRegister f28 = {28};
-const DoubleRegister f29 = {29};
-const DoubleRegister f30 = {30};
-const DoubleRegister f31 = {31};
+typedef FPURegister DoubleRegister;
+typedef FPURegister FloatRegister;
+
+const FPURegister no_freg = { -1 };
+
+const FPURegister f0 = { 0 };  // Return value in hard float mode.
+const FPURegister f1 = { 1 };
+const FPURegister f2 = { 2 };
+const FPURegister f3 = { 3 };
+const FPURegister f4 = { 4 };
+const FPURegister f5 = { 5 };
+const FPURegister f6 = { 6 };
+const FPURegister f7 = { 7 };
+const FPURegister f8 = { 8 };
+const FPURegister f9 = { 9 };
+const FPURegister f10 = { 10 };
+const FPURegister f11 = { 11 };
+const FPURegister f12 = { 12 };  // Arg 0 in hard float mode.
+const FPURegister f13 = { 13 };
+const FPURegister f14 = { 14 };  // Arg 1 in hard float mode.
+const FPURegister f15 = { 15 };
+const FPURegister f16 = { 16 };
+const FPURegister f17 = { 17 };
+const FPURegister f18 = { 18 };
+const FPURegister f19 = { 19 };
+const FPURegister f20 = { 20 };
+const FPURegister f21 = { 21 };
+const FPURegister f22 = { 22 };
+const FPURegister f23 = { 23 };
+const FPURegister f24 = { 24 };
+const FPURegister f25 = { 25 };
+const FPURegister f26 = { 26 };
+const FPURegister f27 = { 27 };
+const FPURegister f28 = { 28 };
+const FPURegister f29 = { 29 };
+const FPURegister f30 = { 30 };
+const FPURegister f31 = { 31 };
 
 // Register aliases.
 // cp is assumed to be a callee saved register.
@@ -276,22 +333,22 @@ const DoubleRegister f31 = {31};
 // FPU (coprocessor 1) control registers.
 // Currently only FCSR (#31) is implemented.
 struct FPUControlRegister {
-  bool is_valid() const { return reg_code == kFCSRRegister; }
-  bool is(FPUControlRegister creg) const { return reg_code == creg.reg_code; }
+  bool is_valid() const { return code_ == kFCSRRegister; }
+  bool is(FPUControlRegister creg) const { return code_ == creg.code_; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
     DCHECK(is_valid());
-    return 1 << reg_code;
+    return 1 << code_;
   }
   void setcode(int f) {
-    reg_code = f;
+    code_ = f;
     DCHECK(is_valid());
   }
   // Unfortunately we can't make this private in a struct.
-  int reg_code;
+  int code_;
 };
 
 const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister };
index 9c047efcc908a49babd4d6ad49303aaa14a6773a..958951a948ea6f10214037c464e08781b3e4bf3e 100644 (file)
@@ -5,7 +5,6 @@
 #include "src/codegen.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
-#include "src/register-configuration.h"
 #include "src/safepoint-table.h"
 
 namespace v8 {
@@ -89,7 +88,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
   }
   input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
   input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
-  for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
+  for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
     input_->SetDoubleRegister(i, 0.0);
   }
 
@@ -140,15 +139,14 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   RegList restored_regs = kJSCallerSaved | kCalleeSaved;
   RegList saved_regs = restored_regs | sp.bit() | ra.bit();
 
-  const int kDoubleRegsSize = kDoubleSize * DoubleRegister::kMaxNumRegisters;
+  const int kDoubleRegsSize =
+      kDoubleSize * FPURegister::kMaxNumAllocatableRegisters;
 
   // Save all FPU registers before messing with them.
   __ Dsubu(sp, sp, Operand(kDoubleRegsSize));
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    const DoubleRegister fpu_reg = DoubleRegister::from_code(code);
-    int offset = code * kDoubleSize;
+  for (int i = 0; i < FPURegister::kMaxNumAllocatableRegisters; ++i) {
+    FPURegister fpu_reg = FPURegister::FromAllocationIndex(i);
+    int offset = i * kDoubleSize;
     __ sdc1(fpu_reg, MemOperand(sp, offset));
   }
 
@@ -223,10 +221,9 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   int double_regs_offset = FrameDescription::double_registers_offset();
   // Copy FPU registers to
   // double_registers_[DoubleRegister::kNumAllocatableRegisters]
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    int dst_offset = code * kDoubleSize + double_regs_offset;
-    int src_offset = code * kDoubleSize + kNumberOfRegisters * kPointerSize;
+  for (int i = 0; i < FPURegister::NumAllocatableRegisters(); ++i) {
+    int dst_offset = i * kDoubleSize + double_regs_offset;
+    int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
     __ ldc1(f0, MemOperand(sp, src_offset));
     __ sdc1(f0, MemOperand(a1, dst_offset));
   }
@@ -292,10 +289,9 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   __ BranchShort(&outer_push_loop, lt, a4, Operand(a1));
 
   __ ld(a1, MemOperand(a0, Deoptimizer::input_offset()));
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    const DoubleRegister fpu_reg = DoubleRegister::from_code(code);
-    int src_offset = code * kDoubleSize + double_regs_offset;
+  for (int i = 0; i < FPURegister::kMaxNumAllocatableRegisters; ++i) {
+    const FPURegister fpu_reg = FPURegister::FromAllocationIndex(i);
+    int src_offset = i * kDoubleSize + double_regs_offset;
     __ ldc1(fpu_reg, MemOperand(a1, src_offset));
   }
 
index 22a06e8e120d2aee865791862929c04bdb772bcd..4c76551138e0801aca4b23d10a913f44561e745a 100644 (file)
@@ -71,7 +71,7 @@ void LCodeGen::SaveCallerDoubles() {
   BitVector* doubles = chunk()->allocated_double_registers();
   BitVector::Iterator save_iterator(doubles);
   while (!save_iterator.Done()) {
-    __ sdc1(DoubleRegister::from_code(save_iterator.Current()),
+    __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
             MemOperand(sp, count * kDoubleSize));
     save_iterator.Advance();
     count++;
@@ -87,7 +87,7 @@ void LCodeGen::RestoreCallerDoubles() {
   BitVector::Iterator save_iterator(doubles);
   int count = 0;
   while (!save_iterator.Done()) {
-    __ ldc1(DoubleRegister::from_code(save_iterator.Current()),
+    __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
             MemOperand(sp, count * kDoubleSize));
     save_iterator.Advance();
     count++;
@@ -386,12 +386,12 @@ bool LCodeGen::GenerateSafepointTable() {
 
 
 Register LCodeGen::ToRegister(int index) const {
-  return Register::from_code(index);
+  return Register::FromAllocationIndex(index);
 }
 
 
 DoubleRegister LCodeGen::ToDoubleRegister(int index) const {
-  return DoubleRegister::from_code(index);
+  return DoubleRegister::FromAllocationIndex(index);
 }
 
 
index 4595722fb4061775ec1b2a8bec98026ef36495e4..4f2f16152410792da707179b8b60dd61d77875ee 100644 (file)
@@ -451,13 +451,14 @@ LPlatformChunk* LChunkBuilder::Build() {
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
-  return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
+                                  Register::ToAllocationIndex(reg));
 }
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(DoubleRegister reg) {
-  return new (zone())
-      LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
+                                  DoubleRegister::ToAllocationIndex(reg));
 }
 
 
index e071a777bbfb8066b75bc6c0d41941a25aca5c3c..7a49ed0ba4a7107596ac980ce71ea607576e06cc 100644 (file)
@@ -12,7 +12,6 @@
 #include "src/cpu-profiler.h"
 #include "src/debug/debug.h"
 #include "src/mips64/macro-assembler-mips64.h"
-#include "src/register-configuration.h"
 #include "src/runtime/runtime.h"
 
 namespace v8 {
@@ -150,7 +149,7 @@ MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) {
 MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) {
   UNIMPLEMENTED_MIPS();
   // General purpose registers are pushed last on the stack.
-  int doubles_size = DoubleRegister::kMaxNumRegisters * kDoubleSize;
+  int doubles_size = FPURegister::NumAllocatableRegisters() * kDoubleSize;
   int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
   return MemOperand(sp, doubles_size + register_offset);
 }
@@ -3732,7 +3731,7 @@ void MacroAssembler::CopyFields(Register dst,
   // Find a temp register in temps list.
   for (int i = 0; i < kNumRegisters; i++) {
     if ((temps & (1 << i)) != 0) {
-      tmp.reg_code = i;
+      tmp.code_ = i;
       break;
     }
   }
@@ -5965,10 +5964,8 @@ Register GetRegisterThatIsNotOneOf(Register reg1,
   if (reg5.is_valid()) regs |= reg5.bit();
   if (reg6.is_valid()) regs |= reg6.bit();
 
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_general_registers(); ++i) {
-    int code = config->GetAllocatableGeneralCode(i);
-    Register candidate = Register::from_code(code);
+  for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
+    Register candidate = Register::FromAllocationIndex(i);
     if (regs & candidate.bit()) continue;
     return candidate;
   }
index f138179f39c1ff7dcef9dc8f7a4b852b7d0c2da3..3d1cbe35f21119323e39574babbb7c7eb9cc5227 100644 (file)
@@ -13,17 +13,17 @@ namespace v8 {
 namespace internal {
 
 // Give alias names to registers for calling conventions.
-const Register kReturnRegister0 = {Register::kCode_v0};
-const Register kReturnRegister1 = {Register::kCode_v1};
-const Register kJSFunctionRegister = {Register::kCode_a1};
-const Register kContextRegister = {Register::kCpRegister};
-const Register kInterpreterAccumulatorRegister = {Register::kCode_v0};
-const Register kInterpreterRegisterFileRegister = {Register::kCode_a7};
-const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_t0};
-const Register kInterpreterBytecodeArrayRegister = {Register::kCode_t1};
-const Register kInterpreterDispatchTableRegister = {Register::kCode_t2};
-const Register kRuntimeCallFunctionRegister = {Register::kCode_a1};
-const Register kRuntimeCallArgCountRegister = {Register::kCode_a0};
+const Register kReturnRegister0 = {kRegister_v0_Code};
+const Register kReturnRegister1 = {kRegister_v1_Code};
+const Register kJSFunctionRegister = {kRegister_a1_Code};
+const Register kContextRegister = {kRegister_s7_Code};
+const Register kInterpreterAccumulatorRegister = {kRegister_v0_Code};
+const Register kInterpreterRegisterFileRegister = {kRegister_a7_Code};
+const Register kInterpreterBytecodeOffsetRegister = {kRegister_t0_Code};
+const Register kInterpreterBytecodeArrayRegister = {kRegister_t1_Code};
+const Register kInterpreterDispatchTableRegister = {kRegister_t2_Code};
+const Register kRuntimeCallFunctionRegister = {kRegister_a1_Code};
+const Register kRuntimeCallArgCountRegister = {kRegister_a0_Code};
 
 // Forward declaration.
 class JumpTarget;
index 626ae77ce298ffff423c05d6ada0aff2267857ba..3e88c961eef0756bc54e58bbae3d0a2076beebd2 100644 (file)
@@ -12162,7 +12162,7 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(
 
         case Translation::DOUBLE_REGISTER: {
           int reg_code = iterator.Next();
-          os << "{input=" << DoubleRegister::from_code(reg_code).ToString()
+          os << "{input=" << DoubleRegister::AllocationIndexToString(reg_code)
              << "}";
           break;
         }
diff --git a/src/register-configuration.cc b/src/register-configuration.cc
deleted file mode 100644 (file)
index 9b1c951..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/register-configuration.h"
-#include "src/globals.h"
-#include "src/macro-assembler.h"
-
-namespace v8 {
-namespace internal {
-
-namespace {
-
-#define REGISTER_COUNT(R) 1 +
-static const int kMaxAllocatableGeneralRegisterCount =
-    ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT)0;
-static const int kMaxAllocatableDoubleRegisterCount =
-    ALLOCATABLE_DOUBLE_REGISTERS(REGISTER_COUNT)0;
-
-static const char* const kGeneralRegisterNames[] = {
-#define REGISTER_NAME(R) #R,
-    GENERAL_REGISTERS(REGISTER_NAME)
-#undef REGISTER_NAME
-};
-
-static const char* const kDoubleRegisterNames[] = {
-#define REGISTER_NAME(R) #R,
-    DOUBLE_REGISTERS(REGISTER_NAME)
-#undef REGISTER_NAME
-};
-
-STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
-              Register::kNumRegisters);
-STATIC_ASSERT(RegisterConfiguration::kMaxDoubleRegisters >=
-              DoubleRegister::kMaxNumRegisters);
-
-class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
- public:
-  ArchDefaultRegisterConfiguration()
-      : RegisterConfiguration(
-            Register::kNumRegisters, DoubleRegister::kMaxNumRegisters,
-#if V8_TARGET_ARCH_IA32
-            kMaxAllocatableGeneralRegisterCount,
-            kMaxAllocatableDoubleRegisterCount,
-            kMaxAllocatableDoubleRegisterCount,
-#elif V8_TARGET_ARCH_X87
-            kMaxAllocatableGeneralRegisterCount, 1, 1,
-#elif V8_TARGET_ARCH_X64
-            kMaxAllocatableGeneralRegisterCount,
-            kMaxAllocatableDoubleRegisterCount,
-            kMaxAllocatableDoubleRegisterCount,
-#elif V8_TARGET_ARCH_ARM
-            FLAG_enable_embedded_constant_pool
-                ? (kMaxAllocatableGeneralRegisterCount - 1)
-                : kMaxAllocatableGeneralRegisterCount,
-            CpuFeatures::IsSupported(VFP32DREGS)
-                ? kMaxAllocatableDoubleRegisterCount
-                : (ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(REGISTER_COUNT)0),
-            ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(REGISTER_COUNT)0,
-#elif V8_TARGET_ARCH_ARM64
-            kMaxAllocatableGeneralRegisterCount,
-            kMaxAllocatableDoubleRegisterCount,
-            kMaxAllocatableDoubleRegisterCount,
-#elif V8_TARGET_ARCH_MIPS
-            kMaxAllocatableGeneralRegisterCount,
-            kMaxAllocatableDoubleRegisterCount,
-            kMaxAllocatableDoubleRegisterCount,
-#elif V8_TARGET_ARCH_MIPS64
-            kMaxAllocatableGeneralRegisterCount,
-            kMaxAllocatableDoubleRegisterCount,
-            kMaxAllocatableDoubleRegisterCount,
-#else
-            GetAllocatableGeneralRegisterCount(),
-            GetAllocatableDoubleRegisterCount(),
-            GetAllocatableAliasedDoubleRegisterCount(),
-#endif
-            GetAllocatableGeneralCodes(), GetAllocatableDoubleCodes(),
-            kGeneralRegisterNames, kDoubleRegisterNames) {
-  }
-
-  const char* general_register_name_table_[Register::kNumRegisters];
-  const char* double_register_name_table_[DoubleRegister::kMaxNumRegisters];
-
- private:
-  friend struct Register;
-  friend struct DoubleRegister;
-
-  static const int* GetAllocatableGeneralCodes() {
-#define REGISTER_CODE(R) Register::kCode_##R,
-    static const int general_codes[] = {
-        ALLOCATABLE_GENERAL_REGISTERS(REGISTER_CODE)};
-#undef REGISTER_CODE
-    return general_codes;
-  }
-
-  static const int* GetAllocatableDoubleCodes() {
-#define REGISTER_CODE(R) DoubleRegister::kCode_##R,
-    static const int double_codes[] = {
-        ALLOCATABLE_DOUBLE_REGISTERS(REGISTER_CODE)};
-#undef REGISTER_CODE
-    return double_codes;
-  }
-};
-
-
-static base::LazyInstance<ArchDefaultRegisterConfiguration>::type
-    kDefaultRegisterConfiguration = LAZY_INSTANCE_INITIALIZER;
-
-}  // namespace
-
-
-const RegisterConfiguration* RegisterConfiguration::ArchDefault() {
-  return &kDefaultRegisterConfiguration.Get();
-}
-
-RegisterConfiguration::RegisterConfiguration(
-    int num_general_registers, int num_double_registers,
-    int num_allocatable_general_registers, int num_allocatable_double_registers,
-    int num_allocatable_aliased_double_registers,
-    const int* allocatable_general_codes, const int* allocatable_double_codes,
-    const char* const* general_register_names,
-    const char* const* double_register_names)
-    : num_general_registers_(num_general_registers),
-      num_double_registers_(num_double_registers),
-      num_allocatable_general_registers_(num_allocatable_general_registers),
-      num_allocatable_double_registers_(num_allocatable_double_registers),
-      num_allocatable_aliased_double_registers_(
-          num_allocatable_aliased_double_registers),
-      allocatable_general_codes_mask_(0),
-      allocatable_double_codes_mask_(0),
-      allocatable_general_codes_(allocatable_general_codes),
-      allocatable_double_codes_(allocatable_double_codes),
-      general_register_names_(general_register_names),
-      double_register_names_(double_register_names) {
-  for (int i = 0; i < num_allocatable_general_registers_; ++i) {
-    allocatable_general_codes_mask_ |= (1 << allocatable_general_codes_[i]);
-  }
-  for (int i = 0; i < num_allocatable_double_registers_; ++i) {
-    allocatable_double_codes_mask_ |= (1 << allocatable_double_codes_[i]);
-  }
-}
-
-#undef REGISTER_COUNT
-
-}  // namespace internal
-}  // namespace v8
diff --git a/src/register-configuration.h b/src/register-configuration.h
deleted file mode 100644 (file)
index f12bc7c..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_REGISTER_CONFIGURATION_H_
-#define V8_COMPILER_REGISTER_CONFIGURATION_H_
-
-#include "src/base/macros.h"
-
-namespace v8 {
-namespace internal {
-
-// An architecture independent representation of the sets of registers available
-// for instruction creation.
-class RegisterConfiguration {
- public:
-  // Architecture independent maxes.
-  static const int kMaxGeneralRegisters = 32;
-  static const int kMaxDoubleRegisters = 32;
-
-  static const RegisterConfiguration* ArchDefault();
-
-  RegisterConfiguration(int num_general_registers, int num_double_registers,
-                        int num_allocatable_general_registers,
-                        int num_allocatable_double_registers,
-                        int num_allocatable_aliased_double_registers,
-                        const int* allocatable_general_codes,
-                        const int* allocatable_double_codes,
-                        char const* const* general_names,
-                        char const* const* double_names);
-
-  int num_general_registers() const { return num_general_registers_; }
-  int num_double_registers() const { return num_double_registers_; }
-  int num_allocatable_general_registers() const {
-    return num_allocatable_general_registers_;
-  }
-  int num_allocatable_double_registers() const {
-    return num_allocatable_double_registers_;
-  }
-  // TODO(turbofan): This is a temporary work-around required because our
-  // register allocator does not yet support the aliasing of single/double
-  // registers on ARM.
-  int num_allocatable_aliased_double_registers() const {
-    return num_allocatable_aliased_double_registers_;
-  }
-  int32_t allocatable_general_codes_mask() const {
-    return allocatable_general_codes_mask_;
-  }
-  int32_t allocatable_double_codes_mask() const {
-    return allocatable_double_codes_mask_;
-  }
-  int GetAllocatableGeneralCode(int index) const {
-    return allocatable_general_codes_[index];
-  }
-  int GetAllocatableDoubleCode(int index) const {
-    return allocatable_double_codes_[index];
-  }
-  const char* GetGeneralRegisterName(int code) const {
-    return general_register_names_[code];
-  }
-  const char* GetDoubleRegisterName(int code) const {
-    return double_register_names_[code];
-  }
-  const int* allocatable_general_codes() const {
-    return allocatable_general_codes_;
-  }
-  const int* allocatable_double_codes() const {
-    return allocatable_double_codes_;
-  }
-
- private:
-  const int num_general_registers_;
-  const int num_double_registers_;
-  int num_allocatable_general_registers_;
-  int num_allocatable_double_registers_;
-  int num_allocatable_aliased_double_registers_;
-  int32_t allocatable_general_codes_mask_;
-  int32_t allocatable_double_codes_mask_;
-  const int* allocatable_general_codes_;
-  const int* allocatable_double_codes_;
-  char const* const* general_register_names_;
-  char const* const* double_register_names_;
-};
-
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_COMPILER_REGISTER_CONFIGURATION_H_
index 059b576beaa42d52765c8b383762199a0a14e392..cb93ab878b9517a1348d32df1914fa9cff856f65 100644 (file)
@@ -115,6 +115,20 @@ void CpuFeatures::PrintFeatures() {
 }
 
 
+// -----------------------------------------------------------------------------
+// Register constants.
+
+const int
+    Register::kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters] = {
+  // rax, rbx, rdx, rcx, rsi, rdi, r8, r9, r11, r12, r14, r15
+  0, 3, 2, 1, 6, 7, 8, 9, 11, 12, 14, 15
+};
+
+const int Register::kAllocationIndexByRegisterCode[kNumRegisters] = {
+  0, 3, 2, 1, -1, -1, 4, 5, 6, 7, -1, 8, 9, -1, 10, 11
+};
+
+
 // -----------------------------------------------------------------------------
 // Implementation of Operand
 
index d5e855c8478c197b00e27b149ecbeea5aac9eb52..47e4d2bddae310469a02e4a93c7e6681bbdad0ab 100644 (file)
@@ -47,39 +47,6 @@ namespace internal {
 
 // Utility functions
 
-#define GENERAL_REGISTERS(V) \
-  V(rax)                     \
-  V(rcx)                     \
-  V(rdx)                     \
-  V(rbx)                     \
-  V(rsp)                     \
-  V(rbp)                     \
-  V(rsi)                     \
-  V(rdi)                     \
-  V(r8)                      \
-  V(r9)                      \
-  V(r10)                     \
-  V(r11)                     \
-  V(r12)                     \
-  V(r13)                     \
-  V(r14)                     \
-  V(r15)
-
-#define ALLOCATABLE_GENERAL_REGISTERS(V) \
-  V(rax)                                 \
-  V(rbx)                                 \
-  V(rdx)                                 \
-  V(rcx)                                 \
-  V(rsi)                                 \
-  V(rdi)                                 \
-  V(r8)                                  \
-  V(r9)                                  \
-  V(r11)                                 \
-  V(r12)                                 \
-  V(r14)                                 \
-  V(r15)
-
-
 // CPU Registers.
 //
 // 1) We would prefer to use an enum, but enum values are assignment-
@@ -101,153 +68,226 @@ namespace internal {
 // mode. This way we get the compile-time error checking in debug mode
 // and best performance in optimized code.
 //
+
 struct Register {
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    GENERAL_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
+  // The non-allocatable registers are:
+  //  rsp - stack pointer
+  //  rbp - frame pointer
+  //  r10 - fixed scratch register
+  //  r13 - root register
+  static const int kMaxNumAllocatableRegisters = 12;
+  static int NumAllocatableRegisters() {
+    return kMaxNumAllocatableRegisters;
+  }
+  static const int kNumRegisters = 16;
+
+  static int ToAllocationIndex(Register reg) {
+    return kAllocationIndexByRegisterCode[reg.code()];
+  }
+
+  static Register FromAllocationIndex(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    Register result = { kRegisterCodeByAllocationIndex[index] };
+    return result;
+  }
 
-  static const int kNumRegisters = Code::kAfterLast;
+  static const char* AllocationIndexToString(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    const char* const names[] = {
+      "rax",
+      "rbx",
+      "rdx",
+      "rcx",
+      "rsi",
+      "rdi",
+      "r8",
+      "r9",
+      "r11",
+      "r12",
+      "r14",
+      "r15"
+    };
+    return names[index];
+  }
 
   static Register from_code(int code) {
-    DCHECK(code >= 0);
-    DCHECK(code < kNumRegisters);
-    Register r = {code};
+    Register r = { code };
     return r;
   }
-  const char* ToString();
-  bool IsAllocatable() const;
-  bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
-  bool is(Register reg) const { return reg_code == reg.reg_code; }
+  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
+  bool is(Register reg) const { return code_ == reg.code_; }
+  // rax, rbx, rcx and rdx are byte registers, the rest are not.
+  bool is_byte_register() const { return code_ <= 3; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
   int bit() const {
-    DCHECK(is_valid());
-    return 1 << reg_code;
+    return 1 << code_;
   }
 
-  bool is_byte_register() const { return reg_code <= 3; }
   // Return the high bit of the register code as a 0 or 1.  Used often
   // when constructing the REX prefix byte.
-  int high_bit() const { return reg_code >> 3; }
+  int high_bit() const {
+    return code_ >> 3;
+  }
   // Return the 3 low bits of the register code.  Used when encoding registers
   // in modR/M, SIB, and opcode bytes.
-  int low_bits() const { return reg_code & 0x7; }
+  int low_bits() const {
+    return code_ & 0x7;
+  }
 
   // Unfortunately we can't make this private in a struct when initializing
   // by assignment.
-  int reg_code;
-};
-
+  int code_;
 
-#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
-GENERAL_REGISTERS(DECLARE_REGISTER)
-#undef DECLARE_REGISTER
-const Register no_reg = {Register::kCode_no_reg};
+ private:
+  static const int kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters];
+  static const int kAllocationIndexByRegisterCode[kNumRegisters];
+};
 
+const int kRegister_rax_Code = 0;
+const int kRegister_rcx_Code = 1;
+const int kRegister_rdx_Code = 2;
+const int kRegister_rbx_Code = 3;
+const int kRegister_rsp_Code = 4;
+const int kRegister_rbp_Code = 5;
+const int kRegister_rsi_Code = 6;
+const int kRegister_rdi_Code = 7;
+const int kRegister_r8_Code = 8;
+const int kRegister_r9_Code = 9;
+const int kRegister_r10_Code = 10;
+const int kRegister_r11_Code = 11;
+const int kRegister_r12_Code = 12;
+const int kRegister_r13_Code = 13;
+const int kRegister_r14_Code = 14;
+const int kRegister_r15_Code = 15;
+const int kRegister_no_reg_Code = -1;
+
+const Register rax = { kRegister_rax_Code };
+const Register rcx = { kRegister_rcx_Code };
+const Register rdx = { kRegister_rdx_Code };
+const Register rbx = { kRegister_rbx_Code };
+const Register rsp = { kRegister_rsp_Code };
+const Register rbp = { kRegister_rbp_Code };
+const Register rsi = { kRegister_rsi_Code };
+const Register rdi = { kRegister_rdi_Code };
+const Register r8 = { kRegister_r8_Code };
+const Register r9 = { kRegister_r9_Code };
+const Register r10 = { kRegister_r10_Code };
+const Register r11 = { kRegister_r11_Code };
+const Register r12 = { kRegister_r12_Code };
+const Register r13 = { kRegister_r13_Code };
+const Register r14 = { kRegister_r14_Code };
+const Register r15 = { kRegister_r15_Code };
+const Register no_reg = { kRegister_no_reg_Code };
 
 #ifdef _WIN64
   // Windows calling convention
-const Register arg_reg_1 = {Register::kCode_rcx};
-const Register arg_reg_2 = {Register::kCode_rdx};
-const Register arg_reg_3 = {Register::kCode_r8};
-const Register arg_reg_4 = {Register::kCode_r9};
+  const Register arg_reg_1 = { kRegister_rcx_Code };
+  const Register arg_reg_2 = { kRegister_rdx_Code };
+  const Register arg_reg_3 = { kRegister_r8_Code };
+  const Register arg_reg_4 = { kRegister_r9_Code };
 #else
   // AMD64 calling convention
-const Register arg_reg_1 = {Register::kCode_rdi};
-const Register arg_reg_2 = {Register::kCode_rsi};
-const Register arg_reg_3 = {Register::kCode_rdx};
-const Register arg_reg_4 = {Register::kCode_rcx};
+  const Register arg_reg_1 = { kRegister_rdi_Code };
+  const Register arg_reg_2 = { kRegister_rsi_Code };
+  const Register arg_reg_3 = { kRegister_rdx_Code };
+  const Register arg_reg_4 = { kRegister_rcx_Code };
 #endif  // _WIN64
 
+struct XMMRegister {
+  static const int kMaxNumRegisters = 16;
+  static const int kMaxNumAllocatableRegisters = 15;
+  static int NumAllocatableRegisters() {
+    return kMaxNumAllocatableRegisters;
+  }
+
+  // TODO(turbofan): Proper support for float32.
+  static int NumAllocatableAliasedRegisters() {
+    return NumAllocatableRegisters();
+  }
+
+  static int ToAllocationIndex(XMMRegister reg) {
+    DCHECK(reg.code() != 0);
+    return reg.code() - 1;
+  }
 
-#define DOUBLE_REGISTERS(V) \
-  V(xmm0)                   \
-  V(xmm1)                   \
-  V(xmm2)                   \
-  V(xmm3)                   \
-  V(xmm4)                   \
-  V(xmm5)                   \
-  V(xmm6)                   \
-  V(xmm7)                   \
-  V(xmm8)                   \
-  V(xmm9)                   \
-  V(xmm10)                  \
-  V(xmm11)                  \
-  V(xmm12)                  \
-  V(xmm13)                  \
-  V(xmm14)                  \
-  V(xmm15)
-
-#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
-  V(xmm1)                               \
-  V(xmm2)                               \
-  V(xmm3)                               \
-  V(xmm4)                               \
-  V(xmm5)                               \
-  V(xmm6)                               \
-  V(xmm7)                               \
-  V(xmm8)                               \
-  V(xmm9)                               \
-  V(xmm10)                              \
-  V(xmm11)                              \
-  V(xmm12)                              \
-  V(xmm13)                              \
-  V(xmm14)                              \
-  V(xmm15)
-
-
-struct DoubleRegister {
-  enum Code {
-#define REGISTER_CODE(R) kCode_##R,
-    DOUBLE_REGISTERS(REGISTER_CODE)
-#undef REGISTER_CODE
-        kAfterLast,
-    kCode_no_reg = -1
-  };
-
-  static const int kMaxNumRegisters = Code::kAfterLast;
-
-  static DoubleRegister from_code(int code) {
-    DoubleRegister result = {code};
+  static XMMRegister FromAllocationIndex(int index) {
+    DCHECK(0 <= index && index < kMaxNumAllocatableRegisters);
+    XMMRegister result = { index + 1 };
     return result;
   }
 
-  const char* ToString();
-  bool IsAllocatable() const;
-  bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
-  bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
+  static const char* AllocationIndexToString(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    const char* const names[] = {
+      "xmm1",
+      "xmm2",
+      "xmm3",
+      "xmm4",
+      "xmm5",
+      "xmm6",
+      "xmm7",
+      "xmm8",
+      "xmm9",
+      "xmm10",
+      "xmm11",
+      "xmm12",
+      "xmm13",
+      "xmm14",
+      "xmm15"
+    };
+    return names[index];
+  }
+
+  static XMMRegister from_code(int code) {
+    DCHECK(code >= 0);
+    DCHECK(code < kMaxNumRegisters);
+    XMMRegister r = { code };
+    return r;
+  }
+  bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters; }
+  bool is(XMMRegister reg) const { return code_ == reg.code_; }
   int code() const {
     DCHECK(is_valid());
-    return reg_code;
+    return code_;
   }
 
   // Return the high bit of the register code as a 0 or 1.  Used often
   // when constructing the REX prefix byte.
-  int high_bit() const { return reg_code >> 3; }
+  int high_bit() const {
+    return code_ >> 3;
+  }
   // Return the 3 low bits of the register code.  Used when encoding registers
   // in modR/M, SIB, and opcode bytes.
-  int low_bits() const { return reg_code & 0x7; }
+  int low_bits() const {
+    return code_ & 0x7;
+  }
 
-  // Unfortunately we can't make this private in a struct when initializing
-  // by assignment.
-  int reg_code;
+  int code_;
 };
 
+const XMMRegister xmm0 = { 0 };
+const XMMRegister xmm1 = { 1 };
+const XMMRegister xmm2 = { 2 };
+const XMMRegister xmm3 = { 3 };
+const XMMRegister xmm4 = { 4 };
+const XMMRegister xmm5 = { 5 };
+const XMMRegister xmm6 = { 6 };
+const XMMRegister xmm7 = { 7 };
+const XMMRegister xmm8 = { 8 };
+const XMMRegister xmm9 = { 9 };
+const XMMRegister xmm10 = { 10 };
+const XMMRegister xmm11 = { 11 };
+const XMMRegister xmm12 = { 12 };
+const XMMRegister xmm13 = { 13 };
+const XMMRegister xmm14 = { 14 };
+const XMMRegister xmm15 = { 15 };
+
+
+typedef XMMRegister DoubleRegister;
 
-#define DECLARE_REGISTER(R) \
-  const DoubleRegister R = {DoubleRegister::kCode_##R};
-DOUBLE_REGISTERS(DECLARE_REGISTER)
-#undef DECLARE_REGISTER
-const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
-
-
-typedef DoubleRegister XMMRegister;
 
 enum Condition {
   // any value < 0 is considered no_condition
index d3f92c530c19a2d00e12db33142180d69fe59004..1344400d48eff7f70642b8cb621d00dfa3f7cf75 100644 (file)
@@ -294,15 +294,13 @@ class RecordWriteStub: public PlatformCodeStub {
     Register GetRegThatIsNotRcxOr(Register r1,
                                   Register r2,
                                   Register r3) {
-      for (int i = 0; i < Register::kNumRegisters; i++) {
-        Register candidate = Register::from_code(i);
-        if (candidate.IsAllocatable()) {
-          if (candidate.is(rcx)) continue;
-          if (candidate.is(r1)) continue;
-          if (candidate.is(r2)) continue;
-          if (candidate.is(r3)) continue;
-          return candidate;
-        }
+      for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
+        Register candidate = Register::FromAllocationIndex(i);
+        if (candidate.is(rcx)) continue;
+        if (candidate.is(r1)) continue;
+        if (candidate.is(r2)) continue;
+        if (candidate.is(r3)) continue;
+        return candidate;
       }
       UNREACHABLE();
       return no_reg;
index 8ec123a5da9f4ee8cea0e9dec88fbcd172cac3b4..72c92f0a39bbfae08505f9314aabb69f1875698b 100644 (file)
@@ -7,7 +7,6 @@
 #include "src/codegen.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen/full-codegen.h"
-#include "src/register-configuration.h"
 #include "src/safepoint-table.h"
 
 namespace v8 {
@@ -96,7 +95,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
   }
   input_->SetRegister(rsp.code(), reinterpret_cast<intptr_t>(frame->sp()));
   input_->SetRegister(rbp.code(), reinterpret_cast<intptr_t>(frame->fp()));
-  for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) {
+  for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
     input_->SetDoubleRegister(i, 0.0);
   }
 
@@ -118,7 +117,7 @@ void Deoptimizer::SetPlatformCompiledStubRegisters(
 
 
 void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
-  for (int i = 0; i < XMMRegister::kMaxNumRegisters; ++i) {
+  for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); ++i) {
     double double_value = input_->GetDoubleRegister(i);
     output_frame->SetDoubleRegister(i, double_value);
   }
@@ -139,14 +138,13 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   // Save all general purpose registers before messing with them.
   const int kNumberOfRegisters = Register::kNumRegisters;
 
-  const int kDoubleRegsSize = kDoubleSize * XMMRegister::kMaxNumRegisters;
+  const int kDoubleRegsSize = kDoubleSize *
+      XMMRegister::NumAllocatableRegisters();
   __ subp(rsp, Immediate(kDoubleRegsSize));
 
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    XMMRegister xmm_reg = XMMRegister::from_code(code);
-    int offset = code * kDoubleSize;
+  for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); ++i) {
+    XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
+    int offset = i * kDoubleSize;
     __ movsd(Operand(rsp, offset), xmm_reg);
   }
 
@@ -212,7 +210,7 @@ void Deoptimizer::TableEntryGenerator::Generate() {
 
   // Fill in the double input registers.
   int double_regs_offset = FrameDescription::double_registers_offset();
-  for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
+  for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) {
     int dst_offset = i * kDoubleSize + double_regs_offset;
     __ popq(Operand(rbx, dst_offset));
   }
@@ -276,10 +274,9 @@ void Deoptimizer::TableEntryGenerator::Generate() {
   __ cmpp(rax, rdx);
   __ j(below, &outer_push_loop);
 
-  for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-    int code = config->GetAllocatableDoubleCode(i);
-    XMMRegister xmm_reg = XMMRegister::from_code(code);
-    int src_offset = code * kDoubleSize + double_regs_offset;
+  for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); ++i) {
+    XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
+    int src_offset = i * kDoubleSize + double_regs_offset;
     __ movsd(xmm_reg, Operand(rbx, src_offset));
   }
 
index 1a2fd8a9e8b1c48a912d778f052ce77eec4a6e3b..81d275f7a9d60bb7dc6cc5ab3291c332cd3d33b4 100644 (file)
@@ -89,7 +89,7 @@ void LCodeGen::SaveCallerDoubles() {
   BitVector::Iterator save_iterator(doubles);
   while (!save_iterator.Done()) {
     __ movsd(MemOperand(rsp, count * kDoubleSize),
-             XMMRegister::from_code(save_iterator.Current()));
+             XMMRegister::FromAllocationIndex(save_iterator.Current()));
     save_iterator.Advance();
     count++;
   }
@@ -104,7 +104,7 @@ void LCodeGen::RestoreCallerDoubles() {
   BitVector::Iterator save_iterator(doubles);
   int count = 0;
   while (!save_iterator.Done()) {
-    __ movsd(XMMRegister::from_code(save_iterator.Current()),
+    __ movsd(XMMRegister::FromAllocationIndex(save_iterator.Current()),
              MemOperand(rsp, count * kDoubleSize));
     save_iterator.Advance();
     count++;
@@ -437,12 +437,12 @@ bool LCodeGen::GenerateSafepointTable() {
 
 
 Register LCodeGen::ToRegister(int index) const {
-  return Register::from_code(index);
+  return Register::FromAllocationIndex(index);
 }
 
 
 XMMRegister LCodeGen::ToDoubleRegister(int index) const {
-  return XMMRegister::from_code(index);
+  return XMMRegister::FromAllocationIndex(index);
 }
 
 
index 722ab01be2b5396b98de40a7967c346cce5dd83a..9df3a7dabf328745bf4731be4f0dd46ed97d8772 100644 (file)
@@ -470,13 +470,14 @@ LPlatformChunk* LChunkBuilder::Build() {
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
-  return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
+                                  Register::ToAllocationIndex(reg));
 }
 
 
 LUnallocated* LChunkBuilder::ToUnallocated(XMMRegister reg) {
-  return new (zone())
-      LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, reg.code());
+  return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
+                                  XMMRegister::ToAllocationIndex(reg));
 }
 
 
index 3eb3b2ff0b4a4c301c7050ec4eb01433ae005e4f..0361828eb5f901823404ca4ad571cfcc189b5f30 100644 (file)
@@ -11,7 +11,6 @@
 #include "src/cpu-profiler.h"
 #include "src/debug/debug.h"
 #include "src/heap/heap.h"
-#include "src/register-configuration.h"
 #include "src/x64/assembler-x64.h"
 #include "src/x64/macro-assembler-x64.h"
 
@@ -731,8 +730,7 @@ void MacroAssembler::GetBuiltinEntry(Register target,
 }
 
 
-#define REG(Name) \
-  { Register::kCode_##Name }
+#define REG(Name) { kRegister_ ## Name ## _Code }
 
 static const Register saved_regs[] = {
   REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8),
@@ -3706,14 +3704,12 @@ void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
 #endif
   // Optionally save all XMM registers.
   if (save_doubles) {
-    int space = XMMRegister::kMaxNumRegisters * kDoubleSize +
-                arg_stack_space * kRegisterSize;
+    int space = XMMRegister::kMaxNumAllocatableRegisters * kDoubleSize +
+        arg_stack_space * kRegisterSize;
     subp(rsp, Immediate(space));
     int offset = -2 * kPointerSize;
-    const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-    for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-      DoubleRegister reg =
-          DoubleRegister::from_code(config->GetAllocatableDoubleCode(i));
+    for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) {
+      XMMRegister reg = XMMRegister::FromAllocationIndex(i);
       movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg);
     }
   } else if (arg_stack_space > 0) {
@@ -3756,10 +3752,8 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles) {
   // r15 : argv
   if (save_doubles) {
     int offset = -2 * kPointerSize;
-    const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-    for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
-      DoubleRegister reg =
-          DoubleRegister::from_code(config->GetAllocatableDoubleCode(i));
+    for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) {
+      XMMRegister reg = XMMRegister::FromAllocationIndex(i);
       movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize)));
     }
   }
index 27137af9f74f9ef204f1ec48acdfe65959de916a..7d392a294bfa6b1fa949caa3fce0664c76b54fa8 100644 (file)
@@ -16,17 +16,17 @@ namespace v8 {
 namespace internal {
 
 // Give alias names to registers for calling conventions.
-const Register kReturnRegister0 = {Register::kCode_rax};
-const Register kReturnRegister1 = {Register::kCode_rdx};
-const Register kJSFunctionRegister = {Register::kCode_rdi};
-const Register kContextRegister = {Register::kCode_rsi};
-const Register kInterpreterAccumulatorRegister = {Register::kCode_rax};
-const Register kInterpreterRegisterFileRegister = {Register::kCode_r11};
-const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_r12};
-const Register kInterpreterBytecodeArrayRegister = {Register::kCode_r14};
-const Register kInterpreterDispatchTableRegister = {Register::kCode_r15};
-const Register kRuntimeCallFunctionRegister = {Register::kCode_rbx};
-const Register kRuntimeCallArgCountRegister = {Register::kCode_rax};
+const Register kReturnRegister0 = {kRegister_rax_Code};
+const Register kReturnRegister1 = {kRegister_rdx_Code};
+const Register kJSFunctionRegister = {kRegister_rdi_Code};
+const Register kContextRegister = {kRegister_rsi_Code};
+const Register kInterpreterAccumulatorRegister = {kRegister_rax_Code};
+const Register kInterpreterRegisterFileRegister = {kRegister_r11_Code};
+const Register kInterpreterBytecodeOffsetRegister = {kRegister_r12_Code};
+const Register kInterpreterBytecodeArrayRegister = {kRegister_r14_Code};
+const Register kInterpreterDispatchTableRegister = {kRegister_r15_Code};
+const Register kRuntimeCallFunctionRegister = {kRegister_rbx_Code};
+const Register kRuntimeCallArgCountRegister = {kRegister_rax_Code};
 
 // Default scratch register used by MacroAssembler (and other code that needs
 // a spare register). The register isn't callee save, and not used by the
index a2a90dfc3ccd764b8c8b5a6a17c04fa897825d3e..1f454bcd9023275bc8a8e0e7ccaeaf10a119b33b 100644 (file)
@@ -76,6 +76,10 @@ struct Register {
 
   static inline const char* AllocationIndexToString(int index);
 
+  static inline int ToAllocationIndex(Register reg);
+
+  static inline Register FromAllocationIndex(int index);
+
   static Register from_code(int code) {
     DCHECK(code >= 0);
     DCHECK(code < kNumRegisters);
@@ -128,6 +132,18 @@ inline const char* Register::AllocationIndexToString(int index) {
 }
 
 
+inline int Register::ToAllocationIndex(Register reg) {
+  DCHECK(reg.is_valid() && !reg.is(esp) && !reg.is(ebp));
+  return (reg.code() >= 6) ? reg.code() - 2 : reg.code();
+}
+
+
+inline Register Register::FromAllocationIndex(int index)  {
+  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+  return (index >= 4) ? from_code(index + 2) : from_code(index);
+}
+
+
 struct X87Register {
   static const int kMaxNumAllocatableRegisters = 6;
   static const int kMaxNumRegisters = 8;
index 7dade3df33a5d821a71f6a2acab2d57e37149f1b..a081ddb8fe9d79410692e8fb43413b693e1ec2a0 100644 (file)
@@ -73,13 +73,7 @@ class InterpreterState {
     AllocatedOperand::AllocatedKind kind;
     int index;
     if (!is_constant) {
-      if (op.IsRegister()) {
-        index = AllocatedOperand::cast(op).GetRegister().code();
-      } else if (op.IsDoubleRegister()) {
-        index = AllocatedOperand::cast(op).GetDoubleRegister().code();
-      } else {
-        index = AllocatedOperand::cast(op).index();
-      }
+      index = AllocatedOperand::cast(op).index();
       kind = AllocatedOperand::cast(op).allocated_kind();
     } else {
       index = ConstantOperand::cast(op).virtual_register();
@@ -96,9 +90,7 @@ class InterpreterState {
       return ConstantOperand(key.index);
     }
     return AllocatedOperand(
-        key.kind,
-        v8::internal::compiler::InstructionSequence::DefaultRepresentation(),
-        key.index);
+        key.kind, InstructionSequence::DefaultRepresentation(), key.index);
   }
 
   friend std::ostream& operator<<(std::ostream& os,
index af3748b8fd1b8049445a3155b8ecda39b779b1fa..bc6acf1bc97b4d57cc777ce9846cc03e898f8e30 100644 (file)
@@ -7,7 +7,6 @@
 #include "src/compiler/linkage.h"
 #include "src/compiler/machine-type.h"
 #include "src/compiler/raw-machine-assembler.h"
-#include "src/register-configuration.h"
 
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/codegen-tester.h"
@@ -36,9 +35,8 @@ typedef double float64;
 // to select a representative set.
 class Pairs {
  public:
-  Pairs(int max_pairs, int range, const int* codes)
+  Pairs(int max_pairs, int range)
       : range_(range),
-        codes_(codes),
         max_pairs_(std::min(max_pairs, range_ * range_)),
         counter_(0) {}
 
@@ -48,33 +46,37 @@ class Pairs {
     do {
       // Find the next pair.
       if (exhaustive()) {
-        *r0 = codes_[counter_ % range_];
-        *r1 = codes_[counter_ / range_];
+        *r0 = counter_ % range_;
+        *r1 = counter_ / range_;
       } else {
         // Try each integer at least once for both r0 and r1.
         int index = counter_ / 2;
         if (counter_ & 1) {
-          *r0 = codes_[index % range_];
-          *r1 = codes_[index / range_];
+          *r0 = index % range_;
+          *r1 = index / range_;
         } else {
-          *r1 = codes_[index % range_];
-          *r0 = codes_[index / range_];
+          *r1 = index % range_;
+          *r0 = index / range_;
         }
       }
       counter_++;
-      if ((same_is_ok) || (*r0 != *r1)) break;
-      if (counter_ == max_pairs_) {
-        // For the last hurrah, reg#0 with reg#n-1
-        *r0 = codes_[0];
-        *r1 = codes_[range_ - 1];
-        break;
+      if (same_is_ok) break;
+      if (*r0 == *r1) {
+        if (counter_ >= max_pairs_) {
+          // For the last hurrah, reg#0 with reg#n-1
+          *r0 = 0;
+          *r1 = range_ - 1;
+          break;
+        }
       }
     } while (true);
+
+    DCHECK(*r0 >= 0 && *r0 < range_);
+    DCHECK(*r1 >= 0 && *r1 < range_);
   }
 
  private:
   int range_;
-  const int* codes_;
   int max_pairs_;
   int counter_;
   bool exhaustive() { return max_pairs_ == (range_ * range_); }
@@ -84,12 +86,7 @@ class Pairs {
 // Pairs of general purpose registers.
 class RegisterPairs : public Pairs {
  public:
-  RegisterPairs()
-      : Pairs(
-            100, RegisterConfiguration::ArchDefault()
-                     ->num_allocatable_general_registers(),
-            RegisterConfiguration::ArchDefault()->allocatable_general_codes()) {
-  }
+  RegisterPairs() : Pairs(100, Register::kMaxNumAllocatableRegisters) {}
 };
 
 
@@ -97,10 +94,7 @@ class RegisterPairs : public Pairs {
 class Float32RegisterPairs : public Pairs {
  public:
   Float32RegisterPairs()
-      : Pairs(
-            100, RegisterConfiguration::ArchDefault()
-                     ->num_allocatable_aliased_double_registers(),
-            RegisterConfiguration::ArchDefault()->allocatable_double_codes()) {}
+      : Pairs(100, DoubleRegister::NumAllocatableAliasedRegisters()) {}
 };
 
 
@@ -108,10 +102,7 @@ class Float32RegisterPairs : public Pairs {
 class Float64RegisterPairs : public Pairs {
  public:
   Float64RegisterPairs()
-      : Pairs(
-            100, RegisterConfiguration::ArchDefault()
-                     ->num_allocatable_aliased_double_registers(),
-            RegisterConfiguration::ArchDefault()->allocatable_double_codes()) {}
+      : Pairs(100, DoubleRegister::NumAllocatableAliasedRegisters()) {}
 };
 
 
@@ -633,12 +624,9 @@ static void Test_RunInt32SubWithRet(int retreg) {
 
 
 // Separate tests for parallelization.
-#define TEST_INT32_SUB_WITH_RET(x)                \
-  TEST(Run_Int32Sub_all_allocatable_pairs_##x) {  \
-    if (x < Register::kNumRegisters &&            \
-        Register::from_code(x).IsAllocatable()) { \
-      Test_RunInt32SubWithRet(x);                 \
-    }                                             \
+#define TEST_INT32_SUB_WITH_RET(x)                                             \
+  TEST(Run_Int32Sub_all_allocatable_pairs_##x) {                               \
+    if (Register::kMaxNumAllocatableRegisters > x) Test_RunInt32SubWithRet(x); \
   }
 
 
@@ -689,8 +677,7 @@ TEST(Run_CopyTwentyInt32_all_allocatable_pairs) {
   while (pairs.More()) {
     Zone zone;
     int parray[2];
-    int rarray[] = {
-        RegisterConfiguration::ArchDefault()->GetAllocatableGeneralCode(0)};
+    int rarray[] = {0};
     pairs.Next(&parray[0], &parray[1], false);
     Allocator params(parray, 2, nullptr, 0);
     Allocator rets(rarray, 1, nullptr, 0);
@@ -737,20 +724,17 @@ static int32_t Compute_Int32_WeightedSum(CallDescriptor* desc, int32_t* input) {
 static void Test_Int32_WeightedSum_of_size(int count) {
   if (DISABLE_NATIVE_STACK_PARAMS) return;
   Int32Signature sig(count);
-  for (int p0 = 0; p0 < Register::kNumRegisters; p0++) {
-    if (Register::from_code(p0).IsAllocatable()) {
-      Zone zone;
+  for (int p0 = 0; p0 < Register::kMaxNumAllocatableRegisters; p0++) {
+    Zone zone;
 
-      int parray[] = {p0};
-      int rarray[] = {
-          RegisterConfiguration::ArchDefault()->GetAllocatableGeneralCode(0)};
-      Allocator params(parray, 1, nullptr, 0);
-      Allocator rets(rarray, 1, nullptr, 0);
-      RegisterConfig config(params, rets);
-      CallDescriptor* desc = config.Create(&zone, &sig);
-      Run_Computation<int32_t>(desc, Build_Int32_WeightedSum,
-                               Compute_Int32_WeightedSum, 257 + count);
-    }
+    int parray[] = {p0};
+    int rarray[] = {0};
+    Allocator params(parray, 1, nullptr, 0);
+    Allocator rets(rarray, 1, nullptr, 0);
+    RegisterConfig config(params, rets);
+    CallDescriptor* desc = config.Create(&zone, &sig);
+    Run_Computation<int32_t>(desc, Build_Int32_WeightedSum,
+                             Compute_Int32_WeightedSum, 257 + count);
   }
 }
 
@@ -798,10 +782,8 @@ template <int which>
 void Test_Int32_Select() {
   if (DISABLE_NATIVE_STACK_PARAMS) return;
 
-  int parray[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableGeneralCode(0)};
-  int rarray[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableGeneralCode(0)};
+  int parray[] = {0};
+  int rarray[] = {0};
   Allocator params(parray, 1, nullptr, 0);
   Allocator rets(rarray, 1, nullptr, 0);
   RegisterConfig config(params, rets);
@@ -837,13 +819,10 @@ TEST_INT32_SELECT(63)
 
 
 TEST(Int64Select_registers) {
-  if (RegisterConfiguration::ArchDefault()
-          ->num_allocatable_general_registers() < 2)
-    return;
+  if (Register::kMaxNumAllocatableRegisters < 2) return;
   if (kPointerSize < 8) return;  // TODO(titzer): int64 on 32-bit platforms
 
-  int rarray[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableGeneralCode(0)};
+  int rarray[] = {0};
   ArgsBuffer<int64_t>::Sig sig(2);
 
   RegisterPairs pairs;
@@ -863,13 +842,9 @@ TEST(Int64Select_registers) {
 
 
 TEST(Float32Select_registers) {
-  if (RegisterConfiguration::ArchDefault()->num_allocatable_double_registers() <
-      2) {
-    return;
-  }
+  if (RegisterConfiguration::ArchDefault()->num_double_registers() < 2) return;
 
-  int rarray[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableDoubleCode(0)};
+  int rarray[] = {0};
   ArgsBuffer<float32>::Sig sig(2);
 
   Float32RegisterPairs pairs;
@@ -889,14 +864,9 @@ TEST(Float32Select_registers) {
 
 
 TEST(Float64Select_registers) {
-  if (RegisterConfiguration::ArchDefault()->num_allocatable_double_registers() <
-      2)
-    return;
-  if (RegisterConfiguration::ArchDefault()
-          ->num_allocatable_general_registers() < 2)
-    return;
-  int rarray[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableDoubleCode(0)};
+  if (RegisterConfiguration::ArchDefault()->num_double_registers() < 2) return;
+
+  int rarray[] = {0};
   ArgsBuffer<float64>::Sig sig(2);
 
   Float64RegisterPairs pairs;
@@ -917,8 +887,7 @@ TEST(Float64Select_registers) {
 
 TEST(Float32Select_stack_params_return_reg) {
   if (DISABLE_NATIVE_STACK_PARAMS) return;
-  int rarray[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableDoubleCode(0)};
+  int rarray[] = {0};
   Allocator params(nullptr, 0, nullptr, 0);
   Allocator rets(nullptr, 0, rarray, 1);
   RegisterConfig config(params, rets);
@@ -939,8 +908,7 @@ TEST(Float32Select_stack_params_return_reg) {
 
 TEST(Float64Select_stack_params_return_reg) {
   if (DISABLE_NATIVE_STACK_PARAMS) return;
-  int rarray[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableDoubleCode(0)};
+  int rarray[] = {0};
   Allocator params(nullptr, 0, nullptr, 0);
   Allocator rets(nullptr, 0, rarray, 1);
   RegisterConfig config(params, rets);
@@ -994,8 +962,7 @@ static void Build_Select_With_Call(CallDescriptor* desc,
 TEST(Float64StackParamsToStackParams) {
   if (DISABLE_NATIVE_STACK_PARAMS) return;
 
-  int rarray[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableDoubleCode(0)};
+  int rarray[] = {0};
   Allocator params(nullptr, 0, nullptr, 0);
   Allocator rets(nullptr, 0, rarray, 1);
 
@@ -1038,18 +1005,10 @@ void MixedParamTest(int start) {
   const int num_params = static_cast<int>(arraysize(types) - start);
 
   // Build call descriptor
-  int parray_gp[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableGeneralCode(0),
-      RegisterConfiguration::ArchDefault()->GetAllocatableGeneralCode(1)};
-  int rarray_gp[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableGeneralCode(0)};
-  int parray_fp[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableDoubleCode(0),
-      RegisterConfiguration::ArchDefault()->GetAllocatableDoubleCode(1)};
-  int rarray_fp[] = {
-      RegisterConfiguration::ArchDefault()->GetAllocatableDoubleCode(0)};
-  Allocator palloc(parray_gp, 2, parray_fp, 2);
-  Allocator ralloc(rarray_gp, 1, rarray_fp, 1);
+  int parray[] = {0, 1};
+  int rarray[] = {0};
+  Allocator palloc(parray, 2, parray, 2);
+  Allocator ralloc(rarray, 1, rarray, 1);
   RegisterConfig config(palloc, ralloc);
 
   for (int which = 0; which < num_params; which++) {
index 385718f486c9cd037c03b2cb4fd56d35029e0373..33145444c7230fd1c58c087ad83e70b7e80e6585 100644 (file)
@@ -76,13 +76,11 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
   // Save registers make sure they don't get clobbered.
   int source_reg_offset = kDoubleSize;
   int reg_num = 0;
-  for (; reg_num < Register::kNumRegisters; ++reg_num) {
+  for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) {
     Register reg = Register::from_code(reg_num);
-    if (reg.IsAllocatable()) {
-      if (!reg.is(destination_reg)) {
-        __ push(reg);
-        source_reg_offset += kPointerSize;
-      }
+    if (!reg.is(destination_reg)) {
+      __ push(reg);
+      source_reg_offset += kPointerSize;
     }
   }
 
@@ -107,13 +105,11 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
   // Make sure no registers have been unexpectedly clobbered
   for (--reg_num; reg_num >= 0; --reg_num) {
     Register reg = Register::from_code(reg_num);
-    if (reg.IsAllocatable()) {
-      if (!reg.is(destination_reg)) {
-        __ ldr(ip, MemOperand(sp, 0));
-        __ cmp(reg, ip);
-        __ Assert(eq, kRegisterWasClobbered);
-        __ add(sp, sp, Operand(kPointerSize));
-      }
+    if (!reg.is(destination_reg)) {
+      __ ldr(ip, MemOperand(sp, 0));
+      __ cmp(reg, ip);
+      __ Assert(eq, kRegisterWasClobbered);
+      __ add(sp, sp, Operand(kPointerSize));
     }
   }
 
index c7a6cdb4be0e5f94a01c710fa884d2bee9666f4b..ecb8819345378667c3ae774954c4185c07e600e4 100644 (file)
@@ -72,13 +72,11 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
   // Save registers make sure they don't get clobbered.
   int source_reg_offset = kDoubleSize;
   int reg_num = 0;
-  for (; reg_num < Register::kNumRegisters; ++reg_num) {
+  for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) {
     Register reg = Register::from_code(reg_num);
-    if (reg.IsAllocatable()) {
-      if (!reg.is(destination_reg)) {
-        queue.Queue(reg);
-        source_reg_offset += kPointerSize;
-      }
+    if (!reg.is(destination_reg)) {
+      queue.Queue(reg);
+      source_reg_offset += kPointerSize;
     }
   }
   // Re-push the double argument.
@@ -103,12 +101,10 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
   // // Make sure no registers have been unexpectedly clobbered
   for (--reg_num; reg_num >= 0; --reg_num) {
     Register reg = Register::from_code(reg_num);
-    if (reg.IsAllocatable()) {
-      if (!reg.is(destination_reg)) {
-        __ Pop(ip0);
-        __ cmp(reg, ip0);
-        __ Assert(eq, kRegisterWasClobbered);
-      }
+    if (!reg.is(destination_reg)) {
+      __ Pop(ip0);
+      __ cmp(reg, ip0);
+      __ Assert(eq, kRegisterWasClobbered);
     }
   }
 
index e0f9a453ed20fc65c8fea39f37aa47fc145efe8a..0b4a8d417bccd1e998c20a8c49669bf6cf6e8ba5 100644 (file)
@@ -70,13 +70,11 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
   int param_offset = 7 * kPointerSize;
   // Save registers make sure they don't get clobbered.
   int reg_num = 0;
-  for (; reg_num < Register::kNumRegisters; ++reg_num) {
-    Register reg = Register::from_code(reg_num);
-    if (reg.IsAllocatable()) {
-      if (!reg.is(esp) && !reg.is(ebp) && !reg.is(destination_reg)) {
-        __ push(reg);
-        param_offset += kPointerSize;
-      }
+  for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) {
+    Register reg = Register::FromAllocationIndex(reg_num);
+    if (!reg.is(esp) && !reg.is(ebp) && !reg.is(destination_reg)) {
+      __ push(reg);
+      param_offset += kPointerSize;
     }
   }
 
@@ -91,13 +89,11 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
 
   // Make sure no registers have been unexpectedly clobbered
   for (--reg_num; reg_num >= 0; --reg_num) {
-    Register reg = Register::from_code(reg_num);
-    if (reg.IsAllocatable()) {
-      if (!reg.is(esp) && !reg.is(ebp) && !reg.is(destination_reg)) {
-        __ cmp(reg, MemOperand(esp, 0));
-        __ Assert(equal, kRegisterWasClobbered);
-        __ add(esp, Immediate(kPointerSize));
-      }
+    Register reg = Register::FromAllocationIndex(reg_num);
+    if (!reg.is(esp) && !reg.is(ebp) && !reg.is(destination_reg)) {
+      __ cmp(reg, MemOperand(esp, 0));
+      __ Assert(equal, kRegisterWasClobbered);
+      __ add(esp, Immediate(kPointerSize));
     }
   }
 
index e64eedf84233ae27cd66c8ef141bfd74a3f16afb..eb3ba02ce878a910ed2dd7275b1e772d0efd64ff 100644 (file)
@@ -34,7 +34,6 @@
 #include "src/factory.h"
 #include "src/macro-assembler.h"
 #include "src/mips/constants-mips.h"
-#include "src/register-configuration.h"
 #include "src/simulator.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/test-code-stubs.h"
@@ -80,8 +79,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
   // Save registers make sure they don't get clobbered.
   int source_reg_offset = kDoubleSize;
   int reg_num = 2;
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (; reg_num < config->num_allocatable_general_registers(); ++reg_num) {
+  for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) {
     Register reg = Register::from_code(reg_num);
     if (!reg.is(destination_reg)) {
       __ push(reg);
index fde2d07a9c12864b3096b9e9d7d9dec8daa3cbb6..1415cec0798eacbc662c231fa0f1876ec5f9712c 100644 (file)
@@ -34,7 +34,6 @@
 #include "src/factory.h"
 #include "src/macro-assembler.h"
 #include "src/mips64/constants-mips64.h"
-#include "src/register-configuration.h"
 #include "src/simulator.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/test-code-stubs.h"
@@ -80,8 +79,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
   // Save registers make sure they don't get clobbered.
   int source_reg_offset = kDoubleSize;
   int reg_num = 2;
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
-  for (; reg_num < config->num_allocatable_general_registers(); ++reg_num) {
+  for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) {
     Register reg = Register::from_code(reg_num);
     if (!reg.is(destination_reg)) {
       __ push(reg);
index 8f22dd9fcfc48f595114f7351e7257f1bbddba21..b58b073f3b7939736499e39caa4fea653634a53c 100644 (file)
@@ -33,7 +33,6 @@
 #include "src/code-stubs.h"
 #include "src/factory.h"
 #include "src/macro-assembler.h"
-#include "src/register-configuration.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/test-code-stubs.h"
 
@@ -63,24 +62,20 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
   __ pushq(rsi);
   __ pushq(rdi);
 
-
-  const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
   if (!source_reg.is(rsp)) {
     // The argument we pass to the stub is not a heap number, but instead
     // stack-allocated and offset-wise made to look like a heap number for
     // the stub.  We create that "heap number" after pushing all allocatable
     // registers.
     int double_argument_slot =
-        (config->num_allocatable_general_registers() - 1) * kPointerSize +
-        kDoubleSize;
+        (Register::NumAllocatableRegisters() - 1) * kPointerSize + kDoubleSize;
     __ leaq(source_reg, MemOperand(rsp, -double_argument_slot - offset));
   }
 
   // Save registers make sure they don't get clobbered.
   int reg_num = 0;
-  for (; reg_num < config->num_allocatable_general_registers(); ++reg_num) {
-    Register reg =
-        Register::from_code(config->GetAllocatableGeneralCode(reg_num));
+  for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) {
+    Register reg = Register::FromAllocationIndex(reg_num);
     if (!reg.is(rsp) && !reg.is(rbp) && !reg.is(destination_reg)) {
       __ pushq(reg);
     }
@@ -97,8 +92,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
 
   // Make sure no registers have been unexpectedly clobbered
   for (--reg_num; reg_num >= 0; --reg_num) {
-    Register reg =
-        Register::from_code(config->GetAllocatableGeneralCode(reg_num));
+    Register reg = Register::FromAllocationIndex(reg_num);
     if (!reg.is(rsp) && !reg.is(rbp) && !reg.is(destination_reg)) {
       __ cmpq(reg, MemOperand(rsp, 0));
       __ Assert(equal, kRegisterWasClobbered);
index 76bfe2217183f1b2a270c290f6bf1d73bc910fda..e14382e914a214378c81a5f52a3886ba4ee3f798 100644 (file)
@@ -127,7 +127,8 @@ bool InstructionSelectorTest::Stream::IsFixed(const InstructionOperand* operand,
   if (!operand->IsUnallocated()) return false;
   const UnallocatedOperand* unallocated = UnallocatedOperand::cast(operand);
   if (!unallocated->HasFixedRegisterPolicy()) return false;
-  return unallocated->fixed_register_index() == reg.code();
+  const int index = Register::ToAllocationIndex(reg);
+  return unallocated->fixed_register_index() == index;
 }
 
 
index 51112a6470ee24e9d21ff18936a9d9554f782aa2..65a7f299c5565703e5f07022facef32546c2f512 100644 (file)
@@ -20,14 +20,6 @@ static char register_names_[10 * (RegisterConfiguration::kMaxGeneralRegisters +
                                   RegisterConfiguration::kMaxDoubleRegisters)];
 
 
-namespace {
-static int allocatable_codes[InstructionSequenceTest::kDefaultNRegs] = {
-    0, 1, 2, 3, 4, 5, 6, 7};
-static int allocatable_double_codes[InstructionSequenceTest::kDefaultNRegs] = {
-    0, 1, 2, 3, 4, 5, 6, 7};
-}
-
-
 static void InitializeRegisterNames() {
   char* loc = register_names_;
   for (int i = 0; i < RegisterConfiguration::kMaxGeneralRegisters; ++i) {
@@ -67,10 +59,8 @@ void InstructionSequenceTest::SetNumRegs(int num_general_registers,
 RegisterConfiguration* InstructionSequenceTest::config() {
   if (config_.is_empty()) {
     config_.Reset(new RegisterConfiguration(
-        num_general_registers_, num_double_registers_, num_general_registers_,
-        num_double_registers_, num_double_registers_, allocatable_codes,
-        allocatable_double_codes, general_register_names_,
-        double_register_names_));
+        num_general_registers_, num_double_registers_, num_double_registers_,
+        general_register_names_, double_register_names_));
   }
   return config_.get();
 }
index e5e5139f970295eb81b4c0c56e0383a020b153ef..54317ede21c6107ac04977456012a33a3c98fc35 100644 (file)
@@ -15,7 +15,7 @@ namespace compiler {
 
 class InstructionSequenceTest : public TestWithIsolateAndZone {
  public:
-  static const int kDefaultNRegs = 8;
+  static const int kDefaultNRegs = 4;
   static const int kNoValue = kMinInt;
 
   typedef RpoNumber Rpo;
index 0fd41d918d670b8b2f19fda0fbb9ca5497ae38c8..23a118b6ad157783b13d7fe85cc3fd7613adabde 100644 (file)
@@ -41,8 +41,7 @@ bool AllocatedOperandMatches(
     const AllocatedOperand& op,
     const InstructionSequenceTest::TestOperand& test_op) {
   return AreOperandsOfSameType(op, test_op) &&
-         ((op.IsRegister() ? op.GetRegister().code() : op.index()) ==
-              test_op.value_ ||
+         (op.index() == test_op.value_ ||
           test_op.value_ == InstructionSequenceTest::kNoValue);
 }
 
index 3d895c16628fa948d19001186893a0442189e275..c8abd433a4a83a03f454c87d3fea1c0cfea5ab3a 100644 (file)
         '../../src/compiler/register-allocator.h',
         '../../src/compiler/register-allocator-verifier.cc',
         '../../src/compiler/register-allocator-verifier.h',
+        '../../src/compiler/register-configuration.cc',
+        '../../src/compiler/register-configuration.h',
         '../../src/compiler/representation-change.h',
         '../../src/compiler/schedule.cc',
         '../../src/compiler/schedule.h',
         '../../src/regexp/regexp-macro-assembler.h',
         '../../src/regexp/regexp-stack.cc',
         '../../src/regexp/regexp-stack.h',
-        '../../src/register-configuration.cc',
-        '../../src/register-configuration.h',
         '../../src/rewriter.cc',
         '../../src/rewriter.h',
         '../../src/runtime-profiler.cc',