diff options
Diffstat (limited to 'deps/v8/src/ppc/assembler-ppc.h')
-rw-r--r-- | deps/v8/src/ppc/assembler-ppc.h | 396 |
1 files changed, 119 insertions, 277 deletions
diff --git a/deps/v8/src/ppc/assembler-ppc.h b/deps/v8/src/ppc/assembler-ppc.h index a1c08ad0ea..36843c17ab 100644 --- a/deps/v8/src/ppc/assembler-ppc.h +++ b/deps/v8/src/ppc/assembler-ppc.h @@ -44,7 +44,6 @@ #include <vector> #include "src/assembler.h" -#include "src/compiler.h" #include "src/ppc/constants-ppc.h" #define ABI_USES_FUNCTION_DESCRIPTORS \ @@ -61,9 +60,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 +70,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 +125,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 - - 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; - } + enum Code { +#define REGISTER_CODE(R) kCode_##R, + GENERAL_REGISTERS(REGISTER_CODE) +#undef REGISTER_CODE + kAfterLast, + kCode_no_reg = -1 + }; - 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 int kNumRegisters = Code::kAfterLast; - 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 +244,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; }; @@ -1072,6 +907,7 @@ class Assembler : public AssemblerBase { void rotldi(Register ra, Register rs, int sh, RCBit r = LeaveRC); void rotrdi(Register ra, Register rs, int sh, RCBit r = LeaveRC); void cntlzd_(Register dst, Register src, RCBit rc = LeaveRC); + void popcntd(Register dst, Register src); void mulld(Register dst, Register src1, Register src2, OEBit o = LeaveOE, RCBit r = LeaveRC); void divd(Register dst, Register src1, Register src2, OEBit o = LeaveOE, @@ -1101,6 +937,7 @@ class Assembler : public AssemblerBase { void rotrwi(Register ra, Register rs, int sh, RCBit r = LeaveRC); void cntlzw_(Register dst, Register src, RCBit rc = LeaveRC); + void popcntw(Register dst, Register src); void subi(Register dst, Register src1, const Operand& src2); @@ -1213,6 +1050,8 @@ class Assembler : public AssemblerBase { RCBit rc = LeaveRC); void fcfid(const DoubleRegister frt, const DoubleRegister frb, RCBit rc = LeaveRC); + void fcfids(const DoubleRegister frt, const DoubleRegister frb, + RCBit rc = LeaveRC); void fctid(const DoubleRegister frt, const DoubleRegister frb, RCBit rc = LeaveRC); void fctidz(const DoubleRegister frt, const DoubleRegister frb, @@ -1471,7 +1310,10 @@ class Assembler : public AssemblerBase { } void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; } - void EndBlockTrampolinePool() { trampoline_pool_blocked_nesting_--; } + void EndBlockTrampolinePool() { + int count = --trampoline_pool_blocked_nesting_; + if (count == 0) CheckTrampolinePoolQuick(); + } bool is_trampoline_pool_blocked() const { return trampoline_pool_blocked_nesting_ > 0; } @@ -1612,7 +1454,7 @@ class EnsureSpace BASE_EMBEDDED { public: explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } }; -} -} // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_PPC_ASSEMBLER_PPC_H_ |