From adc709db2fa22d2d09ee70b265b2247377d5d7ff Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 5 Jul 2024 16:13:46 -0400 Subject: [PATCH] OpcodeDispatcher: drop remnants of deferred flags Signed-off-by: Alyssa Rosenzweig --- .../Interface/Core/OpcodeDispatcher.cpp | 2 - .../Source/Interface/Core/OpcodeDispatcher.h | 105 +----------------- .../Interface/Core/OpcodeDispatcher/Flags.cpp | 21 +--- 3 files changed, 4 insertions(+), 124 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index bad890cc3..bcd25e88c 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -4002,8 +4002,6 @@ void OpDispatchBuilder::BeginFunction(uint64_t RIP, const fextl::vectorBlocks = Block->Wrapped(DualListData.ListBegin()); - - LOGMAN_THROW_A_FMT(IsDeferredFlagsStored(), "Something failed to calculate flags and now we began with invalid state"); } void OpDispatchBuilder::Finalize() { diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index d425a7c26..c6f2a40f3 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -87,10 +87,6 @@ class OpDispatchBuilder final : public IREmitter { friend class FEXCore::IR::PassManager; public: - enum class FlagsGenerationType : uint8_t { - TYPE_NONE, - }; - Ref GetNewJumpBlock(uint64_t RIP) { auto it = JumpTargets.find(RIP); LOGMAN_THROW_A_FMT(it != JumpTargets.end(), "Couldn't find block generated for 0x{:x}", RIP); @@ -196,10 +192,6 @@ public: } } - if (LastOp) { - LOGMAN_THROW_A_FMT(IsDeferredFlagsStored(), "FinishOp: Deferred flags weren't generated at end of block"); - } - BlockSetRIP = false; return false; @@ -1992,98 +1984,18 @@ private: Ref SelectCC(uint8_t OP, IR::OpSize ResultSize, Ref TrueValue, Ref FalseValue); /** - * @name Deferred RFLAG calculation and generation. - * - * Only handles the six flags that ALU ops typically generate. - * Specifically: CF, PF, AF, ZF, SF, OF - * These six flags are heavily generated through basic ALU ops and balloon the IR if not early eliminated. - * This tracking structure only tracks single blocks and requires RFLAGS calculation at block-ending ops. - * Some flags generating ALU ops only touch part of the registers, In these cases it will do calculation up front. - * This means we still need our IR passes to eliminate all redundant flags accesses but this light OpcodeDispatcher optimization - * doesn't take it to that level. - * @{ */ - - // Deferred flag generation tracking structure. - // This structure is used to track RFlags from ALU ops for invalidation. - // - // Future ideas: Use an invalidation mask to do partial generation of flags. - // Particularly for the instructions that don't do the full set of flags calculations. - // These instructions currently calculate the deferred RFLAGS immediately then overwrite rflags state. - // RCLSE IR pass will catch and remove redundant rflags stores like this currently. - struct DeferredFlagData { - // What type of flags to generate - FlagsGenerationType Type {FlagsGenerationType::TYPE_NONE}; - - // Source size of the op - uint8_t SrcSize; - - // Every flag generation type has a result - Ref Res {}; - - union { - // UMUL, BEXTR, BLSI, POPCOUNT, ZCNT, RDRAND - struct { - } NoSource; - - // MUL, BLSR, BLSMSKB, BZHI - struct { - Ref Src1; - } OneSource; - - // Logical - struct { - Ref Src1; - Ref Src2; - } TwoSource; - - // LSHLI, LSHRI, ASHRI - struct { - Ref Src1; - uint64_t Imm; - } OneSrcImmediate; - - // ADD, SUB - struct { - Ref Src1; - Ref Src2; - - bool UpdateCF; - } TwoSrcImmediate; - } Sources {}; - }; - - DeferredFlagData CurrentDeferredFlags {}; - - /** - * @brief Takes the current deferred flag state and stores the result in to RFLAGS. - * - * Once executed there will no longer be any deferred flag state and RFLAGS will have the correct flags in it. - * Necessary to do when leaving a IR block, or if an instruction is doing a partial overwrite of the flags. + * @brief Flushes NZCV. Mostly vestigial. */ - void CalculateDeferredFlags(uint32_t FlagsToCalculateMask = ~0U); + void CalculateDeferredFlags(); /** - * @brief Invalidates the current deferred flags structure. - * - * If the emulated instruction is going to overwrite all of the flags but isn't tracked using the deferred flag system - * then use this function to stop tracking the current active deferred flags. + * @brief Invalidates NZCV. Mostly vestigial. */ void InvalidateDeferredFlags() { - CurrentDeferredFlags.Type = FlagsGenerationType::TYPE_NONE; - // No NZCV bits will be set, they are all invalid. PossiblySetNZCVBits = 0; } - /** - * @brief Checks if there is any deferred flag state active. - * - * @return True if RFLAGs contains the flags. False if deferred flags is tracking the data. - */ - bool IsDeferredFlagsStored() const { - return CurrentDeferredFlags.Type == FlagsGenerationType::TYPE_NONE; - } - void ZeroShiftResult(FEXCore::X86Tables::DecodedOp Op) { // In the case of zero-rotate, we need to store the destination still to deal with 32-bit semantics. const uint32_t Size = GetSrcSize(Op); @@ -2275,14 +2187,3 @@ private: void InstallOpcodeHandlers(Context::OperatingMode Mode); } // namespace FEXCore::IR -template<> -struct fmt::formatter : fmt::formatter { - using Base = fmt::formatter; - - // Pass-through the underlying value, so IDs can - // be formatted like any integral value. - template - auto format(const FEXCore::IR::OpDispatchBuilder::FlagsGenerationType& ID, FormatContext& ctx) { - return Base::format(static_cast(ID), ctx); - } -}; diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp index 02af2178b..8367b653f 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp @@ -258,26 +258,7 @@ void OpDispatchBuilder::CalculateAF(Ref Src1, Ref Src2) { SetRFLAG(XorRes); } -void OpDispatchBuilder::CalculateDeferredFlags(uint32_t FlagsToCalculateMask) { - if (CurrentDeferredFlags.Type == FlagsGenerationType::TYPE_NONE) { - // Nothing to do - if (NZCVDirty && CachedNZCV) { - _StoreNZCV(CachedNZCV); - } - - CachedNZCV = nullptr; - NZCVDirty = false; - return; - } - - switch (CurrentDeferredFlags.Type) { - case FlagsGenerationType::TYPE_NONE: - default: ERROR_AND_DIE_FMT("Unhandled flags type {}", CurrentDeferredFlags.Type); - } - - // Done calculating - CurrentDeferredFlags.Type = FlagsGenerationType::TYPE_NONE; - +void OpDispatchBuilder::CalculateDeferredFlags() { if (NZCVDirty && CachedNZCV) { _StoreNZCV(CachedNZCV); }