From e0973e19fc378ad2a69f2db2b0596e2808b6058a Mon Sep 17 00:00:00 2001 From: lioncash Date: Sat, 6 Nov 2021 23:29:38 -0400 Subject: [PATCH] OpcodeDispatcher: Implement handling for BLSMSK --- .../Interface/Core/OpcodeDispatcher.cpp | 28 ++++++++++++++++ .../Source/Interface/Core/OpcodeDispatcher.h | 1 + .../Interface/Core/X86Tables/VEXTables.cpp | 2 +- unittests/ASM/VEX/blsmsk.asm | 32 +++++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 unittests/ASM/VEX/blsmsk.asm diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 1fe41cb64..8cf099bda 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -2261,6 +2261,33 @@ void OpDispatchBuilder::BLSIBMIOp(OpcodeArgs) { } } +void OpDispatchBuilder::BLSMSKBMIOp(OpcodeArgs) { + // Equivalent to: (Src - 1) ^ Src + + auto Zero = _Constant(0); + auto One = _Constant(1); + + auto* Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1); + auto Result = _Xor(_Sub(Src, One), Src); + + StoreResult(GPRClass, Op, Result, -1); + + // Now for the flags. + SetRFLAG(Zero); + SetRFLAG(Zero); + SetRFLAG(Zero); + if (CTX->Config.ABINoPF) { + _InvalidateFlags(1UL << X86State::RFLAG_PF_LOC); + } else { + SetRFLAG(Zero); + } + + auto CFOp = _Select(IR::COND_EQ, + Src, Zero, + Zero, One); + SetRFLAG(CFOp); +} + void OpDispatchBuilder::BLSRBMIOp(OpcodeArgs) { // Equivalent to: (Src - 1) & Src @@ -5981,6 +6008,7 @@ constexpr uint16_t PF_F2 = 3; #define OPD(group, pp, opcode) (((group - X86Tables::InstType::TYPE_VEX_GROUP_12) << 4) | (pp << 3) | (opcode)) const std::vector> VEXGroupTable = { {OPD(X86Tables::InstType::TYPE_VEX_GROUP_17, 0, 0b001), 1, &OpDispatchBuilder::BLSRBMIOp}, + {OPD(X86Tables::InstType::TYPE_VEX_GROUP_17, 0, 0b010), 1, &OpDispatchBuilder::BLSMSKBMIOp}, {OPD(X86Tables::InstType::TYPE_VEX_GROUP_17, 0, 0b011), 1, &OpDispatchBuilder::BLSIBMIOp}, }; #undef OPD diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 92f2d81bf..5e3e84c45 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -328,6 +328,7 @@ public: void ANDNBMIOp(OpcodeArgs); void BEXTRBMIOp(OpcodeArgs); void BLSIBMIOp(OpcodeArgs); + void BLSMSKBMIOp(OpcodeArgs); void BLSRBMIOp(OpcodeArgs); // X87 Ops diff --git a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp index da9383067..bb7096585 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp +++ b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp @@ -504,7 +504,7 @@ void InitializeVEXTables() { {OPD(TYPE_VEX_GROUP_15, 1, 0b011), 1, X86InstInfo{"VSTMXCSR", TYPE_UNDEC, FLAGS_MODRM, 0, nullptr}}, {OPD(TYPE_VEX_GROUP_17, 0, 0b001), 1, X86InstInfo{"BLSR", TYPE_INST, FLAGS_MODRM | FLAGS_VEX_DST, 0, nullptr}}, - {OPD(TYPE_VEX_GROUP_17, 0, 0b010), 1, X86InstInfo{"BLSMSK", TYPE_UNDEC, FLAGS_MODRM, 0, nullptr}}, + {OPD(TYPE_VEX_GROUP_17, 0, 0b010), 1, X86InstInfo{"BLSMSK", TYPE_INST, FLAGS_MODRM | FLAGS_VEX_DST, 0, nullptr}}, {OPD(TYPE_VEX_GROUP_17, 0, 0b011), 1, X86InstInfo{"BLSI", TYPE_INST, FLAGS_MODRM | FLAGS_VEX_DST, 0, nullptr}}, }; #undef OPD diff --git a/unittests/ASM/VEX/blsmsk.asm b/unittests/ASM/VEX/blsmsk.asm new file mode 100644 index 000000000..ee8d2fe9c --- /dev/null +++ b/unittests/ASM/VEX/blsmsk.asm @@ -0,0 +1,32 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1", + "RBX": "0xFF00000000000000", + "RCX": "0x01FFFFFFFFFFFFFF", + "RDX": "1", + "RSI": "0xFF000000", + "RDI": "0x01FFFFFF" + } +} +%endif + +; Trivial test, this should result in 1. +mov rax, 11 +blsmsk rax, rax + +; Results in 0x01FFFFFFFFFFFFFF being placed into RCX +mov rbx, 0xFF00000000000000 +blsmsk rcx, rbx + +; Same tests but with 32-bit registers + +; Trivial test, this should result in 1. +mov edx, 11 +blsmsk edx, edx + +; Results in 0x01FFFFFF being placed in EDI +mov rsi, 0xFF000000 +blsmsk edi, esi + +hlt \ No newline at end of file