OpcodeDispatcher: absorb invert into PF calculation

with xorn

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
Alyssa Rosenzweig committed 2024-04-01 14:12:33 -04:00
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;
}