OpcodeDispatcher: Handle VPSHUFB

This commit is contained in:
Lioncache committed 2023-02-13 14:47:37 -05:00
1 parent d9a505e22e
commit ac5d09885e
5 files changed
+84 -2

No files matched your search

@@ -6013,6 +6013,7 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() {
{OPD(1, 0b01, 0xFD), 1, &OpDispatchBuilder::AVXVectorALUOp<IR::OP_VADD, 2>},
{OPD(1, 0b01, 0xFE), 1, &OpDispatchBuilder::AVXVectorALUOp<IR::OP_VADD, 4>},
{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>},
@@ -493,6 +493,8 @@ public:
template <size_t ElementSize, bool Signed>
void VPMULLOp(OpcodeArgs);
void VPSHUFBOp(OpcodeArgs);
template <size_t ElementSize>
void VPSLLOp(OpcodeArgs);
void VPSLLDQOp(OpcodeArgs);
@@ -969,6 +969,11 @@ OrderedNode* OpDispatchBuilder::PSHUFBOpImpl(OpcodeArgs, const X86Tables::Decode
OrderedNode *Src2Node = LoadSource(FPRClass, Op, Src2, Op->Flags, -1);
const auto SrcSize = GetSrcSize(Op);
const auto Is256Bit = SrcSize == Core::CPUState::XMM_AVX_REG_SIZE;
// We perform the 256-bit version as two 128-bit operations due to
// the lane splitting behavior, so cap the maximum size at 16.
const auto SanitizedSrcSize = std::min(SrcSize, uint8_t{16});
// PSHUFB doesn't 100% match VTBL behaviour
// VTBL will set the element zero if the index is greater than
@@ -984,7 +989,14 @@ OrderedNode* OpDispatchBuilder::PSHUFBOpImpl(OpcodeArgs, const X86Tables::Decode
OrderedNode *MaskVector = _VectorImm(SrcSize, 1, MaskImm);
OrderedNode *MaskedIndices = _VAnd(SrcSize, SrcSize, Src2Node, MaskVector);
return _VTBL1(SrcSize, Src1Node, MaskedIndices);
OrderedNode *Low = _VTBL1(SanitizedSrcSize, Src1Node, MaskedIndices);
if (!Is256Bit) {
return Low;
}
OrderedNode *HighSrc1 = _VInsElement(SrcSize, 16, 0, 1, Src1Node, Src1Node);
OrderedNode *High = _VTBL1(SanitizedSrcSize, HighSrc1, MaskedIndices);
return _VInsElement(SrcSize, 16, 1, 0, Low, High);
}
void OpDispatchBuilder::PSHUFBOp(OpcodeArgs) {
@@ -992,6 +1004,11 @@ void OpDispatchBuilder::PSHUFBOp(OpcodeArgs) {
StoreResult(FPRClass, Op, Result, -1);
}
void OpDispatchBuilder::VPSHUFBOp(OpcodeArgs) {
OrderedNode *Result = PSHUFBOpImpl(Op, Op->Src[0], Op->Src[1]);
StoreResult(FPRClass, Op, Result, -1);
}
template<size_t ElementSize, bool HalfSize, bool Low>
void OpDispatchBuilder::PSHUFDOp(OpcodeArgs) {
static_assert(ElementSize != 0);
@@ -259,7 +259,7 @@ void InitializeVEXTables() {
{OPD(1, 0b01, 0xFE), 1, X86InstInfo{"VPADDD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}},
// VEX Map 2
{OPD(2, 0b01, 0x00), 1, X86InstInfo{"VPSHUFB", TYPE_UNDEC, FLAGS_MODRM | FLAGS_XMM_FLAGS, 0, nullptr}},
{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}},
+62
View File
@@ -0,0 +1,62 @@
%ifdef CONFIG
{
"HostFeatures": ["AVX"],
"RegData": {
"XMM5": ["0x4848484848484848", "0x4848484848484848", "0x0000000000000000", "0x0000000000000000"],
"XMM6": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"],
"XMM7": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"],
"XMM8": ["0x4847464544434241", "0x5857565554535251", "0x0000000000000000", "0x0000000000000000"],
"XMM9": ["0x4848484848484848", "0x4848484848484848", "0x5858585858585858", "0x5858585858585858"],
"XMM10": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"],
"XMM11": ["0x0000000000000000", "0x0000000000000000", "0x0000000000000000", "0x0000000000000000"],
"XMM12": ["0x4847464544434241", "0x5857565554535251", "0x5847464544434241", "0x4857565554535251"]
}
}
%endif
lea rdx, [rel .data]
vmovaps ymm0, [rdx]
vmovaps ymm1, [rdx + 32 * 1]
vmovaps ymm2, [rdx + 32 * 2]
vmovaps ymm3, [rdx + 32 * 3]
vmovaps ymm4, [rdx + 32 * 4]
vpshufb xmm5, xmm0, xmm1
vpshufb xmm6, xmm0, xmm2
vpshufb xmm7, xmm0, xmm3
vpshufb xmm8, xmm0, xmm4
vpshufb ymm9, ymm0, ymm1
vpshufb ymm10, ymm0, ymm2
vpshufb ymm11, ymm0, ymm3
vpshufb ymm12, ymm0, ymm4
hlt
align 32
.data:
dq 0x4142434445464748
dq 0x5152535455565758
dq 0x4142434445464758
dq 0x5152535455565748
dq 0
dq 0
dq 0
dq 0
dq -1
dq -1
dq -1
dq -1
dq 0x8080808080808080
dq 0x8080808080808080
dq 0x8080808080808080
dq 0x8080808080808080
dq 0x0001020304050607
dq 0x08090A0B0C0D0E0F
dq 0x0001020304050607
dq 0x08090A0B0C0D0E0F