OpcodeDispatcher: Use NZCVSelect for SelectCC

Massively better codegen.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
Alyssa Rosenzweig 2023-11-10 09:04:53 -04:00
parent 228c7d142e
commit b187a853e7
2 changed files with 12 additions and 44 deletions

View File

@ -852,39 +852,34 @@ OrderedNode *OpDispatchBuilder::SelectMask(OrderedNode *Cmp, uint64_t Mask, bool
TrueValue, FalseValue);
}
OrderedNode *OpDispatchBuilder::SelectNZCV(unsigned BitOffset, bool TrueIsNonzero, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue) {
return SelectMask(GetNZCV(), 1u << IndexNZCV(BitOffset), TrueIsNonzero, ResultSize, TrueValue, FalseValue);
}
OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue) {
OrderedNode *SrcCond = nullptr;
auto ZeroConst = _Constant(0);
auto OneConst = _Constant(1);
switch (OP) {
case 0x0: { // JO - Jump if OF == 1
SrcCond = SelectNZCV(FEXCore::X86State::RFLAG_OF_RAW_LOC, true, ResultSize, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_FU}, TrueValue, FalseValue);
break;
}
case 0x1:{ // JNO - Jump if OF == 0
SrcCond = SelectNZCV(FEXCore::X86State::RFLAG_OF_RAW_LOC, false, ResultSize, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_FNU}, TrueValue, FalseValue);
break;
}
case 0x2: { // JC - Jump if CF == 1
SrcCond = SelectNZCV(FEXCore::X86State::RFLAG_CF_RAW_LOC, true, ResultSize, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_UGE}, TrueValue, FalseValue);
break;
}
case 0x3: { // JNC - Jump if CF == 0
SrcCond = SelectNZCV(FEXCore::X86State::RFLAG_CF_RAW_LOC, false, ResultSize, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_ULT}, TrueValue, FalseValue);
break;
}
case 0x4: { // JE - Jump if ZF == 1
SrcCond = SelectNZCV(FEXCore::X86State::RFLAG_ZF_RAW_LOC, true, ResultSize, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_EQ}, TrueValue, FalseValue);
break;
}
case 0x5: { // JNE - Jump if ZF == 0
SrcCond = SelectNZCV(FEXCore::X86State::RFLAG_ZF_RAW_LOC, false, ResultSize, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_NEQ}, TrueValue, FalseValue);
break;
}
case 0x6: { // JNA - Jump if CF == 1 || ZC == 1
@ -900,11 +895,11 @@ OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, IR::OpSize ResultSize, Orde
break;
}
case 0x8: { // JS - Jump if SF == 1
SrcCond = SelectNZCV(FEXCore::X86State::RFLAG_SF_RAW_LOC, true, ResultSize, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_MI}, TrueValue, FalseValue);
break;
}
case 0x9: { // JNS - Jump if SF == 0
SrcCond = SelectNZCV(FEXCore::X86State::RFLAG_SF_RAW_LOC, false, ResultSize, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_PL}, TrueValue, FalseValue);
break;
}
case 0xA: { // JP - Jump if PF == 1
@ -917,45 +912,19 @@ OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, IR::OpSize ResultSize, Orde
break;
}
case 0xC: { // SF <> OF
auto Flag1 = GetRFLAG(FEXCore::X86State::RFLAG_SF_RAW_LOC);
auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_OF_RAW_LOC);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_NEQ},
Flag1, Flag2, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_SLT}, TrueValue, FalseValue);
break;
}
case 0xD: { // SF = OF
auto Flag1 = GetRFLAG(FEXCore::X86State::RFLAG_SF_RAW_LOC);
auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_OF_RAW_LOC);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_EQ},
Flag1, Flag2, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_SGE}, TrueValue, FalseValue);
break;
}
case 0xE: {// ZF = 1 || SF <> OF
auto Select1 = SelectNZCV(FEXCore::X86State::RFLAG_ZF_RAW_LOC, true, OpSize::i32Bit,
OneConst, ZeroConst);
auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_SF_RAW_LOC);
auto Flag3 = GetRFLAG(FEXCore::X86State::RFLAG_OF_RAW_LOC);
auto Select2 = _Select(OpSize::i32Bit, OpSize::i32Bit, CondClassType{COND_NEQ},
Flag2, Flag3, OneConst, ZeroConst);
auto Check = _Or(OpSize::i32Bit, Select1, Select2);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_EQ},
Check, OneConst, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_SLE}, TrueValue, FalseValue);
break;
}
case 0xF: {// ZF = 0 && SF = OF
auto Select1 = SelectNZCV(FEXCore::X86State::RFLAG_ZF_RAW_LOC, false, OpSize::i32Bit,
OneConst, ZeroConst);
auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_SF_RAW_LOC);
auto Flag3 = GetRFLAG(FEXCore::X86State::RFLAG_OF_RAW_LOC);
auto Select2 = _Select(OpSize::i32Bit, OpSize::i32Bit, CondClassType{COND_EQ},
Flag2, Flag3, OneConst, ZeroConst);
auto Check = _And(OpSize::i32Bit, Select1, Select2);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_EQ},
Check, OneConst, TrueValue, FalseValue);
SrcCond = _NZCVSelect(ResultSize, CondClassType{COND_SGT}, TrueValue, FalseValue);
break;
}
default:

View File

@ -1449,7 +1449,6 @@ private:
}
OrderedNode *SelectMask(OrderedNode *Cmp, uint64_t Mask, bool Invert, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue);
OrderedNode *SelectNZCV(unsigned BitOffset, bool Invert, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue);
OrderedNode *SelectCC(uint8_t OP, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue);
/**