Skip to content

Commit

Permalink
OpcodeDispatcher: absorb invert into PF calculation
Browse files Browse the repository at this point in the history
with xorn

Signed-off-by: Alyssa Rosenzweig <[email protected]>
  • Loading branch information
alyssarosenzweig committed Apr 1, 2024
1 parent 3b052e8 commit eb4bb58
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 14 deletions.
14 changes: 5 additions & 9 deletions FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions FEXCore/Source/Interface/Core/OpcodeDispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -1627,7 +1627,7 @@ friend class FEXCore::IR::PassManager;
}

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);

/**
Expand Down Expand Up @@ -1761,7 +1761,7 @@ friend class FEXCore::IR::PassManager;
/**
* @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);
Expand Down
10 changes: 7 additions & 3 deletions FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -237,15 +237,19 @@ 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);

// 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;
}
Expand Down

0 comments on commit eb4bb58

Please sign in to comment.