OpcodeDispatcher: Another FCMov minor optimization

If we are loading exactly the flags we need from the RFLAGS (ensuring we
don't load the reserved flag in bit 1) then we don't need to do a mask
on the result.

Additionally there is some bad code-motion around selects that was
causing SBFE operations to occur on constants. Ensure that we const-prop
any SBFE operations to clean this up.

This PR along with #2783 causes FMOV blow-up to go from 41 instruction
to 31 instructions.
This commit is contained in:
Ryan Houdek committed 2023-07-16 21:37:54 -07:00
1 parent 1b1e9e0fb5
commit 24cb2610a2
4 files changed
+23 -6

No files matched your search

@@ -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)) {
@@ -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;
}
}
@@ -813,6 +813,25 @@ bool ConstProp::ConstantPropagation(IREmitter *IREmit, const IRListView& Current
break;
}
case OP_SBFE: {
auto Op = IROp->C<IR::IROp_Bfe>();
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<IR::IROp_Mul>();
uint64_t Constant1{};
+1
View File
@@ -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,