| 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;
|
| };
|
|
|
|
|
|
|