From 80171adf1ec33dc0199d471c5cde2987e1536637 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 16 Oct 2021 16:42:39 +0200 Subject: [PATCH] PPCTables: Retire FL_EVIL FL_EVIL is only used for blocking instructions from being reordered. There are three types of instructions which have FL_EVIL set: 1. CR operations. The previous commits improved our CR analysis and removed FL_EVIL from these instructions. 2. Load/store operations. These are always blocked from reordering due to always having canCauseException set. 3. isync. I don't know if we actually need to prevent reordering around this one, since as far as I know we only do reorderings that are guaranteed to not change the behavior of the program. But just in case, I've renamed FL_EVIL to FL_NO_REORDER instead of removing it entirely, so that it can be used for this instruction. --- Source/Core/Core/PowerPC/PPCAnalyst.cpp | 4 ++-- Source/Core/Core/PowerPC/PPCTables.cpp | 18 +++++++++--------- Source/Core/Core/PowerPC/PPCTables.h | 23 +++++++++++------------ 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp index e2a4fc519c..d7c4a09a64 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp @@ -222,9 +222,9 @@ bool PPCAnalyzer::CanSwapAdjacentOps(const CodeOp& a, const CodeOp& b) const // [1] https://bugs.dolphin-emu.org/issues/5864#note-7 if (a.canCauseException || b.canCauseException) return false; - if (a_flags & (FL_ENDBLOCK | FL_TIMER | FL_EVIL | FL_SET_OE)) + if (a_flags & (FL_ENDBLOCK | FL_TIMER | FL_NO_REORDER | FL_SET_OE)) return false; - if (b_flags & (FL_ENDBLOCK | FL_TIMER | FL_EVIL | FL_SET_OE)) + if (b_flags & (FL_ENDBLOCK | FL_TIMER | FL_NO_REORDER | FL_SET_OE)) return false; if ((a_flags & (FL_SET_CA | FL_READ_CA)) && (b_flags & (FL_SET_CA | FL_READ_CA))) return false; diff --git a/Source/Core/Core/PowerPC/PPCTables.cpp b/Source/Core/Core/PowerPC/PPCTables.cpp index dc05b03979..9d70fb662b 100644 --- a/Source/Core/Core/PowerPC/PPCTables.cpp +++ b/Source/Core/Core/PowerPC/PPCTables.cpp @@ -87,8 +87,8 @@ constexpr std::array s_primary_table{{ {38, "stb", OpType::Store, 1, FL_IN_A0 | FL_IN_S | FL_LOADSTORE}, {39, "stbu", OpType::Store, 1, FL_OUT_A | FL_IN_A | FL_IN_S | FL_LOADSTORE}, - {46, "lmw", OpType::System, 11, FL_EVIL | FL_IN_A0 | FL_LOADSTORE}, - {47, "stmw", OpType::System, 11, FL_EVIL | FL_IN_A0 | FL_LOADSTORE}, + {46, "lmw", OpType::System, 11, FL_IN_A0 | FL_LOADSTORE}, + {47, "stmw", OpType::System, 11, FL_IN_A0 | FL_LOADSTORE}, {48, "lfs", OpType::LoadFP, 1, FL_OUT_FLOAT_D | FL_IN_A | FL_USE_FPU | FL_LOADSTORE}, {49, "lfsu", OpType::LoadFP, 1, @@ -233,7 +233,7 @@ constexpr std::array s_table19{{ {417, "crorc", OpType::CR, 1, 0}, {193, "crxor", OpType::CR, 1, 0}, - {150, "isync", OpType::InstructionCache, 1, FL_EVIL}, + {150, "isync", OpType::InstructionCache, 1, FL_NO_REORDER}, {0, "mcrf", OpType::System, 1, FL_SET_CRn | FL_READ_CRn}, {50, "rfi", OpType::System, 2, FL_ENDBLOCK | FL_CHECKEXCEPTIONS | FL_PROGRAMEXCEPTION}, @@ -324,12 +324,12 @@ constexpr std::array s_table31{{ {790, "lhbrx", OpType::Load, 1, FL_OUT_D | FL_IN_A0B | FL_LOADSTORE}, // Conditional load/store (Wii SMP) - {150, "stwcxd", OpType::Store, 1, FL_EVIL | FL_IN_S | FL_IN_A0B | FL_SET_CR0 | FL_LOADSTORE}, - {20, "lwarx", OpType::Load, 1, FL_EVIL | FL_OUT_D | FL_IN_A0B | FL_SET_CR0 | FL_LOADSTORE}, + {150, "stwcxd", OpType::Store, 1, FL_IN_S | FL_IN_A0B | FL_SET_CR0 | FL_LOADSTORE}, + {20, "lwarx", OpType::Load, 1, FL_OUT_D | FL_IN_A0B | FL_SET_CR0 | FL_LOADSTORE}, // load string (Inst these) - {533, "lswx", OpType::Load, 1, FL_EVIL | FL_IN_A0B | FL_OUT_D | FL_LOADSTORE}, - {597, "lswi", OpType::Load, 1, FL_EVIL | FL_IN_A0 | FL_OUT_D | FL_LOADSTORE}, + {533, "lswx", OpType::Load, 1, FL_IN_A0B | FL_OUT_D | FL_LOADSTORE}, + {597, "lswi", OpType::Load, 1, FL_IN_A0 | FL_OUT_D | FL_LOADSTORE}, // store word {151, "stwx", OpType::Store, 1, FL_IN_S | FL_IN_A0B | FL_LOADSTORE}, @@ -347,8 +347,8 @@ constexpr std::array s_table31{{ {662, "stwbrx", OpType::Store, 1, FL_IN_S | FL_IN_A0B | FL_LOADSTORE}, {918, "sthbrx", OpType::Store, 1, FL_IN_S | FL_IN_A0B | FL_LOADSTORE}, - {661, "stswx", OpType::Store, 1, FL_EVIL | FL_IN_A0B | FL_LOADSTORE}, - {725, "stswi", OpType::Store, 1, FL_EVIL | FL_IN_A0 | FL_LOADSTORE}, + {661, "stswx", OpType::Store, 1, FL_IN_A0B | FL_LOADSTORE}, + {725, "stswi", OpType::Store, 1, FL_IN_A0 | FL_LOADSTORE}, // fp load/store {535, "lfsx", OpType::LoadFP, 1, FL_OUT_FLOAT_D | FL_IN_A0B | FL_USE_FPU | FL_LOADSTORE}, diff --git a/Source/Core/Core/PowerPC/PPCTables.h b/Source/Core/Core/PowerPC/PPCTables.h index 00d4baaf9f..afb265f840 100644 --- a/Source/Core/Core/PowerPC/PPCTables.h +++ b/Source/Core/Core/PowerPC/PPCTables.h @@ -36,18 +36,17 @@ enum InstructionFlags : u64 FL_OUT_AD = FL_OUT_A | FL_OUT_D, FL_TIMER = (1ull << 15), // Used only for mftb. FL_CHECKEXCEPTIONS = (1ull << 16), // Used with rfi/rfid. - FL_EVIL = - (1ull << 17), // Historically used to refer to instructions that messed up Super Monkey Ball. - FL_USE_FPU = (1ull << 18), // Used to indicate a floating point instruction. - FL_LOADSTORE = (1ull << 19), // Used to indicate a load/store instruction. - FL_SET_FPRF = (1ull << 20), // Sets bits in the FPRF. - FL_READ_FPRF = (1ull << 21), // Reads bits from the FPRF. - FL_SET_OE = (1ull << 22), // Sets the overflow flag. - FL_IN_FLOAT_A = (1ull << 23), // frA is used as an input. - FL_IN_FLOAT_B = (1ull << 24), // frB is used as an input. - FL_IN_FLOAT_C = (1ull << 25), // frC is used as an input. - FL_IN_FLOAT_S = (1ull << 26), // frS is used as an input. - FL_IN_FLOAT_D = (1ull << 27), // frD is used as an input. + FL_NO_REORDER = (1ull << 17), // Instruction should not be reordered by our optimizations. + FL_USE_FPU = (1ull << 18), // Used to indicate a floating point instruction. + FL_LOADSTORE = (1ull << 19), // Used to indicate a load/store instruction. + FL_SET_FPRF = (1ull << 20), // Sets bits in the FPRF. + FL_READ_FPRF = (1ull << 21), // Reads bits from the FPRF. + FL_SET_OE = (1ull << 22), // Sets the overflow flag. + FL_IN_FLOAT_A = (1ull << 23), // frA is used as an input. + FL_IN_FLOAT_B = (1ull << 24), // frB is used as an input. + FL_IN_FLOAT_C = (1ull << 25), // frC is used as an input. + FL_IN_FLOAT_S = (1ull << 26), // frS is used as an input. + FL_IN_FLOAT_D = (1ull << 27), // frD is used as an input. FL_IN_FLOAT_AB = FL_IN_FLOAT_A | FL_IN_FLOAT_B, FL_IN_FLOAT_AC = FL_IN_FLOAT_A | FL_IN_FLOAT_C, FL_IN_FLOAT_ABC = FL_IN_FLOAT_A | FL_IN_FLOAT_B | FL_IN_FLOAT_C,