mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 17:00:19 +02:00
Merge pull request #2422 from lioncash/phadds
OpcodeDispatcher: Handle VPHADDSW
This commit is contained in:
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
@@ -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}},
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in new issue
Block a user