summaryrefslogtreecommitdiff
path: root/deps/v8/src/ppc/assembler-ppc.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ppc/assembler-ppc.h')
-rw-r--r--deps/v8/src/ppc/assembler-ppc.h396
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_