mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 14:00:16 +02:00
OpcodeDispatcher: do Select 0/1 inline in dispatcher
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
1 parent
41a188eaec
commit
2030b70ff8
6 files changed
+20
-33
No files matched your search
@@ -1692,9 +1692,7 @@ void OpDispatchBuilder::BLSMSKBMIOp(OpcodeArgs) {
|
||||
InvalidatePF_AF();
|
||||
|
||||
// CF set according to the Src
|
||||
auto Zero = Constant(0);
|
||||
auto One = Constant(1);
|
||||
auto CFInv = _Select(IR::COND_NEQ, Src, Zero, One, Zero);
|
||||
auto CFInv = To01(OpSize::i64Bit, Src);
|
||||
|
||||
// The output of BLSMSK is always nonzero, so TST will clear Z (along with C
|
||||
// and O) while setting S.
|
||||
@@ -1712,9 +1710,7 @@ void OpDispatchBuilder::BLSRBMIOp(OpcodeArgs) {
|
||||
|
||||
StoreResult(GPRClass, Op, Result, OpSize::iInvalid);
|
||||
|
||||
auto Zero = Constant(0);
|
||||
auto One = Constant(1);
|
||||
auto CFInv = _Select(IR::COND_NEQ, Src, Zero, One, Zero);
|
||||
auto CFInv = To01(OpSize::i64Bit, Src);
|
||||
|
||||
SetNZ_ZeroCV(Size, Result);
|
||||
SetCFInverted(CFInv);
|
||||
@@ -2747,7 +2743,7 @@ void OpDispatchBuilder::PopcountOp(OpcodeArgs) {
|
||||
|
||||
Ref OpDispatchBuilder::CalculateAFForDecimal(Ref A) {
|
||||
auto Nibble = _And(OpSize::i64Bit, A, Constant(0xF));
|
||||
auto Greater = _Select(FEXCore::IR::COND_UGT, Nibble, Constant(9), Constant(1), Constant(0));
|
||||
auto Greater = Select01(OpSize::i64Bit, CondClassType {COND_UGT}, Nibble, Constant(9));
|
||||
|
||||
return _Or(OpSize::i64Bit, LoadAF(), Greater);
|
||||
}
|
||||
@@ -2759,7 +2755,7 @@ void OpDispatchBuilder::DAAOp(OpcodeArgs) {
|
||||
auto AF = CalculateAFForDecimal(AL);
|
||||
|
||||
// CF |= (AL > 0x99);
|
||||
CFInv = _And(OpSize::i64Bit, CFInv, _Select(FEXCore::IR::COND_ULE, AL, Constant(0x99), Constant(1), Constant(0)));
|
||||
CFInv = _And(OpSize::i64Bit, CFInv, Select01(OpSize::i64Bit, CondClassType {COND_ULE}, AL, Constant(0x99)));
|
||||
|
||||
// AL = AF ? (AL + 0x6) : AL;
|
||||
AL = _Select(FEXCore::IR::COND_NEQ, AF, Constant(0), _Add(OpSize::i64Bit, AL, Constant(0x6)), AL);
|
||||
@@ -2782,7 +2778,7 @@ void OpDispatchBuilder::DASOp(OpcodeArgs) {
|
||||
auto AF = CalculateAFForDecimal(AL);
|
||||
|
||||
// CF |= (AL > 0x99);
|
||||
CF = _Or(OpSize::i64Bit, CF, _Select(FEXCore::IR::COND_UGT, AL, Constant(0x99), Constant(1), Constant(0)));
|
||||
CF = _Or(OpSize::i64Bit, CF, Select01(OpSize::i64Bit, CondClassType {COND_UGT}, AL, Constant(0x99)));
|
||||
|
||||
// NewCF = CF | (AF && (Borrow from AL - 6))
|
||||
auto NewCF = _Or(OpSize::i32Bit, CF, _Select(FEXCore::IR::COND_ULT, AL, Constant(6), AF, CF));
|
||||
|
||||
@@ -2212,8 +2212,6 @@ void OpDispatchBuilder::AVX128_VTESTP(OpcodeArgs) {
|
||||
// For 256-bit, we need to split up the operation. This is nontrivial.
|
||||
// Let's go the simple route here.
|
||||
Ref ZF, CFInv;
|
||||
Ref ZeroConst = Constant(0);
|
||||
Ref OneConst = Constant(1);
|
||||
|
||||
const auto ElementSizeInBits = IR::OpSizeAsBits(ElementSize);
|
||||
|
||||
@@ -2255,7 +2253,7 @@ void OpDispatchBuilder::AVX128_VTESTP(OpcodeArgs) {
|
||||
|
||||
// ExtGPR will either be [0, 8] or [0, 16] If 0 then set Flag.
|
||||
auto ExtGPR = _VExtractToGPR(OpSize::i128Bit, ElementSize, AddWide, 0);
|
||||
CFInv = _Select(IR::COND_NEQ, ExtGPR, ZeroConst, OneConst, ZeroConst);
|
||||
CFInv = To01(OpSize::i64Bit, ExtGPR);
|
||||
}
|
||||
|
||||
// As in PTest, this sets Z appropriately while zeroing the rest of NZCV.
|
||||
@@ -2294,10 +2292,7 @@ void OpDispatchBuilder::AVX128_PTest(OpcodeArgs) {
|
||||
Test1 = _VExtractToGPR(OpSize::i128Bit, OpSize::i16Bit, Test1, 0);
|
||||
Test2 = _VExtractToGPR(OpSize::i128Bit, OpSize::i16Bit, Test2, 0);
|
||||
|
||||
auto ZeroConst = Constant(0);
|
||||
auto OneConst = Constant(1);
|
||||
|
||||
Test2 = _Select(FEXCore::IR::COND_NEQ, Test2, ZeroConst, OneConst, ZeroConst);
|
||||
Test2 = To01(OpSize::i64Bit, Test2);
|
||||
|
||||
// Careful, these flags are different between {V,}PTEST and VTESTP{S,D}
|
||||
// Set ZF according to Test1. SF will be zeroed since we do a 32-bit test on
|
||||
|
||||
@@ -267,8 +267,6 @@ Ref OpDispatchBuilder::IncrementByCarry(OpSize OpSize, Ref Src) {
|
||||
}
|
||||
|
||||
Ref OpDispatchBuilder::CalculateFlags_ADC(IR::OpSize SrcSize, Ref Src1, Ref Src2) {
|
||||
auto Zero = _InlineConstant(0);
|
||||
auto One = _InlineConstant(1);
|
||||
auto OpSize = SrcSize == OpSize::i64Bit ? OpSize::i64Bit : OpSize::i32Bit;
|
||||
Ref Res;
|
||||
|
||||
@@ -292,7 +290,7 @@ Ref OpDispatchBuilder::CalculateFlags_ADC(IR::OpSize SrcSize, Ref Src1, Ref Src2
|
||||
Res = _Bfe(OpSize, IR::OpSizeAsBits(SrcSize), 0, Res);
|
||||
|
||||
// TODO: We can fold that second Bfe in (cmp uxth).
|
||||
auto SelectCFInv = _Select(FEXCore::IR::COND_UGE, Res, Src2PlusCF, One, Zero);
|
||||
auto SelectCFInv = Select01(OpSize, CondClassType {COND_UGE}, Res, Src2PlusCF);
|
||||
|
||||
SetNZ_ZeroCV(SrcSize, Res);
|
||||
SetCFInverted(SelectCFInv);
|
||||
@@ -304,8 +302,6 @@ Ref OpDispatchBuilder::CalculateFlags_ADC(IR::OpSize SrcSize, Ref Src1, Ref Src2
|
||||
}
|
||||
|
||||
Ref OpDispatchBuilder::CalculateFlags_SBB(IR::OpSize SrcSize, Ref Src1, Ref Src2) {
|
||||
auto Zero = _InlineConstant(0);
|
||||
auto One = _InlineConstant(1);
|
||||
auto OpSize = SrcSize == OpSize::i64Bit ? OpSize::i64Bit : OpSize::i32Bit;
|
||||
|
||||
CalculateAF(Src1, Src2);
|
||||
@@ -328,7 +324,7 @@ Ref OpDispatchBuilder::CalculateFlags_SBB(IR::OpSize SrcSize, Ref Src1, Ref Src2
|
||||
Res = _Sub(OpSize, Src1, Src2PlusCF);
|
||||
Res = _Bfe(OpSize, IR::OpSizeAsBits(SrcSize), 0, Res);
|
||||
|
||||
auto SelectCFInv = _Select(FEXCore::IR::COND_UGE, Src1, Src2PlusCF, One, Zero);
|
||||
auto SelectCFInv = Select01(OpSize, CondClassType {COND_UGE}, Src1, Src2PlusCF);
|
||||
|
||||
SetNZ_ZeroCV(SrcSize, Res);
|
||||
SetCFInverted(SelectCFInv);
|
||||
|
||||
@@ -3950,10 +3950,7 @@ void OpDispatchBuilder::PTestOpImpl(OpSize Size, Ref Dest, Ref Src) {
|
||||
Test1 = _VExtractToGPR(Size, OpSize::i16Bit, Test1, 0);
|
||||
Test2 = _VExtractToGPR(Size, OpSize::i16Bit, Test2, 0);
|
||||
|
||||
auto ZeroConst = Constant(0);
|
||||
auto OneConst = Constant(1);
|
||||
|
||||
Test2 = _Select(FEXCore::IR::COND_NEQ, Test2, ZeroConst, OneConst, ZeroConst);
|
||||
Test2 = To01(OpSize::i64Bit, Test2);
|
||||
|
||||
// Careful, these flags are different between {V,}PTEST and VTESTP{S,D}
|
||||
// Set ZF according to Test1. SF will be zeroed since we do a 32-bit test on
|
||||
@@ -3990,10 +3987,7 @@ void OpDispatchBuilder::VTESTOpImpl(OpSize SrcSize, IR::OpSize ElementSize, Ref
|
||||
Ref AndGPR = _VExtractToGPR(SrcSize, OpSize::i16Bit, MaxAnd, 0);
|
||||
Ref AndNotGPR = _VExtractToGPR(SrcSize, OpSize::i16Bit, MaxAndNot, 0);
|
||||
|
||||
Ref ZeroConst = Constant(0);
|
||||
Ref OneConst = Constant(1);
|
||||
|
||||
Ref CFInv = _Select(IR::COND_NEQ, AndNotGPR, ZeroConst, OneConst, ZeroConst);
|
||||
Ref CFInv = To01(OpSize::i64Bit, AndNotGPR);
|
||||
|
||||
// As in PTest, this sets Z appropriately while zeroing the rest of NZCV.
|
||||
SetNZ_ZeroCV(OpSize::i32Bit, AndGPR);
|
||||
|
||||
@@ -851,11 +851,9 @@ void OpDispatchBuilder::X87FXAM(OpcodeArgs) {
|
||||
// Claim this is a normal number
|
||||
// We don't support anything else
|
||||
auto TopValid = _StackValidTag(0);
|
||||
auto ZeroConst = Constant(0);
|
||||
auto OneConst = Constant(1);
|
||||
|
||||
// In the case of top being invalid then C3:C2:C0 is 0b101
|
||||
auto C3 = _Select(FEXCore::IR::COND_NEQ, TopValid, OneConst, OneConst, ZeroConst);
|
||||
auto C3 = Select01(OpSize::i32Bit, CondClassType {COND_NEQ}, TopValid, Constant(1));
|
||||
|
||||
auto C2 = TopValid;
|
||||
auto C0 = C3; // Mirror C3 until something other than zero is supported
|
||||
|
||||
@@ -82,6 +82,14 @@ public:
|
||||
return _StoreMem(Class, Size, Value, Addr, Invalid(), Align, MEM_OFFSET_SXTX, 1);
|
||||
}
|
||||
|
||||
IRPair<IROp_Select> Select01(FEXCore::IR::OpSize CompareSize, CondClassType Cond, OrderedNode* Cmp1, OrderedNode* Cmp2) {
|
||||
return _Select(OpSize::i64Bit, CompareSize, Cond, Cmp1, Cmp2, _InlineConstant(1), _InlineConstant(0));
|
||||
}
|
||||
|
||||
IRPair<IROp_Select> To01(FEXCore::IR::OpSize CompareSize, OrderedNode* Cmp1) {
|
||||
return Select01(CompareSize, CondClassType {COND_NEQ}, Cmp1, Constant(0));
|
||||
}
|
||||
|
||||
int64_t Constants[32];
|
||||
Ref ConstantRefs[32];
|
||||
uint32_t NrConstants;
|
||||
|
||||
Reference in new issue
Block a user