mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 17:00:19 +02:00
OpcodeDispatcher: absorb invert into PF calculation
with xorn Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
1 parent
3b052e826f
commit
eb4bb5875e
3 files changed
+14
-14
No files matched your search
@@ -775,24 +775,20 @@ void OpDispatchBuilder::CALLAbsoluteOp(OpcodeArgs) {
|
||||
_ExitFunction(JMPPCOffset); // If we get here then leave the function now
|
||||
}
|
||||
|
||||
OrderedNode *OpDispatchBuilder::SelectBit(OrderedNode *Cmp, bool TrueIsNonzero, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue) {
|
||||
OrderedNode *OpDispatchBuilder::SelectBit(OrderedNode *Cmp, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue) {
|
||||
uint64_t TrueConst, FalseConst;
|
||||
if (IsValueConstant(WrapNode(TrueValue), &TrueConst) &&
|
||||
IsValueConstant(WrapNode(FalseValue), &FalseConst) &&
|
||||
TrueConst == 1 &&
|
||||
FalseConst == 0) {
|
||||
|
||||
if (!TrueIsNonzero)
|
||||
Cmp = _Not(OpSize::i32Bit, Cmp);
|
||||
|
||||
return _And(ResultSize, Cmp, _Constant(1));
|
||||
}
|
||||
|
||||
SaveNZCV();
|
||||
_TestNZ(OpSize::i32Bit, Cmp, _Constant(1));
|
||||
return _NZCVSelect(ResultSize,
|
||||
TrueIsNonzero ? CondClassType{COND_NEQ} : CondClassType{COND_EQ},
|
||||
TrueValue, FalseValue);
|
||||
return _NZCVSelect(ResultSize, CondClassType{COND_NEQ},
|
||||
TrueValue, FalseValue);
|
||||
}
|
||||
|
||||
std::pair<bool, CondClassType> OpDispatchBuilder::DecodeNZCVCondition(uint8_t OP) const {
|
||||
@@ -857,10 +853,10 @@ OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, IR::OpSize ResultSize, Orde
|
||||
}
|
||||
case 0xA: { // JP - Jump if PF == 1
|
||||
// Raw value contains inverted PF in bottom bit
|
||||
return SelectBit(LoadPFRaw(), false, ResultSize, TrueValue, FalseValue);
|
||||
return SelectBit(LoadPFRaw(true), ResultSize, TrueValue, FalseValue);
|
||||
}
|
||||
case 0xB: { // JNP - Jump if PF == 0
|
||||
return SelectBit(LoadPFRaw(), true, ResultSize, TrueValue, FalseValue);
|
||||
return SelectBit(LoadPFRaw(false), ResultSize, TrueValue, FalseValue);
|
||||
}
|
||||
default:
|
||||
LOGMAN_MSG_A_FMT("Unknown CC Op: 0x{:x}\n", OP);
|
||||
|
||||
@@ -1627,7 +1627,7 @@ private:
|
||||
}
|
||||
|
||||
std::pair<bool, CondClassType> DecodeNZCVCondition(uint8_t OP) const;
|
||||
OrderedNode *SelectBit(OrderedNode *Cmp, bool Invert, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue);
|
||||
OrderedNode *SelectBit(OrderedNode *Cmp, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue);
|
||||
OrderedNode *SelectCC(uint8_t OP, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue);
|
||||
|
||||
/**
|
||||
@@ -1761,7 +1761,7 @@ private:
|
||||
/**
|
||||
* @name These functions are used by the deferred flag handling while it is calculating and storing flags in to RFLAGs.
|
||||
* @{ */
|
||||
OrderedNode *LoadPFRaw();
|
||||
OrderedNode *LoadPFRaw(bool Invert);
|
||||
OrderedNode *LoadAF();
|
||||
void FixupAF();
|
||||
void SetAFAndFixup(OrderedNode *AF);
|
||||
|
||||
@@ -179,7 +179,7 @@ OrderedNode *OpDispatchBuilder::GetPackedRFLAG(uint32_t FlagsMask) {
|
||||
// instead.
|
||||
if (FlagsMask & (1 << FEXCore::X86State::RFLAG_PF_RAW_LOC)) {
|
||||
// Set every bit except the bottommost.
|
||||
auto OnesInvPF = _Or(OpSize::i64Bit, LoadPFRaw(), _Constant(~1ull));
|
||||
auto OnesInvPF = _Or(OpSize::i64Bit, LoadPFRaw(false), _Constant(~1ull));
|
||||
|
||||
// Rotate the bottom bit to the appropriate location for PF, so we get
|
||||
// something like 111P1111. Then invert that to get 000p0000. Then OR that
|
||||
@@ -237,7 +237,7 @@ void OpDispatchBuilder::CalculateOF(uint8_t SrcSize, OrderedNode *Res, OrderedNo
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_OF_RAW_LOC>(Anded, SrcSize * 8 - 1, true);
|
||||
}
|
||||
|
||||
OrderedNode *OpDispatchBuilder::LoadPFRaw() {
|
||||
OrderedNode *OpDispatchBuilder::LoadPFRaw(bool Invert) {
|
||||
// Read the stored byte. This is the original result (up to 64-bits), it needs
|
||||
// parity calculated.
|
||||
auto Result = GetRFLAG(FEXCore::X86State::RFLAG_PF_RAW_LOC);
|
||||
@@ -245,7 +245,11 @@ OrderedNode *OpDispatchBuilder::LoadPFRaw() {
|
||||
// Cascade to calculate parity of bottom 8-bits to bottom bit.
|
||||
Result = _XorShift(OpSize::i32Bit, Result, Result, ShiftType::LSR, 4);
|
||||
Result = _XorShift(OpSize::i32Bit, Result, Result, ShiftType::LSR, 2);
|
||||
Result = _XorShift(OpSize::i32Bit, Result, Result, ShiftType::LSR, 1);
|
||||
|
||||
if (Invert)
|
||||
Result = _XornShift(OpSize::i32Bit, Result, Result, ShiftType::LSR, 1);
|
||||
else
|
||||
Result = _XorShift(OpSize::i32Bit, Result, Result, ShiftType::LSR, 1);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user