mirror of
https://github.com/FEX-Emu/FEX.git
synced 2024-12-15 09:59:28 +00:00
OpcodeDispatcher: drop ZeroMultipleFlags
lot of complexity for only a single interesting case. we can massively simplify. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
parent
e2a095372e
commit
f8b68d8b5a
@ -1422,7 +1422,7 @@ private:
|
|||||||
SetRFLAG<FEXCore::X86State::RFLAG_AF_RAW_LOC>(_Constant(Constant << 4));
|
SetRFLAG<FEXCore::X86State::RFLAG_AF_RAW_LOC>(_Constant(Constant << 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZeroMultipleFlags(uint32_t BitMask);
|
void ZeroPF_AF();
|
||||||
|
|
||||||
CondClassType CondForNZCVBit(unsigned BitOffset, bool Invert) {
|
CondClassType CondForNZCVBit(unsigned BitOffset, bool Invert) {
|
||||||
switch (BitOffset) {
|
switch (BitOffset) {
|
||||||
|
@ -38,61 +38,10 @@ constexpr std::array<uint32_t, 17> FlagOffsets = {
|
|||||||
FEXCore::X86State::RFLAG_ID_LOC,
|
FEXCore::X86State::RFLAG_ID_LOC,
|
||||||
};
|
};
|
||||||
|
|
||||||
void OpDispatchBuilder::ZeroMultipleFlags(uint32_t FlagsMask) {
|
void OpDispatchBuilder::ZeroPF_AF() {
|
||||||
auto ZeroConst = _Constant(0);
|
|
||||||
|
|
||||||
if (ContainsNZCV(FlagsMask)) {
|
|
||||||
// NZCV is stored packed together.
|
|
||||||
// It's more optimal to zero NZCV with move+bic instead of multiple bics.
|
|
||||||
auto NZCVFlagsMask = FlagsMask & FullNZCVMask;
|
|
||||||
if (NZCVFlagsMask == FullNZCVMask) {
|
|
||||||
ZeroNZCV();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const auto IndexMask = NZCVIndexMask(FlagsMask);
|
|
||||||
|
|
||||||
if (std::popcount(NZCVFlagsMask) == 1) {
|
|
||||||
// It's more optimal to store only one here.
|
|
||||||
|
|
||||||
for (size_t i = 0; NZCVFlagsMask && i < FlagOffsets.size(); ++i) {
|
|
||||||
const auto FlagOffset = FlagOffsets[i];
|
|
||||||
const auto FlagMask = 1U << FlagOffset;
|
|
||||||
if (!(FlagMask & NZCVFlagsMask)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SetRFLAG(ZeroConst, FlagOffset);
|
|
||||||
NZCVFlagsMask &= ~(FlagMask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
auto IndexMaskConstant = _Constant(IndexMask);
|
|
||||||
auto NewNZCV = _Andn(OpSize::i64Bit, GetNZCV(), IndexMaskConstant);
|
|
||||||
SetNZCV(NewNZCV);
|
|
||||||
}
|
|
||||||
// Unset the possibly set bits.
|
|
||||||
PossiblySetNZCVBits &= ~IndexMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handled NZCV, so remove it from the mask.
|
|
||||||
FlagsMask &= ~FullNZCVMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PF is stored inverted, so invert it when we zero.
|
// PF is stored inverted, so invert it when we zero.
|
||||||
if (FlagsMask & (1u << X86State::RFLAG_PF_RAW_LOC)) {
|
SetRFLAG<FEXCore::X86State::RFLAG_PF_RAW_LOC>(_Constant(1));
|
||||||
SetRFLAG<FEXCore::X86State::RFLAG_PF_RAW_LOC>(_Constant(1));
|
SetAF(0);
|
||||||
FlagsMask &= ~(1u << X86State::RFLAG_PF_RAW_LOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle remaining masks.
|
|
||||||
for (size_t i = 0; FlagsMask && i < FlagOffsets.size(); ++i) {
|
|
||||||
const auto FlagOffset = FlagOffsets[i];
|
|
||||||
const auto FlagMask = 1U << FlagOffset;
|
|
||||||
if (!(FlagMask & FlagsMask)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SetRFLAG(ZeroConst, FlagOffset);
|
|
||||||
FlagsMask &= ~(FlagMask);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpDispatchBuilder::SetPackedRFLAG(bool Lower8, OrderedNode *Src) {
|
void OpDispatchBuilder::SetPackedRFLAG(bool Lower8, OrderedNode *Src) {
|
||||||
@ -994,9 +943,7 @@ void OpDispatchBuilder::CalculateFlags_POPCOUNT(OrderedNode *Result) {
|
|||||||
// is in the range [0, 63]. In particular, it is always positive. So a
|
// is in the range [0, 63]. In particular, it is always positive. So a
|
||||||
// combined NZ test will correctly zero SF/CF/OF while setting ZF.
|
// combined NZ test will correctly zero SF/CF/OF while setting ZF.
|
||||||
SetNZ_ZeroCV(OpSize::i32Bit, Result);
|
SetNZ_ZeroCV(OpSize::i32Bit, Result);
|
||||||
|
ZeroPF_AF();
|
||||||
ZeroMultipleFlags((1U << X86State::RFLAG_AF_RAW_LOC) |
|
|
||||||
(1U << X86State::RFLAG_PF_RAW_LOC));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpDispatchBuilder::CalculateFlags_BZHI(uint8_t SrcSize, OrderedNode *Result, OrderedNode *Src) {
|
void OpDispatchBuilder::CalculateFlags_BZHI(uint8_t SrcSize, OrderedNode *Result, OrderedNode *Src) {
|
||||||
@ -1022,15 +969,10 @@ void OpDispatchBuilder::CalculateFlags_ZCNT(uint8_t SrcSize, OrderedNode *Result
|
|||||||
|
|
||||||
void OpDispatchBuilder::CalculateFlags_RDRAND(OrderedNode *Src) {
|
void OpDispatchBuilder::CalculateFlags_RDRAND(OrderedNode *Src) {
|
||||||
// OF, SF, ZF, AF, PF all zero
|
// OF, SF, ZF, AF, PF all zero
|
||||||
|
ZeroNZCV();
|
||||||
|
ZeroPF_AF();
|
||||||
|
|
||||||
// CF is set to the incoming source
|
// CF is set to the incoming source
|
||||||
|
|
||||||
uint32_t FlagsMaskToZero =
|
|
||||||
FullNZCVMask |
|
|
||||||
(1U << X86State::RFLAG_AF_RAW_LOC) |
|
|
||||||
(1U << X86State::RFLAG_PF_RAW_LOC);
|
|
||||||
|
|
||||||
ZeroMultipleFlags(FlagsMaskToZero);
|
|
||||||
|
|
||||||
SetRFLAG<FEXCore::X86State::RFLAG_CF_RAW_LOC>(Src);
|
SetRFLAG<FEXCore::X86State::RFLAG_CF_RAW_LOC>(Src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4594,11 +4594,7 @@ void OpDispatchBuilder::PTestOp(OpcodeArgs) {
|
|||||||
SetNZ_ZeroCV(32, Test1);
|
SetNZ_ZeroCV(32, Test1);
|
||||||
SetRFLAG<FEXCore::X86State::RFLAG_CF_RAW_LOC>(Test2);
|
SetRFLAG<FEXCore::X86State::RFLAG_CF_RAW_LOC>(Test2);
|
||||||
|
|
||||||
uint32_t FlagsMaskToZero =
|
ZeroPF_AF();
|
||||||
(1U << X86State::RFLAG_PF_RAW_LOC) |
|
|
||||||
(1U << X86State::RFLAG_AF_RAW_LOC);
|
|
||||||
|
|
||||||
ZeroMultipleFlags(FlagsMaskToZero);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpDispatchBuilder::VTESTOpImpl(OpcodeArgs, size_t ElementSize) {
|
void OpDispatchBuilder::VTESTOpImpl(OpcodeArgs, size_t ElementSize) {
|
||||||
@ -4635,8 +4631,7 @@ void OpDispatchBuilder::VTESTOpImpl(OpcodeArgs, size_t ElementSize) {
|
|||||||
SetNZ_ZeroCV(32, AndGPR);
|
SetNZ_ZeroCV(32, AndGPR);
|
||||||
SetRFLAG<X86State::RFLAG_CF_RAW_LOC>(CFResult);
|
SetRFLAG<X86State::RFLAG_CF_RAW_LOC>(CFResult);
|
||||||
|
|
||||||
ZeroMultipleFlags((1U << X86State::RFLAG_PF_RAW_LOC) |
|
ZeroPF_AF();
|
||||||
(1U << X86State::RFLAG_AF_RAW_LOC));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t ElementSize>
|
template <size_t ElementSize>
|
||||||
@ -5568,11 +5563,7 @@ void OpDispatchBuilder::PCMPXSTRXOpImpl(OpcodeArgs, bool IsExplicit, bool IsMask
|
|||||||
SetRFLAG<X86State::RFLAG_CF_RAW_LOC>(GetFlagBit(18));
|
SetRFLAG<X86State::RFLAG_CF_RAW_LOC>(GetFlagBit(18));
|
||||||
SetRFLAG<X86State::RFLAG_OF_RAW_LOC>(GetFlagBit(19));
|
SetRFLAG<X86State::RFLAG_OF_RAW_LOC>(GetFlagBit(19));
|
||||||
|
|
||||||
uint32_t FlagsMaskToZero =
|
ZeroPF_AF();
|
||||||
(1U << X86State::RFLAG_PF_RAW_LOC) |
|
|
||||||
(1U << X86State::RFLAG_AF_RAW_LOC);
|
|
||||||
|
|
||||||
ZeroMultipleFlags(FlagsMaskToZero);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpDispatchBuilder::VPCMPESTRIOp(OpcodeArgs) {
|
void OpDispatchBuilder::VPCMPESTRIOp(OpcodeArgs) {
|
||||||
|
Loading…
Reference in New Issue
Block a user