Index: src/ppc/assembler-ppc.h |
diff --git a/src/ppc/assembler-ppc.h b/src/ppc/assembler-ppc.h |
index c1d6358bb643805f70bfdc2ddcbeacbee133eda1..55e19af6db4e93ccfd6fc1370185724cb528cab6 100644 |
--- a/src/ppc/assembler-ppc.h |
+++ b/src/ppc/assembler-ppc.h |
@@ -61,9 +61,9 @@ |
(V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN) |
#if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64 |
-#define ABI_TOC_REGISTER kRegister_r2_Code |
+#define ABI_TOC_REGISTER Register::kCode_r2 |
#else |
-#define ABI_TOC_REGISTER kRegister_r13_Code |
+#define ABI_TOC_REGISTER Register::kCode_r13 |
#endif |
#define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC |
@@ -71,6 +71,40 @@ |
namespace v8 { |
namespace internal { |
+// clang-format off |
+#define GENERAL_REGISTERS(V) \ |
+ V(r0) V(sp) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \ |
+ V(r8) V(r9) V(r10) V(r11) V(ip) V(r13) V(r14) V(r15) \ |
+ V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ |
+ V(r24) V(r25) V(r26) V(r27) V(r28) V(r29) V(r30) V(fp) |
+ |
+#if V8_EMBEDDED_CONSTANT_POOL |
+#define ALLOCATABLE_GENERAL_REGISTERS(V) \ |
+ V(r3) V(r4) V(r5) V(r6) V(r7) \ |
+ V(r8) V(r9) V(r10) V(r14) V(r15) \ |
+ V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ |
+ V(r24) V(r25) V(r26) V(r27) V(r30) |
+#else |
+#define ALLOCATABLE_GENERAL_REGISTERS(V) \ |
+ V(r3) V(r4) V(r5) V(r6) V(r7) \ |
+ V(r8) V(r9) V(r10) V(r14) V(r15) \ |
+ V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ |
+ V(r24) V(r25) V(r26) V(r27) V(r28) V(r30) |
+#endif |
+ |
+#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(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ |
+ V(d8) V(d9) V(d10) V(d11) V(d12) 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) |
+// clang-format on |
+ |
// CPU Registers. |
// |
// 1) We would prefer to use an enum, but enum values are assignment- |
@@ -92,310 +126,112 @@ namespace internal { |
// mode. This way we get the compile-time error checking in debug mode |
// and best performance in optimized code. |
-// Core register |
struct Register { |
- static const int kNumRegisters = 32; |
- static const int kSizeInBytes = kPointerSize; |
- |
-#if V8_TARGET_LITTLE_ENDIAN |
- static const int kMantissaOffset = 0; |
- static const int kExponentOffset = 4; |
-#else |
- static const int kMantissaOffset = 4; |
- static const int kExponentOffset = 0; |
-#endif |
+ enum Code { |
+#define REGISTER_CODE(R) kCode_##R, |
+ GENERAL_REGISTERS(REGISTER_CODE) |
+#undef REGISTER_CODE |
+ kAfterLast, |
+ kCode_no_reg = -1 |
+ }; |
- static const int kAllocatableLowRangeBegin = 3; |
- static const int kAllocatableLowRangeEnd = 10; |
- static const int kAllocatableHighRangeBegin = 14; |
- static const int kAllocatableHighRangeEnd = |
- FLAG_enable_embedded_constant_pool ? 27 : 28; |
- static const int kAllocatableContext = 30; |
- |
- static const int kNumAllocatableLow = |
- kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1; |
- static const int kNumAllocatableHigh = |
- kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1; |
- static const int kMaxNumAllocatableRegisters = |
- kNumAllocatableLow + kNumAllocatableHigh + 1; // cp |
- |
- static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } |
- |
- static int ToAllocationIndex(Register reg) { |
- int index; |
- int code = reg.code(); |
- if (code == kAllocatableContext) { |
- // Context is the last index |
- index = NumAllocatableRegisters() - 1; |
- } else if (code <= kAllocatableLowRangeEnd) { |
- // low range |
- index = code - kAllocatableLowRangeBegin; |
- } else { |
- // high range |
- index = code - kAllocatableHighRangeBegin + kNumAllocatableLow; |
- } |
- DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); |
- return index; |
- } |
+ static const int kNumRegisters = Code::kAfterLast; |
- static Register FromAllocationIndex(int index) { |
- DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); |
- // Last index is always the 'cp' register. |
- if (index == kMaxNumAllocatableRegisters - 1) { |
- return from_code(kAllocatableContext); |
- } |
- return (index < kNumAllocatableLow) |
- ? from_code(index + kAllocatableLowRangeBegin) |
- : from_code(index - kNumAllocatableLow + |
- kAllocatableHighRangeBegin); |
- } |
- |
- static const char* AllocationIndexToString(int index) { |
- DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); |
- const char* const names[] = { |
- "r3", |
- "r4", |
- "r5", |
- "r6", |
- "r7", |
- "r8", |
- "r9", |
- "r10", |
- "r14", |
- "r15", |
- "r16", |
- "r17", |
- "r18", |
- "r19", |
- "r20", |
- "r21", |
- "r22", |
- "r23", |
- "r24", |
- "r25", |
- "r26", |
- "r27", |
- "r28", |
- "cp", |
- }; |
- if (FLAG_enable_embedded_constant_pool && |
- (index == kMaxNumAllocatableRegisters - 2)) { |
- return names[index + 1]; |
- } |
- return names[index]; |
- } |
+#define REGISTER_COUNT(R) 1 + |
+ static const int kNumAllocatable = |
+ ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT)0; |
+#undef REGISTER_COUNT |
+#define REGISTER_BIT(R) 1 << kCode_##R | |
static const RegList kAllocatable = |
- 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7 | 1 << 8 | 1 << 9 | 1 << 10 | |
- 1 << 14 | 1 << 15 | 1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 | 1 << 20 | |
- 1 << 21 | 1 << 22 | 1 << 23 | 1 << 24 | 1 << 25 | 1 << 26 | 1 << 27 | |
- (FLAG_enable_embedded_constant_pool ? 0 : 1 << 28) | 1 << 30; |
+ ALLOCATABLE_GENERAL_REGISTERS(REGISTER_BIT)0; |
+#undef REGISTER_BIT |
static Register from_code(int code) { |
+ DCHECK(code >= 0); |
+ DCHECK(code < kNumRegisters); |
Register r = {code}; |
return r; |
} |
- |
- bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } |
- bool is(Register reg) const { return code_ == reg.code_; } |
+ 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; } |
int code() const { |
DCHECK(is_valid()); |
- return code_; |
+ return reg_code; |
} |
int bit() const { |
DCHECK(is_valid()); |
- return 1 << code_; |
+ return 1 << reg_code; |
} |
- |
void set_code(int code) { |
- code_ = code; |
+ reg_code = code; |
DCHECK(is_valid()); |
} |
+#if V8_TARGET_LITTLE_ENDIAN |
+ static const int kMantissaOffset = 0; |
+ static const int kExponentOffset = 4; |
+#else |
+ static const int kMantissaOffset = 4; |
+ static const int kExponentOffset = 0; |
+#endif |
+ |
// Unfortunately we can't make this private in a struct. |
- int code_; |
+ int reg_code; |
}; |
-// These constants are used in several locations, including static initializers |
-const int kRegister_no_reg_Code = -1; |
-const int kRegister_r0_Code = 0; // general scratch |
-const int kRegister_sp_Code = 1; // stack pointer |
-const int kRegister_r2_Code = 2; // special on PowerPC |
-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_r11_Code = 11; // lithium scratch |
-const int kRegister_ip_Code = 12; // ip (general scratch) |
-const int kRegister_r13_Code = 13; // special on PowerPC |
-const int kRegister_r14_Code = 14; |
-const int kRegister_r15_Code = 15; |
- |
-const int kRegister_r16_Code = 16; |
-const int kRegister_r17_Code = 17; |
-const int kRegister_r18_Code = 18; |
-const int kRegister_r19_Code = 19; |
-const int kRegister_r20_Code = 20; |
-const int kRegister_r21_Code = 21; |
-const int kRegister_r22_Code = 22; |
-const int kRegister_r23_Code = 23; |
-const int kRegister_r24_Code = 24; |
-const int kRegister_r25_Code = 25; |
-const int kRegister_r26_Code = 26; |
-const int kRegister_r27_Code = 27; |
-const int kRegister_r28_Code = 28; // constant pool pointer |
-const int kRegister_r29_Code = 29; // roots array pointer |
-const int kRegister_r30_Code = 30; // context pointer |
-const int kRegister_fp_Code = 31; // frame pointer |
- |
-const Register no_reg = {kRegister_no_reg_Code}; |
- |
-const Register r0 = {kRegister_r0_Code}; |
-const Register sp = {kRegister_sp_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}; |
-const Register r7 = {kRegister_r7_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 ip = {kRegister_ip_Code}; |
-const Register r13 = {kRegister_r13_Code}; |
-const Register r14 = {kRegister_r14_Code}; |
-const Register r15 = {kRegister_r15_Code}; |
- |
-const Register r16 = {kRegister_r16_Code}; |
-const Register r17 = {kRegister_r17_Code}; |
-const Register r18 = {kRegister_r18_Code}; |
-const Register r19 = {kRegister_r19_Code}; |
-const Register r20 = {kRegister_r20_Code}; |
-const Register r21 = {kRegister_r21_Code}; |
-const Register r22 = {kRegister_r22_Code}; |
-const Register r23 = {kRegister_r23_Code}; |
-const Register r24 = {kRegister_r24_Code}; |
-const Register r25 = {kRegister_r25_Code}; |
-const Register r26 = {kRegister_r26_Code}; |
-const Register r27 = {kRegister_r27_Code}; |
-const Register r28 = {kRegister_r28_Code}; |
-const Register r29 = {kRegister_r29_Code}; |
-const Register r30 = {kRegister_r30_Code}; |
-const Register fp = {kRegister_fp_Code}; |
- |
-// Give alias names to registers |
-const Register cp = {kRegister_r30_Code}; // JavaScript context pointer |
-const Register kRootRegister = {kRegister_r29_Code}; // Roots array pointer. |
-const Register kConstantPoolRegister = {kRegister_r28_Code}; // Constant pool |
+#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}; |
+ |
+// Aliases |
+const Register kLithiumScratch = r11; // lithium scratch. |
+const Register kConstantPoolRegister = r28; // Constant pool. |
+const Register kRootRegister = r29; // Roots array pointer. |
+const Register cp = r30; // JavaScript context pointer. |
// Double word FP register. |
struct DoubleRegister { |
- static const int kNumRegisters = 32; |
- static const int kMaxNumRegisters = kNumRegisters; |
- static const int kNumVolatileRegisters = 14; // d0-d13 |
- static const int kSizeInBytes = 8; |
- |
- static const int kAllocatableLowRangeBegin = 1; |
- static const int kAllocatableLowRangeEnd = 12; |
- static const int kAllocatableHighRangeBegin = 15; |
- static const int kAllocatableHighRangeEnd = 31; |
- |
- static const int kNumAllocatableLow = |
- kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1; |
- static const int kNumAllocatableHigh = |
- kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1; |
- static const int kMaxNumAllocatableRegisters = |
- kNumAllocatableLow + kNumAllocatableHigh; |
- static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } |
- |
- // TODO(turbofan) |
- inline static int NumAllocatableAliasedRegisters() { |
- return NumAllocatableRegisters(); |
- } |
- |
- static int ToAllocationIndex(DoubleRegister reg) { |
- int code = reg.code(); |
- int index = (code <= kAllocatableLowRangeEnd) |
- ? code - kAllocatableLowRangeBegin |
- : code - kAllocatableHighRangeBegin + kNumAllocatableLow; |
- DCHECK(index < kMaxNumAllocatableRegisters); |
- return index; |
- } |
- |
- static DoubleRegister FromAllocationIndex(int index) { |
- DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); |
- return (index < kNumAllocatableLow) |
- ? from_code(index + kAllocatableLowRangeBegin) |
- : from_code(index - kNumAllocatableLow + |
- kAllocatableHighRangeBegin); |
- } |
- |
- static const char* AllocationIndexToString(int index); |
- |
- static DoubleRegister from_code(int code) { |
- DoubleRegister r = {code}; |
- return r; |
- } |
+ enum Code { |
+#define REGISTER_CODE(R) kCode_##R, |
+ DOUBLE_REGISTERS(REGISTER_CODE) |
+#undef REGISTER_CODE |
+ kAfterLast, |
+ kCode_no_reg = -1 |
+ }; |
- bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters; } |
- bool is(DoubleRegister reg) const { return code_ == reg.code_; } |
+ static const int kNumRegisters = Code::kAfterLast; |
+ static const int kMaxNumRegisters = kNumRegisters; |
+ const char* ToString(); |
+ bool IsAllocatable() const; |
+ bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } |
+ bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; } |
int code() const { |
DCHECK(is_valid()); |
- return code_; |
+ return reg_code; |
} |
int bit() const { |
DCHECK(is_valid()); |
- return 1 << code_; |
+ return 1 << reg_code; |
} |
- void split_code(int* vm, int* m) const { |
- DCHECK(is_valid()); |
- *m = (code_ & 0x10) >> 4; |
- *vm = code_ & 0x0F; |
+ |
+ static DoubleRegister from_code(int code) { |
+ DoubleRegister r = {code}; |
+ return r; |
} |
- int code_; |
+ int reg_code; |
}; |
- |
-const DoubleRegister no_dreg = {-1}; |
-const DoubleRegister d0 = {0}; |
-const DoubleRegister d1 = {1}; |
-const DoubleRegister d2 = {2}; |
-const DoubleRegister d3 = {3}; |
-const DoubleRegister d4 = {4}; |
-const DoubleRegister d5 = {5}; |
-const DoubleRegister d6 = {6}; |
-const DoubleRegister d7 = {7}; |
-const DoubleRegister d8 = {8}; |
-const DoubleRegister d9 = {9}; |
-const DoubleRegister d10 = {10}; |
-const DoubleRegister d11 = {11}; |
-const DoubleRegister d12 = {12}; |
-const DoubleRegister d13 = {13}; |
-const DoubleRegister d14 = {14}; |
-const DoubleRegister d15 = {15}; |
-const DoubleRegister d16 = {16}; |
-const DoubleRegister d17 = {17}; |
-const DoubleRegister d18 = {18}; |
-const DoubleRegister d19 = {19}; |
-const DoubleRegister d20 = {20}; |
-const DoubleRegister d21 = {21}; |
-const DoubleRegister d22 = {22}; |
-const DoubleRegister d23 = {23}; |
-const DoubleRegister d24 = {24}; |
-const DoubleRegister d25 = {25}; |
-const DoubleRegister d26 = {26}; |
-const DoubleRegister d27 = {27}; |
-const DoubleRegister d28 = {28}; |
-const DoubleRegister d29 = {29}; |
-const DoubleRegister d30 = {30}; |
-const DoubleRegister d31 = {31}; |
+#define DECLARE_REGISTER(R) \ |
+ const DoubleRegister R = {DoubleRegister::kCode_##R}; |
+DOUBLE_REGISTERS(DECLARE_REGISTER) |
+#undef DECLARE_REGISTER |
+const Register no_dreg = {Register::kCode_no_reg}; |
// Aliases for double registers. Defined using #define instead of |
// "static const DoubleRegister&" because Clang complains otherwise when a |
@@ -409,19 +245,19 @@ Register ToRegister(int num); |
// Coprocessor register |
struct CRegister { |
- bool is_valid() const { return 0 <= code_ && code_ < 16; } |
- bool is(CRegister creg) const { return code_ == creg.code_; } |
+ bool is_valid() const { return 0 <= reg_code && reg_code < 16; } |
+ bool is(CRegister creg) const { return reg_code == creg.reg_code; } |
int code() const { |
DCHECK(is_valid()); |
- return code_; |
+ return reg_code; |
} |
int bit() const { |
DCHECK(is_valid()); |
- return 1 << code_; |
+ return 1 << reg_code; |
} |
// Unfortunately we can't make this private in a struct. |
- int code_; |
+ int reg_code; |
}; |