diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp index 8c0bcccf5..0b1ed3117 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp @@ -63,7 +63,7 @@ OrderedNode *OpDispatchBuilder::GetPackedRFLAG(uint32_t FlagsMask) { // Calculate flags early. CalculateDeferredFlags(); - OrderedNode *Original = _Constant(2); + OrderedNode *Original = _Constant((1U << X86State::RFLAG_RESERVED_LOC) & FlagsMask ? 2 : 0); for (size_t i = 0; i < FlagOffsets.size(); ++i) { const auto FlagOffset = FlagOffsets[i]; if (!((1U << FlagOffset) & FlagsMask)) { diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp index e97626916..3af970f6c 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp @@ -1357,20 +1357,17 @@ void OpDispatchBuilder::X87FCMOV(OpcodeArgs) { break; } - auto MaskConst = _Constant(FLAGMask); - auto RFLAG = GetPackedRFLAG(FLAGMask); - auto AndOp = _And(RFLAG, MaskConst); switch (Type) { case COMPARE_ZERO: { SrcCond = _Select(FEXCore::IR::COND_EQ, - AndOp, ZeroConst, OneConst, ZeroConst); + RFLAG, ZeroConst, OneConst, ZeroConst); break; } case COMPARE_NOTZERO: { SrcCond = _Select(FEXCore::IR::COND_EQ, - AndOp, ZeroConst, ZeroConst, OneConst); + RFLAG, ZeroConst, ZeroConst, OneConst); break; } } diff --git a/External/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp b/External/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp index 6a22a79a1..ed3ded59d 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/ConstProp.cpp @@ -813,6 +813,25 @@ bool ConstProp::ConstantPropagation(IREmitter *IREmit, const IRListView& Current break; } + case OP_SBFE: { + auto Op = IROp->C(); + uint64_t Constant; + if (IREmit->IsValueConstant(Op->Src, &Constant)) { + // SBFE of a constant can be converted to a constant. + uint64_t SourceMask = (1ULL << Op->Width) - 1; + if (Op->Width == 64) + SourceMask = ~0ULL; + SourceMask <<= Op->lsb; + + int64_t NewConstant = (Constant & SourceMask) >> Op->lsb; + NewConstant <<= 64 - Op->Width; + NewConstant >>= 64 - Op->Width; + IREmit->ReplaceWithConstant(CodeNode, NewConstant); + + Changed = true; + } + break; + } case OP_MUL: { auto Op = IROp->C(); uint64_t Constant1{}; diff --git a/External/FEXCore/include/FEXCore/Core/X86Enums.h b/External/FEXCore/include/FEXCore/Core/X86Enums.h index bfbe4821c..a28c942cd 100644 --- a/External/FEXCore/include/FEXCore/Core/X86Enums.h +++ b/External/FEXCore/include/FEXCore/Core/X86Enums.h @@ -56,6 +56,7 @@ enum X86Reg : uint32_t { * @{ */ enum X86RegLocation : uint32_t { RFLAG_CF_LOC = 0, + RFLAG_RESERVED_LOC = 1, // Reserved Bit, Read-as-1 RFLAG_PF_LOC = 2, RFLAG_AF_LOC = 4, RFLAG_ZF_LOC = 6,