PPC: make simd registers independent of double/fp registers
PPC Simd regs are already using separate set of register banks
on ppc, more details can be found here:
https://crrev.com/c/2718472
Here we are making use of this CL https://crrev.com/c/3005768
(fcd3ef4
) and fully separating Simd regs during register allocation.
Member function `toSimd()` is also introduced which will be used
to cast FP regs to Simd regs in liftoff.
Change-Id: Ic5551fb04f37de7fc9501a2f1aba8fb44f622d95
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3755213
Commit-Queue: Milad Farazmand <mfarazma@redhat.com>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81707}
This commit is contained in:
parent
060f05787c
commit
dda8d86087
@ -42,6 +42,12 @@ namespace internal {
|
||||
#define DOUBLE_REGISTERS(V) \
|
||||
LOW_DOUBLE_REGISTERS(V) NON_LOW_DOUBLE_REGISTERS(V)
|
||||
|
||||
#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)
|
||||
|
||||
#define FLOAT_REGISTERS DOUBLE_REGISTERS
|
||||
#define SIMD128_REGISTERS(V) \
|
||||
V(v0) V(v1) V(v2) V(v3) V(v4) V(v5) V(v6) V(v7) \
|
||||
@ -49,11 +55,11 @@ namespace internal {
|
||||
V(v16) V(v17) V(v18) V(v19) V(v20) V(v21) V(v22) V(v23) \
|
||||
V(v24) V(v25) V(v26) V(v27) V(v28) V(v29) V(v30) V(v31)
|
||||
|
||||
#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)
|
||||
#define ALLOCATABLE_SIMD128_REGISTERS(V) \
|
||||
V(v0) V(v1) V(v2) V(v3) V(v4) V(v5) V(v6) V(v7) \
|
||||
V(v8) V(v9) V(v10) V(v11) V(v12) V(v15) \
|
||||
V(v16) V(v17) V(v18) V(v19) V(v20) V(v21) V(v22) V(v23) \
|
||||
V(v24) V(v25) V(v26) V(v27) V(v28) V(v29) V(v30) V(v31)
|
||||
|
||||
#define C_REGISTERS(V) \
|
||||
V(cr0) V(cr1) V(cr2) V(cr3) V(cr4) V(cr5) V(cr6) V(cr7) \
|
||||
@ -138,41 +144,9 @@ constexpr int ArgumentPaddingSlots(int argument_count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
constexpr AliasingKind kFPAliasing = AliasingKind::kOverlap;
|
||||
constexpr AliasingKind kFPAliasing = AliasingKind::kIndependent;
|
||||
constexpr bool kSimdMaskRegisters = false;
|
||||
|
||||
enum DoubleRegisterCode {
|
||||
#define REGISTER_CODE(R) kDoubleCode_##R,
|
||||
DOUBLE_REGISTERS(REGISTER_CODE)
|
||||
#undef REGISTER_CODE
|
||||
kDoubleAfterLast
|
||||
};
|
||||
|
||||
// Double word FP register.
|
||||
class DoubleRegister : public RegisterBase<DoubleRegister, kDoubleAfterLast> {
|
||||
public:
|
||||
// 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 constexpr int kSizeInBytes = 8;
|
||||
|
||||
// This function differs from kNumRegisters by returning the number of double
|
||||
// registers supported by the current CPU, while kNumRegisters always returns
|
||||
// 32.
|
||||
inline static int SupportedRegisterCount();
|
||||
|
||||
private:
|
||||
friend class RegisterBase;
|
||||
explicit constexpr DoubleRegister(int code) : RegisterBase(code) {}
|
||||
};
|
||||
|
||||
ASSERT_TRIVIALLY_COPYABLE(DoubleRegister);
|
||||
static_assert(sizeof(DoubleRegister) <= sizeof(int),
|
||||
"DoubleRegister can efficiently be passed by value");
|
||||
|
||||
using FloatRegister = DoubleRegister;
|
||||
|
||||
// | | 0
|
||||
// | | 1
|
||||
// | | 2
|
||||
@ -206,14 +180,55 @@ enum Simd128RegisterCode {
|
||||
// Simd128 register.
|
||||
class Simd128Register
|
||||
: public RegisterBase<Simd128Register, kSimd128AfterLast> {
|
||||
private:
|
||||
friend class RegisterBase;
|
||||
|
||||
public:
|
||||
explicit constexpr Simd128Register(int code) : RegisterBase(code) {}
|
||||
};
|
||||
ASSERT_TRIVIALLY_COPYABLE(Simd128Register);
|
||||
static_assert(sizeof(Simd128Register) <= sizeof(int),
|
||||
"Simd128Register can efficiently be passed by value");
|
||||
|
||||
enum DoubleRegisterCode {
|
||||
#define REGISTER_CODE(R) kDoubleCode_##R,
|
||||
DOUBLE_REGISTERS(REGISTER_CODE)
|
||||
#undef REGISTER_CODE
|
||||
kDoubleAfterLast
|
||||
};
|
||||
|
||||
// Double word FP register.
|
||||
class DoubleRegister : public RegisterBase<DoubleRegister, kDoubleAfterLast> {
|
||||
public:
|
||||
// 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 constexpr int kSizeInBytes = 8;
|
||||
|
||||
// This function differs from kNumRegisters by returning the number of double
|
||||
// registers supported by the current CPU, while kNumRegisters always returns
|
||||
// 32.
|
||||
inline static int SupportedRegisterCount();
|
||||
|
||||
// On PPC Simdi128 registers are separate from Double registers.
|
||||
// More details can be found here: https://crrev.com/c/2718472 . This is a
|
||||
// helper function to cast a Double to a Simdi128 register.
|
||||
Simd128Register toSimd() const {
|
||||
DCHECK(base::IsInRange(static_cast<int>(code()), 0, kSimd128AfterLast - 1));
|
||||
return Simd128Register(code());
|
||||
}
|
||||
|
||||
private:
|
||||
friend class RegisterBase;
|
||||
explicit constexpr DoubleRegister(int code) : RegisterBase(code) {}
|
||||
};
|
||||
|
||||
ASSERT_TRIVIALLY_COPYABLE(DoubleRegister);
|
||||
static_assert(sizeof(DoubleRegister) <= sizeof(int),
|
||||
"DoubleRegister can efficiently be passed by value");
|
||||
|
||||
using FloatRegister = DoubleRegister;
|
||||
|
||||
#define DECLARE_SIMD128_REGISTER(R) \
|
||||
constexpr Simd128Register R = Simd128Register::from_code(kSimd128Code_##R);
|
||||
SIMD128_REGISTERS(DECLARE_SIMD128_REGISTER)
|
||||
@ -230,8 +245,6 @@ constexpr DoubleRegister kFirstCalleeSavedDoubleReg = d14;
|
||||
constexpr DoubleRegister kLastCalleeSavedDoubleReg = d31;
|
||||
constexpr DoubleRegister kDoubleRegZero = d14;
|
||||
constexpr DoubleRegister kScratchDoubleReg = d13;
|
||||
// Simd128 zero and scratch regs must have the same numbers as Double zero and
|
||||
// scratch
|
||||
constexpr Simd128Register kSimd128RegZero = v14;
|
||||
constexpr Simd128Register kScratchSimd128Reg = v13;
|
||||
|
||||
|
@ -46,8 +46,9 @@ const int kNumCalleeSaved = 18;
|
||||
const DoubleRegList kCallerSavedDoubles = {d0, d1, d2, d3, d4, d5, d6,
|
||||
d7, d8, d9, d10, d11, d12, d13};
|
||||
|
||||
const Simd128RegList kCallerSavedSimd128s = {v0, v1, v2, v3, v4, v5, v6,
|
||||
v7, v8, v9, v10, v11, v12, v13};
|
||||
const Simd128RegList kCallerSavedSimd128s = {v0, v1, v2, v3, v4, v5, v6,
|
||||
v7, v8, v9, v10, v11, v12, v13,
|
||||
v14, v15, v16, v17, v18, v19};
|
||||
|
||||
const int kNumCallerSavedDoubles = 14;
|
||||
|
||||
|
@ -19,7 +19,7 @@ static const int kMaxAllocatableGeneralRegisterCount =
|
||||
ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT) 0;
|
||||
static const int kMaxAllocatableDoubleRegisterCount =
|
||||
ALLOCATABLE_DOUBLE_REGISTERS(REGISTER_COUNT) 0;
|
||||
#if V8_TARGET_ARCH_RISCV64
|
||||
#if V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
|
||||
static const int kMaxAllocatableSIMD128RegisterCount =
|
||||
ALLOCATABLE_SIMD128_REGISTERS(REGISTER_COUNT) 0;
|
||||
#endif
|
||||
@ -38,12 +38,16 @@ static const int kAllocatableNoVFP32DoubleCodes[] = {
|
||||
#endif // V8_TARGET_ARCH_ARM
|
||||
#undef REGISTER_CODE
|
||||
|
||||
#if V8_TARGET_ARCH_RISCV64
|
||||
#if V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
|
||||
static const int kAllocatableSIMD128Codes[] = {
|
||||
#if V8_TARGET_ARCH_RISCV64
|
||||
#define REGISTER_CODE(R) kVRCode_##R,
|
||||
#else
|
||||
#define REGISTER_CODE(R) kSimd128Code_##R,
|
||||
#endif
|
||||
ALLOCATABLE_SIMD128_REGISTERS(REGISTER_CODE)};
|
||||
#undef REGISTER_CODE
|
||||
#endif // V8_TARGET_ARCH_RISCV64
|
||||
#endif // V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
|
||||
|
||||
static_assert(RegisterConfiguration::kMaxGeneralRegisters >=
|
||||
Register::kNumRegisters);
|
||||
@ -56,11 +60,11 @@ static_assert(RegisterConfiguration::kMaxFPRegisters >=
|
||||
|
||||
static int get_num_simd128_registers() {
|
||||
return
|
||||
#if V8_TARGET_ARCH_RISCV64
|
||||
#if V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
|
||||
Simd128Register::kNumRegisters;
|
||||
#else
|
||||
0;
|
||||
#endif // V8_TARGET_ARCH_RISCV64
|
||||
#endif // V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
|
||||
}
|
||||
|
||||
// Callers on architectures other than Arm expect this to be be constant
|
||||
@ -100,7 +104,7 @@ static int get_num_allocatable_double_registers() {
|
||||
|
||||
static int get_num_allocatable_simd128_registers() {
|
||||
return
|
||||
#if V8_TARGET_ARCH_RISCV64
|
||||
#if V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
|
||||
kMaxAllocatableSIMD128RegisterCount;
|
||||
#else
|
||||
0;
|
||||
@ -121,7 +125,7 @@ static const int* get_allocatable_double_codes() {
|
||||
|
||||
static const int* get_allocatable_simd128_codes() {
|
||||
return
|
||||
#if V8_TARGET_ARCH_RISCV64
|
||||
#if V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
|
||||
kAllocatableSIMD128Codes;
|
||||
#else
|
||||
kAllocatableDoubleCodes;
|
||||
|
Loading…
Reference in New Issue
Block a user