diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 73f08fb3a..8555aa805 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -6019,6 +6019,7 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() { {OPD(2, 0b01, 0xDC), 1, &OpDispatchBuilder::VAESEncOp}, {OPD(2, 0b01, 0xDD), 1, &OpDispatchBuilder::VAESEncLastOp}, {OPD(2, 0b01, 0xDE), 1, &OpDispatchBuilder::VAESDecOp}, + {OPD(2, 0b01, 0xDF), 1, &OpDispatchBuilder::VAESDecLastOp}, {OPD(3, 0b01, 0x00), 1, &OpDispatchBuilder::VPERMQOp}, {OPD(3, 0b01, 0x01), 1, &OpDispatchBuilder::VPERMQOp}, diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 4e100e899..47e3279db 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -420,6 +420,7 @@ public: void VADDSUBPOp(OpcodeArgs); void VAESDecOp(OpcodeArgs); + void VAESDecLastOp(OpcodeArgs); void VAESEncOp(OpcodeArgs); void VAESEncLastOp(OpcodeArgs); void VAESIMCOp(OpcodeArgs); diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Crypto.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Crypto.cpp index da0a151c4..0331b7774 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Crypto.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Crypto.cpp @@ -355,8 +355,25 @@ void OpDispatchBuilder::VAESDecOp(OpcodeArgs) { void OpDispatchBuilder::AESDecLastOp(OpcodeArgs) { OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); - auto Res = _VAESDecLast(Dest, Src); - StoreResult(FPRClass, Op, Res, -1); + OrderedNode *Result = _VAESDecLast(Dest, Src); + StoreResult(FPRClass, Op, Result, -1); +} + +void OpDispatchBuilder::VAESDecLastOp(OpcodeArgs) { + const auto DstSize = GetDstSize(Op); + const auto Is128Bit = DstSize == Core::CPUState::XMM_SSE_REG_SIZE; + + // TODO: Handle 256-bit VAESDECLAST. + LOGMAN_THROW_A_FMT(Is128Bit, "256-bit VAESDECLAST unimplemented"); + + OrderedNode *State = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags, -1); + OrderedNode *Key = LoadSource(FPRClass, Op, Op->Src[1], Op->Flags, -1); + OrderedNode *Result = _VAESDecLast(State, Key); + + if (Is128Bit) { + Result = _VMov(16, Result); + } + StoreResult(FPRClass, Op, Result, -1); } OrderedNode* OpDispatchBuilder::AESKeyGenAssistImpl(OpcodeArgs) { diff --git a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp index 4cb7b8e7e..842f8af80 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp +++ b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp @@ -384,7 +384,7 @@ void InitializeVEXTables() { {OPD(2, 0b01, 0xDC), 1, X86InstInfo{"VAESENC", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(2, 0b01, 0xDD), 1, X86InstInfo{"VAESENCLAST", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(2, 0b01, 0xDE), 1, X86InstInfo{"VAESDEC", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, - {OPD(2, 0b01, 0xDF), 1, X86InstInfo{"VAESDECLAST", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(2, 0b01, 0xDF), 1, X86InstInfo{"VAESDECLAST", TYPE_INST, GenFlagsSameSize(SIZE_128BIT) | FLAGS_MODRM | FLAGS_VEX_1ST_SRC | FLAGS_XMM_FLAGS, 0, nullptr}}, {OPD(2, 0b00, 0xF2), 1, X86InstInfo{"ANDN", TYPE_INST, FLAGS_MODRM | FLAGS_VEX_1ST_SRC, 0, nullptr}}, diff --git a/unittests/ASM/Disabled_Tests_Simulator b/unittests/ASM/Disabled_Tests_Simulator index 4b88445f1..72979a949 100644 --- a/unittests/ASM/Disabled_Tests_Simulator +++ b/unittests/ASM/Disabled_Tests_Simulator @@ -6,6 +6,7 @@ Test_H0F38/66_DE.asm Test_H0F38/66_DF.asm Test_H0F3A/0_66_DF.asm Test_VEX/vaesdec.asm +Test_VEX/vaesdeclast.asm Test_VEX/vaesenc.asm Test_VEX/vaesenclast.asm Test_VEX/vaesimc.asm diff --git a/unittests/ASM/VEX/vaesdeclast.asm b/unittests/ASM/VEX/vaesdeclast.asm new file mode 100644 index 000000000..589abd1bc --- /dev/null +++ b/unittests/ASM/VEX/vaesdeclast.asm @@ -0,0 +1,49 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM1": ["0xD5D56A6A6AD5D56A", "0x6A6AD5D5D56A6AD5", "0x0000000000000000", "0x0000000000000000"], + "XMM2": ["0x2A2A9595952A2A95", "0x95952A2A2A95952A", "0x0000000000000000", "0x0000000000000000"], + "XMM3": ["0xD5D56A6B6AD5D56B", "0x6A6AD5D4D56A6AD4", "0x0000000000000000", "0x0000000000000000"], + "XMM4": ["0x2A2A95956AD5D56A", "0x6A6AD5D42A95952A", "0x0000000000000000", "0x0000000000000000"] + } +} +%endif + +lea rdx, [rel .data] + +vmovaps ymm0, [rdx + 32 * 4] + +vaesdeclast xmm1, xmm0, [rdx + 32 * 0] +vaesdeclast xmm2, xmm0, [rdx + 32 * 1] +vaesdeclast xmm3, xmm0, [rdx + 32 * 2] +vaesdeclast xmm4, xmm0, [rdx + 32 * 3] + +hlt + +align 32 +.data: +dq 0x0000000000000000 +dq 0x0000000000000000 +dq 0x0000000000000000 +dq 0x0000000000000000 + +dq 0xFFFFFFFFFFFFFFFF +dq 0xFFFFFFFFFFFFFFFF +dq 0xFFFFFFFFFFFFFFFF +dq 0xFFFFFFFFFFFFFFFF + +dq 0x0000000100000001 +dq 0x0000000100000001 +dq 0x0000000100000001 +dq 0x0000000100000001 + +dq 0xFFFFFFFF00000000 +dq 0x00000001FFFFFFFF +dq 0xFFFFFFFF00000000 +dq 0x00000001FFFFFFFF + +dq 0x0202020202020202 +dq 0x0303030303030303 +dq 0x0202020202020202 +dq 0x0303030303030303