mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 10:00:16 +02:00
Merge pull request #2306 from lioncash/perm
OpcodeDispatcher: Handle immediate variants of VPERMILPD/VPERMILPS
This commit is contained in:
6 files changed
+119
-2
No files matched your search
@@ -6070,6 +6070,8 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() {
|
||||
|
||||
{OPD(3, 0b01, 0x00), 1, &OpDispatchBuilder::VPERMQOp},
|
||||
{OPD(3, 0b01, 0x01), 1, &OpDispatchBuilder::VPERMQOp},
|
||||
{OPD(3, 0b01, 0x04), 1, &OpDispatchBuilder::VPERMILImmOp<4>},
|
||||
{OPD(3, 0b01, 0x05), 1, &OpDispatchBuilder::VPERMILImmOp<8>},
|
||||
{OPD(3, 0b01, 0x06), 1, &OpDispatchBuilder::VPERM2Op},
|
||||
{OPD(3, 0b01, 0x08), 1, &OpDispatchBuilder::AVXVectorRound<4, false>},
|
||||
{OPD(3, 0b01, 0x09), 1, &OpDispatchBuilder::AVXVectorRound<8, false>},
|
||||
|
||||
@@ -470,6 +470,9 @@ public:
|
||||
void VPERM2Op(OpcodeArgs);
|
||||
void VPERMQOp(OpcodeArgs);
|
||||
|
||||
template <size_t ElementSize>
|
||||
void VPERMILImmOp(OpcodeArgs);
|
||||
|
||||
void VPHMINPOSUWOp(OpcodeArgs);
|
||||
|
||||
template <size_t ElementSize>
|
||||
|
||||
@@ -3766,4 +3766,45 @@ void OpDispatchBuilder::VZEROOp(OpcodeArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t ElementSize>
|
||||
void OpDispatchBuilder::VPERMILImmOp(OpcodeArgs) {
|
||||
const auto DstSize = GetDstSize(Op);
|
||||
const auto Is256Bit = DstSize == Core::CPUState::XMM_AVX_REG_SIZE;
|
||||
|
||||
LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here");
|
||||
const auto Selector = Op->Src[1].Data.Literal.Value & 0xFF;
|
||||
|
||||
OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1);
|
||||
OrderedNode *Result = _VectorZero(DstSize);
|
||||
|
||||
if constexpr (ElementSize == 8) {
|
||||
Result = _VInsElement(DstSize, ElementSize, 0, Selector & 0b0001, Result, Src);
|
||||
Result = _VInsElement(DstSize, ElementSize, 1, (Selector & 0b0010) >> 1, Result, Src);
|
||||
|
||||
if (Is256Bit) {
|
||||
Result = _VInsElement(DstSize, ElementSize, 2, ((Selector & 0b0100) >> 2) + 2, Result, Src);
|
||||
Result = _VInsElement(DstSize, ElementSize, 3, ((Selector & 0b1000) >> 3) + 2, Result, Src);
|
||||
}
|
||||
} else {
|
||||
Result = _VInsElement(DstSize, ElementSize, 0, Selector & 0b00000011, Result, Src);
|
||||
Result = _VInsElement(DstSize, ElementSize, 1, (Selector & 0b00001100) >> 2, Result, Src);
|
||||
Result = _VInsElement(DstSize, ElementSize, 2, (Selector & 0b00110000) >> 4, Result, Src);
|
||||
Result = _VInsElement(DstSize, ElementSize, 3, (Selector & 0b11000000) >> 6, Result, Src);
|
||||
|
||||
if (Is256Bit) {
|
||||
Result = _VInsElement(DstSize, ElementSize, 4, (Selector & 0b00000011) + 4, Result, Src);
|
||||
Result = _VInsElement(DstSize, ElementSize, 5, ((Selector & 0b00001100) >> 2) + 4, Result, Src);
|
||||
Result = _VInsElement(DstSize, ElementSize, 6, ((Selector & 0b00110000) >> 4) + 4, Result, Src);
|
||||
Result = _VInsElement(DstSize, ElementSize, 7, ((Selector & 0b11000000) >> 6) + 4, Result, Src);
|
||||
}
|
||||
}
|
||||
|
||||
StoreResult(FPRClass, Op, Result, -1);
|
||||
}
|
||||
|
||||
template
|
||||
void OpDispatchBuilder::VPERMILImmOp<4>(OpcodeArgs);
|
||||
template
|
||||
void OpDispatchBuilder::VPERMILImmOp<8>(OpcodeArgs);
|
||||
|
||||
}
|
||||
@@ -408,8 +408,8 @@ void InitializeVEXTables() {
|
||||
{OPD(3, 0b01, 0x00), 1, X86InstInfo{"VPERMQ", TYPE_INST, GenFlagsSameSize(SIZE_256BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
{OPD(3, 0b01, 0x01), 1, X86InstInfo{"VPERMPD", TYPE_INST, GenFlagsSameSize(SIZE_256BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
{OPD(3, 0b01, 0x02), 1, X86InstInfo{"VPBLENDD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(3, 0b01, 0x04), 1, X86InstInfo{"VPERMILPS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(3, 0b01, 0x05), 1, X86InstInfo{"VPERMILPD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}},
|
||||
{OPD(3, 0b01, 0x04), 1, X86InstInfo{"VPERMILPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
{OPD(3, 0b01, 0x05), 1, X86InstInfo{"VPERMILPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
{OPD(3, 0b01, 0x06), 1, X86InstInfo{"VPERM2F128", TYPE_INST, GenFlagsSameSize(SIZE_256BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
|
||||
{OPD(3, 0b01, 0x08), 1, X86InstInfo{"VROUNDPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_XMM_FLAGS, 1, nullptr}},
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"HostFeatures": ["AVX"],
|
||||
"RegData": {
|
||||
"XMM1": ["0xAAAAAAAAAAAAAAAA", "0xAAAAAAAAAAAAAAAA", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM2": ["0xBBBBBBBBBBBBBBBB", "0xBBBBBBBBBBBBBBBB", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM3": ["0xAAAAAAAAAAAAAAAA", "0xBBBBBBBBBBBBBBBB", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM4": ["0xBBBBBBBBBBBBBBBB", "0xAAAAAAAAAAAAAAAA", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM5": ["0xAAAAAAAAAAAAAAAA", "0xAAAAAAAAAAAAAAAA", "0xCCCCCCCCCCCCCCCC", "0xCCCCCCCCCCCCCCCC"],
|
||||
"XMM6": ["0xBBBBBBBBBBBBBBBB", "0xBBBBBBBBBBBBBBBB", "0xDDDDDDDDDDDDDDDD", "0xDDDDDDDDDDDDDDDD"],
|
||||
"XMM7": ["0xAAAAAAAAAAAAAAAA", "0xBBBBBBBBBBBBBBBB", "0xCCCCCCCCCCCCCCCC", "0xDDDDDDDDDDDDDDDD"]
|
||||
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
lea rdx, [rel .data]
|
||||
|
||||
vmovaps ymm0, [rdx]
|
||||
|
||||
vpermilpd xmm1, xmm0, 0000b
|
||||
vpermilpd xmm2, xmm0, 0011b
|
||||
vpermilpd xmm3, xmm0, 0010b
|
||||
vpermilpd xmm4, xmm0, 0001b
|
||||
|
||||
vpermilpd ymm5, ymm0, 0000b
|
||||
vpermilpd ymm6, ymm0, 1111b
|
||||
vpermilpd ymm7, ymm0, 1010b
|
||||
|
||||
hlt
|
||||
|
||||
align 32
|
||||
.data:
|
||||
dq 0xAAAAAAAAAAAAAAAA
|
||||
dq 0xBBBBBBBBBBBBBBBB
|
||||
dq 0xCCCCCCCCCCCCCCCC
|
||||
dq 0xDDDDDDDDDDDDDDDD
|
||||
@@ -0,0 +1,34 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"HostFeatures": ["AVX"],
|
||||
"RegData": {
|
||||
"XMM1": ["0xBBBBBBBBBBBBBBBB", "0xBBBBBBBBBBBBBBBB", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM2": ["0xCCCCCCCCCCCCCCCC", "0xCCCCCCCCCCCCCCCC", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM3": ["0xDDDDDDDDDDDDDDDD", "0xDDDDDDDDDDDDDDDD", "0x0000000000000000", "0x0000000000000000"],
|
||||
"XMM4": ["0xBBBBBBBBBBBBBBBB", "0xBBBBBBBBBBBBBBBB", "0xFFFFFFFFFFFFFFFF", "0xFFFFFFFFFFFFFFFF"],
|
||||
"XMM5": ["0xCCCCCCCCCCCCCCCC", "0xCCCCCCCCCCCCCCCC", "0x9999999999999999", "0x9999999999999999"],
|
||||
"XMM6": ["0xDDDDDDDDDDDDDDDD", "0xDDDDDDDDDDDDDDDD", "0x8888888888888888", "0x8888888888888888"]
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
lea rdx, [rel .data]
|
||||
|
||||
vmovaps ymm0, [rdx]
|
||||
|
||||
vpermilps xmm1, xmm0, 00000000b
|
||||
vpermilps xmm2, xmm0, 11111111b
|
||||
vpermilps xmm3, xmm0, 10101010b
|
||||
|
||||
vpermilps ymm4, ymm0, 00000000b
|
||||
vpermilps ymm5, ymm0, 11111111b
|
||||
vpermilps ymm6, ymm0, 10101010b
|
||||
|
||||
hlt
|
||||
|
||||
align 32
|
||||
.data:
|
||||
dq 0xAAAAAAAABBBBBBBB
|
||||
dq 0xCCCCCCCCDDDDDDDD
|
||||
dq 0xEEEEEEEEFFFFFFFF
|
||||
dq 0x9999999988888888
|
||||
Reference in new issue
Block a user