From f4ce6fb621a97cdbe0cbce4bf9224d317f5fcfb9 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 26 Nov 2024 08:38:20 -0500 Subject: [PATCH] OpcodeDispatcher: optimize AAS/AAD flag Signed-off-by: Alyssa Rosenzweig --- .../Source/Interface/Core/OpcodeDispatcher.cpp | 6 ++---- .../Source/Interface/Core/OpcodeDispatcher.h | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index fab35fb0b..f6d79666a 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -2861,8 +2861,7 @@ void OpDispatchBuilder::AAAOp(OpcodeArgs) { auto AF = CalculateAFForDecimal(A); // CF = AF, OF/SF/ZF/PF undefined - ZeroNZCV(); - SetCFDirect(AF); + SetCFDirect_InvalidateNZV(AF); SetAFAndFixup(AF); CalculateDeferredFlags(); @@ -2881,8 +2880,7 @@ void OpDispatchBuilder::AASOp(OpcodeArgs) { auto AF = CalculateAFForDecimal(A); // CF = AF, OF/SF/ZF/PF undefined - ZeroNZCV(); - SetCFDirect(AF); + SetCFDirect_InvalidateNZV(AF); SetAFAndFixup(AF); CalculateDeferredFlags(); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 118cd10bf..6cd14e223 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -1751,6 +1751,23 @@ private: CFInverted = true; } + // Set CF directly to the given 0/1 value. This needs to respect the + // invert. We use a subtraction: + // + // 0 - x = 0 + (~x) + 1. + // + // If x = 0, then 0 + (~0) + 1 = 0x100000000 so hardware C is set. + // If x = 1, then 0 + (~1) + 1 = 0x0ffffffff so hardware C is not set. + void SetCFDirect_InvalidateNZV(Ref Value, unsigned ValueOffset = 0, bool MustMask = false) { + if (ValueOffset || MustMask) { + Value = _Bfe(OpSize::i64Bit, 1, ValueOffset, Value); + } + + HandleNZCVWrite(); + _SubNZCV(OpSize::i32Bit, _Constant(0), Value); + CFInverted = true; + } + void SetCFInverted(Ref Value, unsigned ValueOffset = 0, bool MustMask = false) { SetRFLAG(Value, X86State::RFLAG_CF_RAW_LOC, ValueOffset, MustMask); CFInverted = true;