diff --git a/src/codegen/ppc/assembler-ppc.cc b/src/codegen/ppc/assembler-ppc.cc index 37a53b49f2..66f27c6bc6 100644 --- a/src/codegen/ppc/assembler-ppc.cc +++ b/src/codegen/ppc/assembler-ppc.cc @@ -1777,6 +1777,12 @@ void Assembler::mtvsrd(const Simd128Register rt, const Register ra) { emit(MTVSRD | rt.code() * B21 | ra.code() * B16 | TX); } +void Assembler::mtvsrdd(const Simd128Register rt, const Register ra, + const Register rb) { + int TX = 1; + emit(MTVSRDD | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 | TX); +} + void Assembler::lxvd(const Simd128Register rt, const MemOperand& src) { int TX = 1; emit(LXVD | rt.code() * B21 | src.ra().code() * B16 | src.rb().code() * B11 | diff --git a/src/codegen/ppc/assembler-ppc.h b/src/codegen/ppc/assembler-ppc.h index f26a3c89c9..7d3f7facd6 100644 --- a/src/codegen/ppc/assembler-ppc.h +++ b/src/codegen/ppc/assembler-ppc.h @@ -1019,6 +1019,7 @@ class Assembler : public AssemblerBase { void mfvsrd(const Register ra, const Simd128Register r); void mfvsrwz(const Register ra, const Simd128Register r); void mtvsrd(const Simd128Register rt, const Register ra); + void mtvsrdd(const Simd128Register rt, const Register ra, const Register rb); void lxvd(const Simd128Register rt, const MemOperand& src); void stxvd(const Simd128Register rt, const MemOperand& src); diff --git a/src/codegen/ppc/constants-ppc.h b/src/codegen/ppc/constants-ppc.h index 306175e06d..a5ad546d7a 100644 --- a/src/codegen/ppc/constants-ppc.h +++ b/src/codegen/ppc/constants-ppc.h @@ -414,6 +414,8 @@ using Instr = uint32_t; V(xssqrtsp, XSSQRTSP, 0xF000002C) \ /* Move To VSR Doubleword */ \ V(mtvsrd, MTVSRD, 0x7C000166) \ + /* Move To VSR Double Doubleword */ \ + V(mtvsrdd, MTVSRDD, 0x7C000366) \ /* Move To VSR Word Algebraic */ \ V(mtvsrwa, MTVSRWA, 0x7C0001A6) \ /* Move To VSR Word and Zero */ \ @@ -2202,13 +2204,17 @@ using Instr = uint32_t; /* Rotate Left Word then AND with Mask */ \ V(rlwnm, RLWNMX, 0x5C000000) -#define PPC_VX_OPCODE_A_FORM_LIST(V) \ - /* Vector Splat Byte */ \ - V(vspltb, VSPLTB, 0x1000020C) \ - /* Vector Splat Word */ \ - V(vspltw, VSPLTW, 0x1000028C) \ - /* Vector Splat Halfword */ \ - V(vsplth, VSPLTH, 0x1000024C) +#define PPC_VX_OPCODE_A_FORM_LIST(V) \ + /* Vector Splat Byte */ \ + V(vspltb, VSPLTB, 0x1000020C) \ + /* Vector Splat Word */ \ + V(vspltw, VSPLTW, 0x1000028C) \ + /* Vector Splat Halfword */ \ + V(vsplth, VSPLTH, 0x1000024C) \ + /* Vector Extract Unsigned Byte */ \ + V(vextractub, VEXTRACTUB, 0x1000020d) \ + /* Vector Extract Unsigned Halfword */ \ + V(vextractuh, VEXTRACTUH, 0x1000024D) #define PPC_VX_OPCODE_B_FORM_LIST(V) \ /* Vector Logical OR */ \ @@ -2348,7 +2354,9 @@ using Instr = uint32_t; /* Vector Minimum Single-Precision */ \ V(vminfp, VMINFP, 0x1000044A) \ /* Vector Maximum Single-Precision */ \ - V(vmaxfp, VMAXFP, 0x1000040A) + V(vmaxfp, VMAXFP, 0x1000040A) \ + /* Vector Bit Permute Quadword */ \ + V(vbpermq, VBPERMQ, 0x1000054C) #define PPC_VX_OPCODE_C_FORM_LIST(V) \ /* Vector Unpack Low Signed Halfword */ \ @@ -2387,8 +2395,6 @@ using Instr = uint32_t; V(vavgsw, VAVGSW, 0x10000582) \ /* Vector Average Unsigned Word */ \ V(vavguw, VAVGUW, 0x10000482) \ - /* Vector Bit Permute Quadword */ \ - V(vbpermq, VBPERMQ, 0x1000054C) \ /* Vector Convert From Signed Fixed-Point Word To Single-Precision */ \ V(vcfsx, VCFSX, 0x1000034A) \ /* Vector Convert From Unsigned Fixed-Point Word To Single-Precision */ \ diff --git a/src/compiler/backend/ppc/code-generator-ppc.cc b/src/compiler/backend/ppc/code-generator-ppc.cc index 767247b2fd..9af1617519 100644 --- a/src/compiler/backend/ppc/code-generator-ppc.cc +++ b/src/compiler/backend/ppc/code-generator-ppc.cc @@ -3438,6 +3438,36 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ xvrspi(i.OutputSimd128Register(), i.InputSimd128Register(0)); break; } + case kPPC_I32x4BitMask: { + __ mov(kScratchReg, + Operand(0x8080808000204060)); // Select 0 for the high bits. + __ mtvsrd(kScratchDoubleReg, kScratchReg); + __ vbpermq(kScratchDoubleReg, i.InputSimd128Register(0), + kScratchDoubleReg); + __ vextractub(kScratchDoubleReg, kScratchDoubleReg, Operand(6)); + __ mfvsrd(i.OutputRegister(), kScratchDoubleReg); + break; + } + case kPPC_I16x8BitMask: { + __ mov(kScratchReg, Operand(0x10203040506070)); + __ mtvsrd(kScratchDoubleReg, kScratchReg); + __ vbpermq(kScratchDoubleReg, i.InputSimd128Register(0), + kScratchDoubleReg); + __ vextractub(kScratchDoubleReg, kScratchDoubleReg, Operand(6)); + __ mfvsrd(i.OutputRegister(), kScratchDoubleReg); + break; + } + case kPPC_I8x16BitMask: { + Register temp = i.ToRegister(instr->TempAt(0)); + __ mov(temp, Operand(0x8101820283038)); + __ mov(ip, Operand(0x4048505860687078)); + __ mtvsrdd(kScratchDoubleReg, temp, ip); + __ vbpermq(kScratchDoubleReg, i.InputSimd128Register(0), + kScratchDoubleReg); + __ vextractuh(kScratchDoubleReg, kScratchDoubleReg, Operand(6)); + __ mfvsrd(i.OutputRegister(), kScratchDoubleReg); + break; + } case kPPC_StoreCompressTagged: { ASSEMBLE_STORE_INTEGER(StoreTaggedField, StoreTaggedFieldX); break; diff --git a/src/compiler/backend/ppc/instruction-codes-ppc.h b/src/compiler/backend/ppc/instruction-codes-ppc.h index fb5151ebd4..6999589d9c 100644 --- a/src/compiler/backend/ppc/instruction-codes-ppc.h +++ b/src/compiler/backend/ppc/instruction-codes-ppc.h @@ -287,6 +287,7 @@ namespace compiler { V(PPC_I32x4SConvertI16x8High) \ V(PPC_I32x4UConvertI16x8Low) \ V(PPC_I32x4UConvertI16x8High) \ + V(PPC_I32x4BitMask) \ V(PPC_F32x4Qfma) \ V(PPC_F32x4Qfms) \ V(PPC_I16x8Splat) \ @@ -323,6 +324,7 @@ namespace compiler { V(PPC_I16x8AddSaturateU) \ V(PPC_I16x8SubSaturateU) \ V(PPC_I16x8RoundingAverageU) \ + V(PPC_I16x8BitMask) \ V(PPC_I8x16Splat) \ V(PPC_I8x16ExtractLaneU) \ V(PPC_I8x16ExtractLaneS) \ @@ -354,6 +356,7 @@ namespace compiler { V(PPC_I8x16RoundingAverageU) \ V(PPC_I8x16Shuffle) \ V(PPC_I8x16Swizzle) \ + V(PPC_I8x16BitMask) \ V(PPC_V64x2AnyTrue) \ V(PPC_V32x4AnyTrue) \ V(PPC_V16x8AnyTrue) \ diff --git a/src/compiler/backend/ppc/instruction-scheduler-ppc.cc b/src/compiler/backend/ppc/instruction-scheduler-ppc.cc index 8beaa8539c..7a0735533b 100644 --- a/src/compiler/backend/ppc/instruction-scheduler-ppc.cc +++ b/src/compiler/backend/ppc/instruction-scheduler-ppc.cc @@ -212,6 +212,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kPPC_I32x4SConvertI16x8High: case kPPC_I32x4UConvertI16x8Low: case kPPC_I32x4UConvertI16x8High: + case kPPC_I32x4BitMask: case kPPC_I16x8Splat: case kPPC_I16x8ExtractLaneU: case kPPC_I16x8ExtractLaneS: @@ -246,6 +247,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kPPC_I16x8AddSaturateU: case kPPC_I16x8SubSaturateU: case kPPC_I16x8RoundingAverageU: + case kPPC_I16x8BitMask: case kPPC_I8x16Splat: case kPPC_I8x16ExtractLaneU: case kPPC_I8x16ExtractLaneS: @@ -277,6 +279,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kPPC_I8x16RoundingAverageU: case kPPC_I8x16Shuffle: case kPPC_I8x16Swizzle: + case kPPC_I8x16BitMask: case kPPC_V64x2AnyTrue: case kPPC_V32x4AnyTrue: case kPPC_V16x8AnyTrue: diff --git a/src/compiler/backend/ppc/instruction-selector-ppc.cc b/src/compiler/backend/ppc/instruction-selector-ppc.cc index 0c61821cf5..9266e100dc 100644 --- a/src/compiler/backend/ppc/instruction-selector-ppc.cc +++ b/src/compiler/backend/ppc/instruction-selector-ppc.cc @@ -2378,6 +2378,18 @@ SIMD_SHIFT_LIST(SIMD_VISIT_SHIFT) SIMD_BOOL_LIST(SIMD_VISIT_BOOL) #undef SIMD_VISIT_BOOL #undef SIMD_BOOL_LIST + +#define SIMD_VISIT_BITMASK(Opcode) \ + void InstructionSelector::Visit##Opcode(Node* node) { \ + PPCOperandGenerator g(this); \ + InstructionOperand temps[] = {g.TempRegister()}; \ + Emit(kPPC_##Opcode, g.DefineAsRegister(node), \ + g.UseUniqueRegister(node->InputAt(0)), arraysize(temps), temps); \ + } +SIMD_VISIT_BITMASK(I8x16BitMask) +SIMD_VISIT_BITMASK(I16x8BitMask) +SIMD_VISIT_BITMASK(I32x4BitMask) +#undef SIMD_VISIT_BITMASK #undef SIMD_TYPES void InstructionSelector::VisitI8x16Shuffle(Node* node) { @@ -2419,12 +2431,6 @@ void InstructionSelector::VisitS128Select(Node* node) { void InstructionSelector::VisitS128Const(Node* node) { UNIMPLEMENTED(); } -void InstructionSelector::VisitI8x16BitMask(Node* node) { UNIMPLEMENTED(); } - -void InstructionSelector::VisitI16x8BitMask(Node* node) { UNIMPLEMENTED(); } - -void InstructionSelector::VisitI32x4BitMask(Node* node) { UNIMPLEMENTED(); } - void InstructionSelector::EmitPrepareResults( ZoneVector* results, const CallDescriptor* call_descriptor, Node* node) {