Merge pull request #2422 from lioncash/phadds

OpcodeDispatcher: Handle VPHADDSW
This commit is contained in:
Ryan Houdek authored and GitHub committed 2023-02-20 15:20:20 -08:00
commit 268deddd09
6 files changed
+155 -27

No files matched your search

@@ -5963,6 +5963,7 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() {
{OPD(2, 0b01, 0x00), 1, &OpDispatchBuilder::VPSHUFBOp},
{OPD(2, 0b01, 0x01), 1, &OpDispatchBuilder::VHADDPOp<IR::OP_VADDP, 2>},
{OPD(2, 0b01, 0x02), 1, &OpDispatchBuilder::VHADDPOp<IR::OP_VADDP, 4>},
{OPD(2, 0b01, 0x03), 1, &OpDispatchBuilder::VPHADDSWOp},
{OPD(2, 0b01, 0x05), 1, &OpDispatchBuilder::VPHSUBOp<2>},
{OPD(2, 0b01, 0x06), 1, &OpDispatchBuilder::VPHSUBOp<4>},
+11 -6
View File
@@ -437,17 +437,21 @@ public:
void VANDNOp(OpcodeArgs);
void VBLENDPDOp(OpcodeArgs);
void VPBLENDDOp(OpcodeArgs);
void VPBLENDWOp(OpcodeArgs);
template <size_t ElementSize>
void VBROADCASTOp(OpcodeArgs);
template <size_t ElementSize>
void VDPPOp(OpcodeArgs);
void VEXTRACT128Op(OpcodeArgs);
template <IROps IROp, size_t ElementSize>
void VHADDPOp(OpcodeArgs);
void VEXTRACT128Op(OpcodeArgs);
void VINSERTOp(OpcodeArgs);
void VINSERTPSOp(OpcodeArgs);
@@ -474,16 +478,14 @@ public:
void VPALIGNROp(OpcodeArgs);
void VBLENDPDOp(OpcodeArgs);
void VPBLENDDOp(OpcodeArgs);
void VPBLENDWOp(OpcodeArgs);
void VPERM2Op(OpcodeArgs);
void VPERMQOp(OpcodeArgs);
template <size_t ElementSize>
void VPERMILImmOp(OpcodeArgs);
void VPHADDSWOp(OpcodeArgs);
void VPHMINPOSUWOp(OpcodeArgs);
template <size_t ElementSize>
@@ -812,6 +814,9 @@ private:
const X86Tables::DecodedOperand& Src2,
const X86Tables::DecodedOperand& Imm);
OrderedNode* PHADDSOpImpl(OpcodeArgs, const X86Tables::DecodedOperand& Src1,
const X86Tables::DecodedOperand& Src2);
OrderedNode* PHMINPOSUWOpImpl(OpcodeArgs);
OrderedNode* PHSUBOpImpl(OpcodeArgs, const X86Tables::DecodedOperand& Src1,
@@ -3244,38 +3244,56 @@ void OpDispatchBuilder::VPHSUBOp<2>(OpcodeArgs);
template
void OpDispatchBuilder::VPHSUBOp<4>(OpcodeArgs);
void OpDispatchBuilder::PHADDS(OpcodeArgs) {
auto Size = GetSrcSize(Op);
OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1);
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
OrderedNode* OpDispatchBuilder::PHADDSOpImpl(OpcodeArgs, const X86Tables::DecodedOperand& Src1,
const X86Tables::DecodedOperand& Src2) {
const auto Size = GetSrcSize(Op);
OrderedNode *Src1Node = LoadSource(FPRClass, Op, Src1, Op->Flags, -1);
OrderedNode *Src2Node = LoadSource(FPRClass, Op, Src2, Op->Flags, -1);
if (Size == 8) {
// Implementation is more efficient for 8byte registers
auto Dest_Larger = _VSXTL(Size * 2, 2, Dest);
auto Src_Larger = _VSXTL(Size * 2, 2, Src);
OrderedNode *Src1_Larger = _VSXTL(Size * 2, 2, Src1Node);
OrderedNode *Src2_Larger = _VSXTL(Size * 2, 2, Src2Node);
OrderedNode *AddRes = _VAddP(Size * 2, 4, Dest_Larger, Src_Larger);
OrderedNode *AddRes = _VAddP(Size * 2, 4, Src1_Larger, Src2_Larger);
// Saturate back down to the result
OrderedNode *Res = _VSQXTN(Size * 2, 4, AddRes);
StoreResult(FPRClass, Op, Res, -1);
return _VSQXTN(Size * 2, 4, AddRes);
}
else {
auto Dest_Larger = _VSXTL(Size, 2, Dest);
auto Dest_Larger_H = _VSXTL2(Size, 2, Dest);
auto Src_Larger = _VSXTL(Size, 2, Src);
auto Src_Larger_H = _VSXTL2(Size, 2, Src);
OrderedNode *Src1_Larger = _VSXTL(Size, 2, Src1Node);
OrderedNode *Src1_Larger_H = _VSXTL2(Size, 2, Src1Node);
OrderedNode *AddRes_L = _VAddP(Size, 4, Dest_Larger, Dest_Larger_H);
OrderedNode *AddRes_H = _VAddP(Size, 4, Src_Larger, Src_Larger_H);
OrderedNode *Src2_Larger = _VSXTL(Size, 2, Src2Node);
OrderedNode *Src2_Larger_H = _VSXTL2(Size, 2, Src2Node);
// Saturate back down to the result
OrderedNode *Res = _VSQXTN(Size, 4, AddRes_L);
Res = _VSQXTN2(Size, 4, Res, AddRes_H);
OrderedNode *AddRes_L = _VAddP(Size, 4, Src1_Larger, Src1_Larger_H);
OrderedNode *AddRes_H = _VAddP(Size, 4, Src2_Larger, Src2_Larger_H);
StoreResult(FPRClass, Op, Res, -1);
// Saturate back down to the result
OrderedNode *Res = _VSQXTN(Size, 4, AddRes_L);
return _VSQXTN2(Size, 4, Res, AddRes_H);
}
void OpDispatchBuilder::PHADDS(OpcodeArgs) {
OrderedNode *Result = PHADDSOpImpl(Op, Op->Dest, Op->Src[0]);
StoreResult(FPRClass, Op, Result, -1);
}
void OpDispatchBuilder::VPHADDSWOp(OpcodeArgs) {
const auto SrcSize = GetSrcSize(Op);
const auto Is256Bit = SrcSize == Core::CPUState::XMM_AVX_REG_SIZE;
OrderedNode *Result = PHADDSOpImpl(Op, Op->Src[0], Op->Src[1]);
OrderedNode *Dest = Result;
if (Is256Bit) {
Dest = _VInsElement(SrcSize, 8, 1, 2, Result, Result);
Dest = _VInsElement(SrcSize, 8, 2, 1, Dest, Result);
}
StoreResult(FPRClass, Op, Dest, -1);
}
void OpDispatchBuilder::PHSUBS(OpcodeArgs) {
@@ -262,7 +262,7 @@ void InitializeVEXTables() {
{OPD(2, 0b01, 0x00), 1, X86InstInfo{"VPSHUFB", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}},
{OPD(2, 0b01, 0x01), 1, X86InstInfo{"VPHADDW", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}},
{OPD(2, 0b01, 0x02), 1, X86InstInfo{"VPHADDD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}},
{OPD(2, 0b01, 0x03), 1, X86InstInfo{"VPHADDSW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(2, 0b01, 0x03), 1, X86InstInfo{"VPHADDSW", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}},
{OPD(2, 0b01, 0x04), 1, X86InstInfo{"VPMADDUBSW", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
{OPD(2, 0b01, 0x05), 1, X86InstInfo{"VPHSUBW", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}},
{OPD(2, 0b01, 0x06), 1, X86InstInfo{"VPHSUBD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}},
+48
View File
@@ -0,0 +1,48 @@
%ifdef CONFIG
{
"HostFeatures": ["AVX"],
"RegData": {
"XMM4": ["0x7FFF7FFF7FFF7FFF", "0x800080007FFF7FFF", "0x0000000000000000", "0x0000000000000000"],
"XMM5": ["0x800080007FFF7FFF", "0x7FFF7FFF7FFF7FFF", "0x0000000000000000", "0x0000000000000000"],
"XMM6": ["0x71836D874331472D", "0x800080007FFF7FFF", "0x0000000000000000", "0x0000000000000000"],
"XMM7": ["0x800080007FFF7FFF", "0x71836D874331472D", "0x0000000000000000", "0x0000000000000000"],
"XMM8": ["0x7FFF7FFF7FFF7FFF", "0x71836D874331472D", "0x0000000000000000", "0x0000000000000000"],
"XMM9": ["0x800080007FFF7FFF", "0x800080007FFF7FFF", "0x0000000000000000", "0x0000000000000000"],
"XMM10": ["0x71836D874331472D", "0x800080007FFF7FFF", "0x0000000000000000", "0x0000000000000000"]
}
}
%endif
lea rdx, [rel .data]
vmovaps xmm0, [rdx]
vmovaps xmm1, [rdx + 16]
vmovaps xmm2, [rdx + 32]
vmovaps xmm3, [rdx + 48]
vphaddsw xmm4, xmm0, [rdx + 16]
vphaddsw xmm5, xmm1, [rdx]
vphaddsw xmm6, xmm2, [rdx + 16]
vphaddsw xmm7, xmm3, [rdx + 32]
vphaddsw xmm8, xmm0, [rdx + 32]
vphaddsw xmm9, xmm1, [rdx + 48]
vphaddsw xmm10, xmm2, [rdx + 48]
hlt
align 32
.data:
dq 0x4142434445464748
dq 0x5152535455565758
dq 0x7F7F7F7F7F7F7F7F
dq 0x8080808080808080
dq 0x2119221823172416
dq 0x3941384237433644
dq 0x7F7F7F7F7F7F7F7F
dq 0x8080808080808080
+56
View File
@@ -0,0 +1,56 @@
%ifdef CONFIG
{
"HostFeatures": ["AVX"],
"RegData": {
"XMM4": ["0x7FFF7FFF7FFF7FFF", "0x800080007FFF7FFF", "0x7FFF7FFF7FFF7FFF", "0x7FFF7FFF80008000"],
"XMM5": ["0x800080007FFF7FFF", "0x7FFF7FFF7FFF7FFF", "0x7FFF7FFF80008000", "0x7FFF7FFF7FFF7FFF"],
"XMM6": ["0x71836D874331472D", "0x800080007FFF7FFF", "0x4331472D71836D87", "0x7FFF7FFF80008000"],
"XMM7": ["0x800080007FFF7FFF", "0x71836D874331472D", "0x7FFF7FFF80008000", "0x4331472D71836D87"],
"XMM8": ["0x7FFF7FFF7FFF7FFF", "0x71836D874331472D", "0x7FFF7FFF7FFF7FFF", "0x4331472D71836D87"],
"XMM9": ["0x800080007FFF7FFF", "0x800080007FFF7FFF", "0x7FFF7FFF80008000", "0x7FFF7FFF80008000"],
"XMM10": ["0x71836D874331472D", "0x800080007FFF7FFF", "0x4331472D71836D87", "0x7FFF7FFF80008000"]
}
}
%endif
lea rdx, [rel .data]
vmovaps ymm0, [rdx]
vmovaps ymm1, [rdx + 32]
vmovaps ymm2, [rdx + 64]
vmovaps ymm3, [rdx + 96]
vphaddsw ymm4, ymm0, [rdx + 32]
vphaddsw ymm5, ymm1, [rdx]
vphaddsw ymm6, ymm2, [rdx + 32]
vphaddsw ymm7, ymm3, [rdx + 64]
vphaddsw ymm8, ymm0, [rdx + 64]
vphaddsw ymm9, ymm1, [rdx + 96]
vphaddsw ymm10, ymm2, [rdx + 96]
hlt
align 32
.data:
dq 0x4142434445464748
dq 0x5152535455565758
dq 0x5152535455565758
dq 0x4142434445464748
dq 0x7F7F7F7F7F7F7F7F
dq 0x8080808080808080
dq 0x8080808080808080
dq 0x7F7F7F7F7F7F7F7F
dq 0x2119221823172416
dq 0x3941384237433644
dq 0x3941384237433644
dq 0x2119221823172416
dq 0x7F7F7F7F7F7F7F7F
dq 0x8080808080808080
dq 0x8080808080808080
dq 0x7F7F7F7F7F7F7F7F