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:
parent
a851275912
commit
98c242cefb
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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(); }
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user