mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-14 07:00:43 +02:00
OpcodeDispatcher: Optimize OF calc of immediates
If we know the sign of one of the sources, we can do better when calculating OF. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
1 parent
e795ec683d
commit
ea8b7633eb
1 file changed
+23
-5
@@ -202,11 +202,29 @@ OrderedNode *OpDispatchBuilder::GetPackedRFLAG(uint32_t FlagsMask) {
|
||||
|
||||
void OpDispatchBuilder::CalculateOF_Add(uint8_t SrcSize, OrderedNode *Res, OrderedNode *Src1, OrderedNode *Src2) {
|
||||
auto OpSize = SrcSize == 8 ? OpSize::i64Bit : OpSize::i32Bit;
|
||||
auto XorOp1 = _Xor(OpSize, Src1, Src2);
|
||||
auto XorOp2 = _Xor(OpSize, Res, Src1);
|
||||
OrderedNode *AndOp1 = _Andn(OpSize, XorOp2, XorOp1);
|
||||
AndOp1 = _Bfe(OpSize, 1, SrcSize * 8 - 1, AndOp1);
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_OF_LOC>(AndOp1);
|
||||
uint64_t SignBit = (SrcSize * 8) - 1;
|
||||
OrderedNode *Anded = nullptr;
|
||||
|
||||
// OF is set iff the sources have the same sign but the destination sign
|
||||
// differs. If we know a source sign, we can simplify the expression: if
|
||||
// source 2 is known to be positive, we set OF if source 1 is positive and
|
||||
// source 2 is negative. Similarly if source 2 is known negative.
|
||||
uint64_t Const;
|
||||
if (IsValueConstant(WrapNode(Src2), &Const)) {
|
||||
bool Negative = (Const & (1ull << SignBit)) != 0;
|
||||
|
||||
if (Negative)
|
||||
Anded = _Andn(OpSize, Src1, Res);
|
||||
else
|
||||
Anded = _Andn(OpSize, Res, Src1);
|
||||
} else {
|
||||
auto XorOp1 = _Xor(OpSize, Src1, Src2);
|
||||
auto XorOp2 = _Xor(OpSize, Res, Src1);
|
||||
Anded = _Andn(OpSize, XorOp2, XorOp1);
|
||||
}
|
||||
|
||||
auto OF = _Bfe(OpSize, 1, SrcSize * 8 - 1, Anded);
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_OF_LOC>(OF);
|
||||
}
|
||||
|
||||
OrderedNode *OpDispatchBuilder::LoadPFRaw() {
|
||||
|
||||
Reference in new issue
Block a user