PPC: [wasm-simd] Add Simd128 registers to register-ppc

Simd128Registers::names_ is also removed as the stringification
will be done by DEFINE_REGISTER_NAMES.

PPC FP and Vector Register (VR and VSR) Layou:

VR0 is VSR32 and goes all the way to VSR63 which is used by V8 Vector
operations.

VSR[0]0 - FPR[0]                     VSR[0]128
  |
  |
  |
VSR[31] - FPR[31]
VSR[32] - VR[0]                      VR[0]128
  |
  |
  |
  V
VSR[63] - VR[31]

Change-Id: Ied2a530b08d1eb40af59ce44f848d638f2a6dc9f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2587356
Reviewed-by: Junliang Yan <junyan@redhat.com>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#71735}
This commit is contained in:
Milad Fa 2020-12-11 17:47:39 -05:00 committed by Commit Bot
parent a1fc8a1b85
commit c277b558ab
7 changed files with 313 additions and 309 deletions

View File

@ -444,14 +444,14 @@ class Assembler : public AssemblerBase {
PPC_XX2_OPCODE_A_FORM_LIST(DECLARE_PPC_XX2_INSTRUCTIONS)
#undef DECLARE_PPC_XX2_INSTRUCTIONS
#define DECLARE_PPC_XX3_INSTRUCTIONS(name, instr_name, instr_value) \
inline void name(const DoubleRegister rt, const DoubleRegister ra, \
const DoubleRegister rb) { \
xx3_form(instr_name, rt, ra, rb); \
#define DECLARE_PPC_XX3_INSTRUCTIONS(name, instr_name, instr_value) \
inline void name(const Simd128Register rt, const Simd128Register ra, \
const Simd128Register rb) { \
xx3_form(instr_name, rt, ra, rb); \
}
inline void xx3_form(Instr instr, DoubleRegister t, DoubleRegister a,
DoubleRegister b) {
inline void xx3_form(Instr instr, Simd128Register t, Simd128Register a,
Simd128Register b) {
// Using VR (high VSR) registers.
int AX = 1;
int BX = 1;

View File

@ -21,27 +21,6 @@ const char* DoubleRegisters::names_[kNumDoubleRegisters] = {
"d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21",
"d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
// PPC FP and Vector Register (VR and VSR) Layout.
// VR0 is VSR32 and goes all the way to VSR63 which is used by V8 Vector
// operations.
//
// VSR[0]0 - FPR[0] VSR[0]128
// |
// |
// |
// VSR[31] - FPR[31]
// VSR[32] - VR[0] VR[0]128
// |
// |
// |
// V
// VSR[63] - VR[31]
const char* Simd128Registers::names_[kNumSimd128Registers] = {
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
"v24", "vr25", "v26", "v27", "v28", "v29", "v30", "v31"};
int DoubleRegisters::Number(const char* name) {
for (int i = 0; i < kNumDoubleRegisters; i++) {
if (strcmp(names_[i], name) == 0) {

View File

@ -74,9 +74,6 @@ const int kNumRegisters = 32;
// FP support.
const int kNumDoubleRegisters = 32;
// Vector support.
const int kNumSimd128Registers = 32;
const int kNoRegister = -1;
// Used in embedded constant pool builder - max reach in bits for
@ -3047,12 +3044,6 @@ class DoubleRegisters {
private:
static const char* names_[kNumDoubleRegisters];
};
// Helper functions for converting between Vector register names.
class Simd128Registers {
public:
static const char* names_[kNumSimd128Registers];
};
} // namespace internal
} // namespace v8

View File

@ -3168,40 +3168,40 @@ void TurboAssembler::SwapSimd128(Simd128Register src, Simd128Register dst,
void TurboAssembler::SwapSimd128(Simd128Register src, MemOperand dst,
Simd128Register scratch) {
DCHECK(!AreAliased(src, scratch));
// push d0, to be used as scratch
DCHECK(src != scratch);
// push v0, to be used as scratch
addi(sp, sp, Operand(-kSimd128Size));
StoreSimd128(d0, MemOperand(r0, sp), r0, scratch);
StoreSimd128(v0, MemOperand(r0, sp), r0, scratch);
mov(ip, Operand(dst.offset()));
LoadSimd128(d0, MemOperand(dst.ra(), ip), r0, scratch);
LoadSimd128(v0, MemOperand(dst.ra(), ip), r0, scratch);
StoreSimd128(src, MemOperand(dst.ra(), ip), r0, scratch);
vor(src, d0, d0);
// restore d0
LoadSimd128(d0, MemOperand(r0, sp), ip, scratch);
vor(src, v0, v0);
// restore v0
LoadSimd128(v0, MemOperand(r0, sp), ip, scratch);
addi(sp, sp, Operand(kSimd128Size));
}
void TurboAssembler::SwapSimd128(MemOperand src, MemOperand dst,
Simd128Register scratch) {
// push d0 and d1, to be used as scratch
// push v0 and v1, to be used as scratch
addi(sp, sp, Operand(2 * -kSimd128Size));
StoreSimd128(d0, MemOperand(r0, sp), ip, scratch);
StoreSimd128(v0, MemOperand(r0, sp), ip, scratch);
li(ip, Operand(kSimd128Size));
StoreSimd128(d1, MemOperand(ip, sp), r0, scratch);
StoreSimd128(v1, MemOperand(ip, sp), r0, scratch);
mov(ip, Operand(src.offset()));
LoadSimd128(d0, MemOperand(src.ra(), ip), r0, scratch);
LoadSimd128(v0, MemOperand(src.ra(), ip), r0, scratch);
mov(ip, Operand(dst.offset()));
LoadSimd128(d1, MemOperand(dst.ra(), ip), r0, scratch);
LoadSimd128(v1, MemOperand(dst.ra(), ip), r0, scratch);
StoreSimd128(d0, MemOperand(dst.ra(), ip), r0, scratch);
StoreSimd128(v0, MemOperand(dst.ra(), ip), r0, scratch);
mov(ip, Operand(src.offset()));
StoreSimd128(d1, MemOperand(src.ra(), ip), r0, scratch);
StoreSimd128(v1, MemOperand(src.ra(), ip), r0, scratch);
// restore d0 and d1
LoadSimd128(d0, MemOperand(r0, sp), ip, scratch);
// restore v0 and v1
LoadSimd128(v0, MemOperand(r0, sp), ip, scratch);
li(ip, Operand(kSimd128Size));
LoadSimd128(d1, MemOperand(ip, sp), r0, scratch);
LoadSimd128(v1, MemOperand(ip, sp), r0, scratch);
addi(sp, sp, Operand(2 * kSimd128Size));
}

View File

@ -44,7 +44,11 @@ namespace internal {
LOW_DOUBLE_REGISTERS(V) NON_LOW_DOUBLE_REGISTERS(V)
#define FLOAT_REGISTERS DOUBLE_REGISTERS
#define SIMD128_REGISTERS DOUBLE_REGISTERS
#define 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(v13) V(v14) 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 ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
@ -245,8 +249,29 @@ static_assert(sizeof(DoubleRegister) == sizeof(int),
using FloatRegister = DoubleRegister;
// TODO(ppc) Define SIMD registers.
using Simd128Register = DoubleRegister;
enum Simd128RegisterCode {
#define REGISTER_CODE(R) kSimd128Code_##R,
SIMD128_REGISTERS(REGISTER_CODE)
#undef REGISTER_CODE
kSimd128AfterLast
};
// Simd128 register.
class Simd128Register
: public RegisterBase<Simd128Register, kSimd128AfterLast> {
private:
friend class RegisterBase;
explicit constexpr Simd128Register(int code) : RegisterBase(code) {}
};
ASSERT_TRIVIALLY_COPYABLE(Simd128Register);
static_assert(sizeof(Simd128Register) == sizeof(int),
"Simd128Register can efficiently be passed by value");
#define DECLARE_SIMD128_REGISTER(R) \
constexpr Simd128Register R = Simd128Register::from_code(kSimd128Code_##R);
SIMD128_REGISTERS(DECLARE_SIMD128_REGISTER)
#undef DECLARE_SIMD128_REGISTER
const Simd128Register no_simdreg = Simd128Register::no_reg();
#define DEFINE_REGISTER(R) \
constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R);
@ -258,6 +283,10 @@ 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;
Register ToRegister(int num);
@ -283,6 +312,7 @@ C_REGISTERS(DECLARE_C_REGISTER)
// Define {RegisterName} methods for the register types.
DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS)
DEFINE_REGISTER_NAMES(DoubleRegister, DOUBLE_REGISTERS)
DEFINE_REGISTER_NAMES(Simd128Register, SIMD128_REGISTERS)
// Give alias names to registers for calling conventions.
constexpr Register kReturnRegister0 = r3;

File diff suppressed because it is too large Load Diff

View File

@ -120,7 +120,10 @@ void Decoder::PrintDRegister(int reg) {
Print(RegisterName(DoubleRegister::from_code(reg)));
}
void Decoder::PrintVectorRegister(int reg) { Print(NameOfVectorRegister(reg)); }
// Print the Simd128 register name according to the active name converter.
void Decoder::PrintVectorRegister(int reg) {
Print(RegisterName(Simd128Register::from_code(reg)));
}
// Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
// the FormatOption method.
@ -143,11 +146,6 @@ void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
}
}
const char* Decoder::NameOfVectorRegister(int reg) const {
if (0 <= reg && reg < 32) return Simd128Registers::names_[reg];
return "novectorreg";
}
// Handle all register based formatting in this function to reduce the
// complexity of FormatOption.
int Decoder::FormatRegister(Instruction* instr, const char* format) {