PPC: [wasm-simd] Implement simd FP Splat

This CL introduces VOR and VSRO opcodes which get used
for implementing F64x2Splat, I64x2Splat and F32x4Splat.

Change-Id: I64b4cd340fbe9ecf6a789a91e3219b6ad83ce3f3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2184830
Reviewed-by: Junliang Yan <jyan@ca.ibm.com>
Commit-Queue: Milad Farazmand <miladfar@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#67627}
This commit is contained in:
Milad Farazmand 2020-05-06 16:37:50 +00:00 committed by Commit Bot
parent a851275912
commit 98c242cefb
7 changed files with 70 additions and 7 deletions

View File

@ -1763,6 +1763,16 @@ void Assembler::mtvsrd(const DoubleRegister rt, const Register ra) {
emit(MTVSRD | rt.code() * B21 | ra.code() * B16 | TX);
}
void Assembler::vor(const DoubleRegister rt, const DoubleRegister ra,
const DoubleRegister rb) {
emit(VOR | rt.code() * B21 | ra.code() * B16 | rb.code() * B11);
}
void Assembler::vsro(const DoubleRegister rt, const DoubleRegister ra,
const DoubleRegister rb) {
emit(VSRO | rt.code() * B21 | ra.code() * B16 | rb.code() * B11);
}
// Pseudo instructions.
void Assembler::nop(int type) {
Register reg = r0;

View File

@ -936,6 +936,10 @@ class Assembler : public AssemblerBase {
// Vector instructions
void mtvsrd(const DoubleRegister rt, const Register ra);
void vor(const DoubleRegister rt, const DoubleRegister ra,
const DoubleRegister rb);
void vsro(const DoubleRegister rt, const DoubleRegister ra,
const DoubleRegister rb);
// Pseudo instructions

View File

@ -2145,6 +2145,43 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
#endif // V8_TARGET_ARCH_PPC64
case kPPC_F64x2Splat: {
Simd128Register dst = i.OutputSimd128Register();
constexpr int shift_bits = 64;
__ MovDoubleToInt64(r0, i.InputDoubleRegister(0));
__ mtvsrd(dst, r0);
// right shift
__ li(ip, Operand(shift_bits));
__ mtvsrd(kScratchDoubleReg, ip);
__ vspltb(kScratchDoubleReg, kScratchDoubleReg, Operand(7));
__ vsro(dst, dst, kScratchDoubleReg);
// reload
__ mtvsrd(kScratchDoubleReg, r0);
__ vor(dst, dst, kScratchDoubleReg);
break;
}
case kPPC_F32x4Splat: {
Simd128Register dst = i.OutputSimd128Register();
__ MovFloatToInt(kScratchReg, i.InputDoubleRegister(0));
__ mtvsrd(dst, kScratchReg);
__ vspltw(dst, dst, Operand(1));
break;
}
case kPPC_I64x2Splat: {
Register src = i.InputRegister(0);
Simd128Register dst = i.OutputSimd128Register();
constexpr int shift_bits = 64;
__ mtvsrd(dst, src);
// right shift
__ li(ip, Operand(shift_bits));
__ mtvsrd(kScratchDoubleReg, ip);
__ vspltb(kScratchDoubleReg, kScratchDoubleReg, Operand(7));
__ vsro(dst, dst, kScratchDoubleReg);
// reload
__ mtvsrd(kScratchDoubleReg, src);
__ vor(dst, dst, kScratchDoubleReg);
break;
}
case kPPC_I32x4Splat: {
Simd128Register dst = i.OutputSimd128Register();
__ mtvsrd(dst, i.InputRegister(0));

View File

@ -190,6 +190,9 @@ namespace compiler {
V(PPC_AtomicXorInt16) \
V(PPC_AtomicXorInt32) \
V(PPC_AtomicXorInt64) \
V(PPC_F64x2Splat) \
V(PPC_F32x4Splat) \
V(PPC_I64x2Splat) \
V(PPC_I32x4Splat) \
V(PPC_I16x8Splat) \
V(PPC_I8x16Splat)

View File

@ -113,6 +113,9 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_CompressSigned:
case kPPC_CompressPointer:
case kPPC_CompressAny:
case kPPC_F64x2Splat:
case kPPC_F32x4Splat:
case kPPC_I64x2Splat:
case kPPC_I32x4Splat:
case kPPC_I16x8Splat:
case kPPC_I8x16Splat:

View File

@ -2101,6 +2101,8 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
}
#define SIMD_TYPES(V) \
V(F64x2) \
V(F32x4) \
V(I32x4) \
V(I16x8) \
V(I8x16)
@ -2288,8 +2290,6 @@ void InstructionSelector::VisitF32x4Lt(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Le(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Splat(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::EmitPrepareResults(
@ -2432,8 +2432,6 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitS8x16Swizzle(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Splat(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2ReplaceLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Abs(Node* node) { UNIMPLEMENTED(); }

View File

@ -360,15 +360,23 @@ void Decoder::UnknownFormat(Instruction* instr, const char* name) {
void Decoder::DecodeExt0(Instruction* instr) {
switch (EXT0 | (instr->BitField(10, 0))) {
case VSPLTB: {
Format(instr, "vspltb 'Dt, 'Db, 'UIM");
Format(instr, "vspltb 'Dt, 'Db, 'UIM");
break;
}
case VSPLTW: {
Format(instr, "vspltw 'Dt, 'Db, 'UIM");
Format(instr, "vspltw 'Dt, 'Db, 'UIM");
break;
}
case VSPLTH: {
Format(instr, "vsplth 'Dt, 'Db, 'UIM");
Format(instr, "vsplth 'Dt, 'Db, 'UIM");
break;
}
case VSRO: {
Format(instr, "vsro 'Dt, 'Da, 'Db");
break;
}
case VOR: {
Format(instr, "vor 'Dt, 'Da, 'Db");
break;
}
}