diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 5468b41ea..27cb5f58d 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -6121,6 +6121,7 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() { {OPD(3, 0b01, 0x4A), 1, &OpDispatchBuilder::AVXVectorVariableBlend<4>}, {OPD(3, 0b01, 0x4B), 1, &OpDispatchBuilder::AVXVectorVariableBlend<8>}, + {OPD(3, 0b01, 0x4C), 1, &OpDispatchBuilder::AVXVectorVariableBlend<1>}, {OPD(3, 0b01, 0xDF), 1, &OpDispatchBuilder::VAESKeyGenAssistOp}, }; diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 31790d244..1bd2777b4 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -3468,6 +3468,8 @@ void OpDispatchBuilder::AVXVectorVariableBlend(OpcodeArgs) { StoreResult(FPRClass, Op, Result, -1); } template +void OpDispatchBuilder::AVXVectorVariableBlend<1>(OpcodeArgs); +template void OpDispatchBuilder::AVXVectorVariableBlend<4>(OpcodeArgs); template void OpDispatchBuilder::AVXVectorVariableBlend<8>(OpcodeArgs); diff --git a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp index 4a236fecd..2a7785edc 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp +++ b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp @@ -447,7 +447,7 @@ void InitializeVEXTables() { {OPD(3, 0b01, 0x49), 1, X86InstInfo{"VPERMILzz2PD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, {OPD(3, 0b01, 0x4A), 1, X86InstInfo{"VBLENDVPS", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 1, nullptr}}, {OPD(3, 0b01, 0x4B), 1, X86InstInfo{"VBLENDVPD", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 1, nullptr}}, - {OPD(3, 0b01, 0x4C), 1, X86InstInfo{"VBLENDVB", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(3, 0b01, 0x4C), 1, X86InstInfo{"VPBLENDVB", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 1, nullptr}}, {OPD(3, 0b01, 0x5C), 1, X86InstInfo{"VFMADDSUBPS", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, {OPD(3, 0b01, 0x5D), 1, X86InstInfo{"VFMADDSUBPD", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, diff --git a/unittests/ASM/VEX/vpblendvb.asm b/unittests/ASM/VEX/vpblendvb.asm new file mode 100644 index 000000000..6a20e43f7 --- /dev/null +++ b/unittests/ASM/VEX/vpblendvb.asm @@ -0,0 +1,78 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM3": ["0x1222324252627282", "0xAABBCCDDEEFF9900", "0x8070605040302010", "0x1020304050607080"], + "XMM4": ["0x1222324252627282", "0xAABBCCDDEEFF9900", "0x0000000000000000", "0x0000000000000000"], + "XMM5": ["0xAABBCCDDEEFF1122", "0x3344556677889900", "0x1020304050607080", "0x9585756555453525"], + "XMM6": ["0xAABBCCDDEEFF1122", "0x3344556677889900", "0x0000000000000000", "0x0000000000000000"], + "XMM7": ["0xAA22CC42EE621182", "0x33BB55DD77FF9900", "0x1070305050307010", "0x9520754055603580"], + "XMM8": ["0xAA22CC42EE621182", "0x33BB55DD77FF9900", "0x0000000000000000", "0x0000000000000000"], + "XMM9": ["0x12BB32DD52FF7222", "0xAA44CC66EE889900", "0x8020604040602080", "0x1085306550457025"], + "XMM10": ["0x12BB32DD52FF7222", "0xAA44CC66EE889900", "0x0000000000000000", "0x0000000000000000"] + } +} +%endif + +lea rdx, [rel .data] + +vmovaps ymm0, [rdx] +vmovaps ymm1, [rdx + 32] +vmovaps ymm2, [rel .mask_all] + +; Select all ymm1 +vpblendvb ymm3, ymm0, ymm1, ymm2 +vpblendvb xmm4, xmm0, xmm1, xmm2 + +; Select all ymm0 +vmovaps ymm2, [rel .mask_none] +vpblendvb ymm5, ymm0, ymm1, ymm2 +vpblendvb xmm6, xmm0, xmm1, xmm2 + +; Interleaved selection from ymm1 and ymm0 +vmovaps ymm2, [rel .mask_interleave1] +vpblendvb ymm7, ymm0, ymm1, ymm2 +vpblendvb xmm8, xmm0, xmm1, xmm2 + +; Interleaved selection from ymm0 and ymm1 +vmovaps ymm2, [rel .mask_interleave2] +vpblendvb ymm9, ymm0, ymm1, ymm2 +vpblendvb xmm10, xmm0, xmm1, xmm2 + +hlt + +align 32 +.data: +dq 0xAABBCCDDEEFF1122 +dq 0x3344556677889900 +dq 0x1020304050607080 +dq 0x9585756555453525 + +dq 0x1222324252627282 +dq 0xAABBCCDDEEFF9900 +dq 0x8070605040302010 +dq 0x1020304050607080 + +.mask_all: +dq 0xFFFFFFFFFFFFFFFF +dq 0xFFFFFFFFFFFFFFFF +dq 0xFFFFFFFFFFFFFFFF +dq 0xFFFFFFFFFFFFFFFF + +.mask_none: +dq 0x0000000000000000 +dq 0x0000000000000000 +dq 0x0000000000000000 +dq 0x0000000000000000 + +.mask_interleave1: +dq 0x0080008000800080 +dq 0x0080008000800080 +dq 0x0080008000800080 +dq 0x0080008000800080 + +.mask_interleave2: +dq 0x8000800080008000 +dq 0x8000800080008000 +dq 0x8000800080008000 +dq 0x8000800080008000