diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 385ab7d42..3dd0e49fa 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -2130,6 +2130,17 @@ void OpDispatchBuilder::ROLImmediateOp(OpcodeArgs) { GenerateFlags_RotateLeftImmediate(Op, ALUOp, Dest, Shift); } +void OpDispatchBuilder::ANDNBMIOp(OpcodeArgs) { + auto* Src1 = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1); + auto* Src2 = LoadSource(GPRClass, Op, Op->Src[1], Op->Flags, -1); + + // TODO: This can be replaced with a BIC IR op once it's implemented. + auto Dest = _And(_Not(Src1), Src2); + + StoreResult(GPRClass, Op, Dest, -1); + GenerateFlags_Logical(Op, Dest, Src1, Src2); +} + void OpDispatchBuilder::RCROp1Bit(OpcodeArgs) { OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1); auto Size = GetSrcSize(Op) * 8; @@ -5797,6 +5808,8 @@ constexpr uint16_t PF_F2 = 3; {OPD(2, 0b01, 0x78), 1, &OpDispatchBuilder::UnimplementedOp}, {OPD(2, 0b01, 0x79), 1, &OpDispatchBuilder::UnimplementedOp}, + + {OPD(2, 0b00, 0xF2), 1, &OpDispatchBuilder::ANDNBMIOp}, }; #undef OPD diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 1494de57d..88bc9ed8c 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -324,6 +324,9 @@ public: template void PSIGN(OpcodeArgs); + // BMI Ops + void ANDNBMIOp(OpcodeArgs); + // X87 Ops template void FLD(OpcodeArgs); diff --git a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp index 6ee0958b8..debb05379 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp +++ b/External/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp @@ -386,7 +386,7 @@ void InitializeVEXTables() { {OPD(2, 0b01, 0xDE), 1, X86InstInfo{"VAESDEC", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, {OPD(2, 0b01, 0xDF), 1, X86InstInfo{"VAESDECLAST", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, - {OPD(2, 0b00, 0xF2), 1, X86InstInfo{"ANDN", TYPE_UNDEC, FLAGS_NONE, 0, nullptr}}, + {OPD(2, 0b00, 0xF2), 1, X86InstInfo{"ANDN", TYPE_INST, FLAGS_MODRM | FLAGS_VEX, 0, nullptr}}, {OPD(2, 0b00, 0xF3), 1, X86InstInfo{"", TYPE_VEX_GROUP_17, FLAGS_NONE, 0, nullptr}}, // VEX Group 17 {OPD(2, 0b01, 0xF3), 1, X86InstInfo{"", TYPE_VEX_GROUP_17, FLAGS_NONE, 0, nullptr}}, // VEX Group 17 diff --git a/unittests/ASM/VEX/andn.asm b/unittests/ASM/VEX/andn.asm new file mode 100644 index 000000000..0622a6f78 --- /dev/null +++ b/unittests/ASM/VEX/andn.asm @@ -0,0 +1,22 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0xFFFFFFFFFFFFFFFF", + "RBX": "0", + "RCX": "0xFFFFFFFF", + "RDX": "0" + } +} +%endif + +mov rax, 0 +mov rbx, -1 +andn rax, rax, rbx +andn rbx, rbx, rax + +mov rcx, 0 +mov rdx, -1 +andn ecx, ecx, edx +andn edx, edx, ecx + +hlt \ No newline at end of file