mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-23 11:00:48 +02:00
Merge pull request #2745 from Sonicadvance1/optimize_fcmov
OpcodeDispatcher: Optimize GetPackedRFLAG
This commit is contained in:
5 files changed
+25
-20
No files matched your search
+14
-6
@@ -1020,14 +1020,22 @@ DEF_OP(Bfi) {
|
||||
const auto SrcDst = GetReg(Op->Dest.ID());
|
||||
const auto Src = GetReg(Op->Src.ID());
|
||||
|
||||
mov(EmitSize, TMP1, SrcDst);
|
||||
bfi(EmitSize, TMP1, Src, Op->lsb, Op->Width);
|
||||
|
||||
if (OpSize == 8) {
|
||||
mov(EmitSize, Dst, TMP1.R());
|
||||
if (Dst == SrcDst) {
|
||||
// If Dst and SrcDst match then this turns in to a simple BFI instruction.
|
||||
bfi(EmitSize, Dst, Src, Op->lsb, Op->Width);
|
||||
}
|
||||
else {
|
||||
ubfx(EmitSize, Dst, TMP1, 0, OpSize * 8);
|
||||
// Destination didn't match the dst source register.
|
||||
// TODO: Inefficient until FEX can have RA constraints here.
|
||||
mov(EmitSize, TMP1, SrcDst);
|
||||
bfi(EmitSize, TMP1, Src, Op->lsb, Op->Width);
|
||||
|
||||
if (OpSize == 8) {
|
||||
mov(EmitSize, Dst, TMP1.R());
|
||||
}
|
||||
else {
|
||||
ubfx(EmitSize, Dst, TMP1, 0, OpSize * 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1554,7 +1554,7 @@ void OpDispatchBuilder::SAHFOp(OpcodeArgs) {
|
||||
}
|
||||
void OpDispatchBuilder::LAHFOp(OpcodeArgs) {
|
||||
// Load the lower 8 bits of the Rflags register
|
||||
auto RFLAG = GetPackedRFLAG(true);
|
||||
auto RFLAG = GetPackedRFLAG(0xFF);
|
||||
|
||||
// Store the lower 8 bits of the rflags register in to AH
|
||||
StoreGPRRegister(X86State::REG_RAX, RFLAG, 1, 8);
|
||||
@@ -4269,7 +4269,7 @@ void OpDispatchBuilder::BSWAPOp(OpcodeArgs) {
|
||||
void OpDispatchBuilder::PUSHFOp(OpcodeArgs) {
|
||||
const uint8_t Size = GetSrcSize(Op);
|
||||
|
||||
OrderedNode *Src = GetPackedRFLAG(false);
|
||||
OrderedNode *Src = GetPackedRFLAG();
|
||||
if (Size != 8) {
|
||||
Src = _Bfe(Size * 8, 0, Src);
|
||||
}
|
||||
|
||||
@@ -827,7 +827,7 @@ public:
|
||||
void InvalidOp(OpcodeArgs);
|
||||
|
||||
void SetPackedRFLAG(bool Lower8, OrderedNode *Src);
|
||||
OrderedNode *GetPackedRFLAG(bool Lower8);
|
||||
OrderedNode *GetPackedRFLAG(uint32_t FlagsMask = ~0U);
|
||||
|
||||
void SetMultiblock(bool _Multiblock) { Multiblock = _Multiblock; }
|
||||
|
||||
|
||||
@@ -59,22 +59,19 @@ void OpDispatchBuilder::SetPackedRFLAG(bool Lower8, OrderedNode *Src) {
|
||||
}
|
||||
}
|
||||
|
||||
OrderedNode *OpDispatchBuilder::GetPackedRFLAG(bool Lower8) {
|
||||
OrderedNode *OpDispatchBuilder::GetPackedRFLAG(uint32_t FlagsMask) {
|
||||
// Calculate flags early.
|
||||
CalculateDeferredFlags();
|
||||
|
||||
OrderedNode *Original = _Constant(2);
|
||||
size_t NumFlags = FlagOffsets.size();
|
||||
if (Lower8) {
|
||||
NumFlags = 5;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < NumFlags; ++i) {
|
||||
for (size_t i = 0; i < FlagOffsets.size(); ++i) {
|
||||
const auto FlagOffset = FlagOffsets[i];
|
||||
if (!((1U << FlagOffset) & FlagsMask)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OrderedNode *Flag = _LoadFlag(FlagOffset);
|
||||
Flag = _Bfe(4, 32, 0, Flag);
|
||||
Flag = _Lshl(Flag, _Constant(FlagOffset));
|
||||
Original = _Or(Original, Flag);
|
||||
Original = _Bfi(4, 1, FlagOffset, Original, Flag);
|
||||
}
|
||||
return Original;
|
||||
}
|
||||
|
||||
@@ -1356,7 +1356,7 @@ void OpDispatchBuilder::X87FCMOV(OpcodeArgs) {
|
||||
|
||||
auto MaskConst = _Constant(FLAGMask);
|
||||
|
||||
auto RFLAG = GetPackedRFLAG(false);
|
||||
auto RFLAG = GetPackedRFLAG(FLAGMask);
|
||||
|
||||
auto AndOp = _And(RFLAG, MaskConst);
|
||||
switch (Type) {
|
||||
|
||||
Reference in new issue
Block a user