Merge pull request #3129 from Sonicadvance1/remove_non_explicit_selectcc

OpcodeDispatcher: Removes non-explicit SelectCC function
This commit is contained in:
Mai authored and GitHub committed 2023-09-21 08:33:30 -04:00
commit 43fd159689
4 files changed
+28 -257

No files matched your search

@@ -835,234 +835,7 @@ void OpDispatchBuilder::CALLAbsoluteOp(OpcodeArgs) {
_ExitFunction(JMPPCOffset); // If we get here then leave the function now
}
OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, OrderedNode *TrueValue, OrderedNode *FalseValue) {
OrderedNode *SrcCond = nullptr;
auto ZeroConst = _Constant(0);
auto OneConst = _Constant(1);
switch (OP) {
case 0x0: { // JO - Jump if OF == 1
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_OF_LOC);
SrcCond = _Select(FEXCore::IR::COND_NEQ,
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x1:{ // JNO - Jump if OF == 0
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_OF_LOC);
SrcCond = _Select(FEXCore::IR::COND_EQ,
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x2: { // JC - Jump if CF == 1
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_CF_LOC);
SrcCond = _Select(FEXCore::IR::COND_NEQ,
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x3: { // JNC - Jump if CF == 0
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_CF_LOC);
SrcCond = _Select(FEXCore::IR::COND_EQ,
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x4: { // JE - Jump if ZF == 1
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_ZF_LOC);
SrcCond = _Select(FEXCore::IR::COND_NEQ,
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x5: { // JNE - Jump if ZF == 0
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_ZF_LOC);
SrcCond = _Select(FEXCore::IR::COND_EQ,
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x6: { // JNA - Jump if CF == 1 || ZC == 1
auto Flag1 = GetRFLAG(FEXCore::X86State::RFLAG_ZF_LOC);
auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_CF_LOC);
auto Check = _Or(IR::SizeToOpSize(std::max<uint8_t>(4u, std::max(GetOpSize(Flag1), GetOpSize(Flag2)))), Flag1, Flag2);
SrcCond = _Select(FEXCore::IR::COND_EQ,
Check, OneConst, TrueValue, FalseValue);
break;
}
case 0x7: { // JA - Jump if CF == 0 && ZF == 0
auto Flag1 = GetRFLAG(FEXCore::X86State::RFLAG_ZF_LOC);
auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_CF_LOC);
auto Check = _Or(IR::SizeToOpSize(std::max<uint8_t>(4u, std::max(GetOpSize(Flag1), GetOpSize(Flag2)))), Flag1, Flag2);
SrcCond = _Select(FEXCore::IR::COND_EQ,
Check, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x8: { // JS - Jump if SF == 1
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_SF_LOC);
SrcCond = _Select(FEXCore::IR::COND_NEQ,
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x9: { // JNS - Jump if SF == 0
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_SF_LOC);
SrcCond = _Select(FEXCore::IR::COND_EQ,
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0xA: { // JP - Jump if PF == 1
SrcCond = _Select(FEXCore::IR::COND_EQ, LoadPFInverted(), ZeroConst, TrueValue, FalseValue);
break;
}
case 0xB: { // JNP - Jump if PF == 0
SrcCond = _Select(FEXCore::IR::COND_NEQ, LoadPFInverted(), ZeroConst, TrueValue, FalseValue);
break;
}
case 0xC: { // SF <> OF
auto Flag1 = GetRFLAG(FEXCore::X86State::RFLAG_SF_LOC);
auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_OF_LOC);
SrcCond = _Select(FEXCore::IR::COND_NEQ,
Flag1, Flag2, TrueValue, FalseValue);
break;
}
case 0xD: { // SF = OF
auto Flag1 = GetRFLAG(FEXCore::X86State::RFLAG_SF_LOC);
auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_OF_LOC);
SrcCond = _Select(FEXCore::IR::COND_EQ,
Flag1, Flag2, TrueValue, FalseValue);
break;
}
case 0xE: {// ZF = 1 || SF <> OF
auto Flag1 = GetRFLAG(FEXCore::X86State::RFLAG_ZF_LOC);
auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_SF_LOC);
auto Flag3 = GetRFLAG(FEXCore::X86State::RFLAG_OF_LOC);
auto Select1 = _Select(FEXCore::IR::COND_EQ,
Flag1, OneConst, OneConst, ZeroConst);
auto Select2 = _Select(FEXCore::IR::COND_NEQ,
Flag2, Flag3, OneConst, ZeroConst);
auto Check = _Or(IR::SizeToOpSize(std::max<uint8_t>(4u, std::max(GetOpSize(Select1), GetOpSize(Select2)))), Select1, Select2);
SrcCond = _Select(FEXCore::IR::COND_EQ,
Check, OneConst, TrueValue, FalseValue);
break;
}
case 0xF: {// ZF = 0 && SF = OF
auto Flag1 = GetRFLAG(FEXCore::X86State::RFLAG_ZF_LOC);
auto Flag2 = GetRFLAG(FEXCore::X86State::RFLAG_SF_LOC);
auto Flag3 = GetRFLAG(FEXCore::X86State::RFLAG_OF_LOC);
auto Select1 = _Select(FEXCore::IR::COND_EQ,
Flag1, ZeroConst, OneConst, ZeroConst);
auto Select2 = _Select(FEXCore::IR::COND_EQ,
Flag2, Flag3, OneConst, ZeroConst);
auto Check = _And(IR::SizeToOpSize(std::max<uint8_t>(4u, std::max(GetOpSize(Select1), GetOpSize(Select2)))), Select1, Select2);
SrcCond = _Select(FEXCore::IR::COND_EQ,
Check, OneConst, TrueValue, FalseValue);
break;
}
default:
LOGMAN_MSG_A_FMT("Unknown CC Op: 0x{:x}\n", OP);
return nullptr;
}
// Try folding the flags generation in the select op
if (flagsOp == SelectionFlag::CMP) {
switch(OP) {
// SGT
case 0xF: SrcCond = _Select(FEXCore::IR::COND_SGT, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue, flagsOpSize); break;
// SLE
case 0xE: SrcCond = _Select(FEXCore::IR::COND_SLE, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue, flagsOpSize); break;
// SGE
case 0xD: SrcCond = _Select(FEXCore::IR::COND_SGE, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue, flagsOpSize); break;
// SL
case 0xC: SrcCond = _Select(FEXCore::IR::COND_SLT, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue, flagsOpSize); break;
// not sign
//case 0x99: SrcCond = _Select(FEXCore::IR::COND_, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue, flagsOpSize); break;
// sign
//case 0x98: SrcCond = _Select(FEXCore::IR::COND_, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue, flagsOpSize); break;
// UABove
case 0x7: SrcCond = _Select(FEXCore::IR::COND_UGT, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize); break;
// UBE
case 0x6: SrcCond = _Select(FEXCore::IR::COND_ULE, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize); break;
// NE
case 0x5: SrcCond = _Select(FEXCore::IR::COND_NEQ, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize); break;
// EQ/Zero
case 0x4: SrcCond = _Select(FEXCore::IR::COND_EQ, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize); break;
// UAE
case 0x3: SrcCond = _Select(FEXCore::IR::COND_UGE, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize); break;
// UBelow
case 0x2: SrcCond = _Select(FEXCore::IR::COND_ULT, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize); break;
//default: printf("Missed Condition %04X OP_CMP\n", OP); break;
}
}
else if (flagsOp == SelectionFlag::AND) {
switch(OP) {
case 0x4: SrcCond = _Select(FEXCore::IR::COND_EQ, flagsOpDest, ZeroConst, TrueValue, FalseValue, flagsOpSize); break;
case 0x5: SrcCond = _Select(FEXCore::IR::COND_NEQ, flagsOpDest, ZeroConst, TrueValue, FalseValue, flagsOpSize); break;
//default: printf("Missed Condition %04X OP_AND\n", OP); break;
}
} else if (flagsOp == SelectionFlag::FCMP) {
/*
x86:ZCP
unordered { 11 1 }
greater { 00 0 }
less { 01 0 }
equal { 10 0 }
aarch64: NZCV
unordered { 0 01 1 }
greater { 0 01 0 }
less { 1 00 0 }
equal { 0 11 0 }
*/
/*
eq = 0, // Z set Equal.
ne = 1, // Z clear Not equal.
cs = 2, // C set Carry set.
cc = 3, // C clear Carry clear.
mi = 4, // N set Negative.
pl = 5, // N clear Positive or zero.
vs = 6, // V set Overflow.
vc = 7, // V clear No overflow.
hi = 8, // C set, Z clear Unsigned higher.
ls = 9, // C clear or Z set Unsigned lower or same.
ge = 10, // N == V Greater or equal.
lt = 11, // N != V Less than.
gt = 12, // Z clear, N == V Greater than.
le = 13, // Z set or N != V Less then or equal
*/
switch(OP) {
case 0x2: // CF == 1 // less or unordered // N==1 OR V==1 // lt
SrcCond = _Select(FEXCore::IR::COND_FLU, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize);
break;
case 0x3: // CF == 0 // greater or equal (and not unordered) // N==V // ge
SrcCond = _Select(FEXCore::IR::COND_FGE, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize);
break;
case 0x6: // CF == 1 || ZF == 1 // less or equal or unordered // Z==1 OR N!=V // le
SrcCond = _Select(FEXCore::IR::COND_FLEU, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize);
break;
case 0x7: // CF == 0 && ZF == 0 // greater (and not unordered) // C==1 AND V=0 // hi
SrcCond = _Select(FEXCore::IR::COND_FGT, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize);
break;
case 0xA: // PF = 1 // unordered // V==1 // vs
SrcCond = _Select(FEXCore::IR::COND_FU, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize);
break;
case 0xB: // PF = 0 // not unordered // V==0 // vc
SrcCond = _Select(FEXCore::IR::COND_FNU, flagsOpDest, flagsOpSrc, TrueValue, FalseValue, flagsOpSize);
break;
default:
// TODO: Add more optimized cases
break;
}
}
return SrcCond;
}
OrderedNode *OpDispatchBuilder::SelectCCExplicitSize(uint8_t OP, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue) {
OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue) {
OrderedNode *SrcCond = nullptr;
auto ZeroConst = _Constant(0);
@@ -1298,7 +1071,7 @@ void OpDispatchBuilder::SETccOp(OpcodeArgs) {
auto ZeroConst = _Constant(0);
auto OneConst = _Constant(1);
auto SrcCond = SelectCC(Op->OP & 0xF, OneConst, ZeroConst);
auto SrcCond = SelectCC(Op->OP & 0xF, OpSize::i64Bit, OneConst, ZeroConst);
StoreResult(GPRClass, Op, SrcCond, -1);
}
@@ -1319,7 +1092,7 @@ void OpDispatchBuilder::CMOVOp(OpcodeArgs) {
Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
}
auto SrcCond = SelectCCExplicitSize(Op->OP & 0xF, IR::SizeToOpSize(std::max<uint8_t>(4u, GetSrcSize(Op))), Src, Dest);
auto SrcCond = SelectCC(Op->OP & 0xF, IR::SizeToOpSize(std::max<uint8_t>(4u, GetSrcSize(Op))), Src, Dest);
StoreResult(GPRClass, Op, SrcCond, -1);
}
@@ -1333,7 +1106,7 @@ void OpDispatchBuilder::CondJUMPOp(OpcodeArgs) {
auto TakeBranch = _Constant(1);
auto DoNotTakeBranch = _Constant(0);
auto SrcCond = SelectCC(Op->OP & 0xF, TakeBranch, DoNotTakeBranch);
auto SrcCond = SelectCC(Op->OP & 0xF, OpSize::i64Bit, TakeBranch, DoNotTakeBranch);
// Jump instruction only uses up to 32-bit signed displacement
LOGMAN_THROW_A_FMT(Op->Src[0].IsLiteral(), "Src1 needs to be literal here");
@@ -1280,9 +1280,7 @@ private:
CachedIndexedNamedVectorConstants.clear();
}
// TODO: SelectCC is duplicated SelectCCExplicitSize. Should get removed once all users are removed.
OrderedNode *SelectCC(uint8_t OP, OrderedNode *TrueValue, OrderedNode *FalseValue);
OrderedNode *SelectCCExplicitSize(uint8_t OP, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue);
OrderedNode *SelectCC(uint8_t OP, IR::OpSize ResultSize, OrderedNode *TrueValue, OrderedNode *FalseValue);
/**
* @name Deferred RFLAG calculation and generation.
@@ -1325,7 +1325,7 @@ void OpDispatchBuilder::X87FCMOV(OpcodeArgs) {
auto ZeroConst = _Constant(0);
auto AllOneConst = _Constant(0xffff'ffff'ffff'ffffull);
OrderedNode *SrcCond = SelectCCExplicitSize(CC, OpSize::i64Bit, AllOneConst, ZeroConst);
OrderedNode *SrcCond = SelectCC(CC, OpSize::i64Bit, AllOneConst, ZeroConst);
OrderedNode *VecCond = _VDupFromGPR(16, 8, SrcCond);
auto top = GetX87Top();
+22 -22
View File
@@ -1462,7 +1462,7 @@
"ExpectedArm64ASM": [
"ldr w20, [x28, #728]",
"ubfx w20, w20, #28, #1",
"cmp x20, #0x0 (0)",
"cmp w20, #0x0 (0)",
"cset x20, ne",
"bfxil x4, x20, #0, #8"
]
@@ -1474,7 +1474,7 @@
"ExpectedArm64ASM": [
"ldr w20, [x28, #728]",
"ubfx w20, w20, #28, #1",
"cmp x20, #0x0 (0)",
"cmp w20, #0x0 (0)",
"cset x20, eq",
"bfxil x4, x20, #0, #8"
]
@@ -1486,7 +1486,7 @@
"ExpectedArm64ASM": [
"ldr w20, [x28, #728]",
"ubfx w20, w20, #29, #1",
"cmp x20, #0x0 (0)",
"cmp w20, #0x0 (0)",
"cset x20, ne",
"bfxil x4, x20, #0, #8"
]
@@ -1498,7 +1498,7 @@
"ExpectedArm64ASM": [
"ldr w20, [x28, #728]",
"ubfx w20, w20, #29, #1",
"cmp x20, #0x0 (0)",
"cmp w20, #0x0 (0)",
"cset x20, eq",
"bfxil x4, x20, #0, #8"
]
@@ -1510,7 +1510,7 @@
"ExpectedArm64ASM": [
"ldr w20, [x28, #728]",
"ubfx w20, w20, #30, #1",
"cmp x20, #0x0 (0)",
"cmp w20, #0x0 (0)",
"cset x20, ne",
"bfxil x4, x20, #0, #8"
]
@@ -1522,7 +1522,7 @@
"ExpectedArm64ASM": [
"ldr w20, [x28, #728]",
"ubfx w20, w20, #30, #1",
"cmp x20, #0x0 (0)",
"cmp w20, #0x0 (0)",
"cset x20, eq",
"bfxil x4, x20, #0, #8"
]
@@ -1536,7 +1536,7 @@
"ubfx w21, w20, #30, #1",
"ubfx w20, w20, #29, #1",
"orr w20, w21, w20",
"cmp x20, #0x1 (1)",
"cmp w20, #0x1 (1)",
"cset x20, eq",
"bfxil x4, x20, #0, #8"
]
@@ -1550,7 +1550,7 @@
"ubfx w21, w20, #30, #1",
"ubfx w20, w20, #29, #1",
"orr w20, w21, w20",
"cmp x20, #0x0 (0)",
"cmp w20, #0x0 (0)",
"cset x20, eq",
"bfxil x4, x20, #0, #8"
]
@@ -1562,7 +1562,7 @@
"ExpectedArm64ASM": [
"ldr w20, [x28, #728]",
"lsr w20, w20, #31",
"cmp x20, #0x0 (0)",
"cmp w20, #0x0 (0)",
"cset x20, ne",
"bfxil x4, x20, #0, #8"
]
@@ -1574,7 +1574,7 @@
"ExpectedArm64ASM": [
"ldr w20, [x28, #728]",
"lsr w20, w20, #31",
"cmp x20, #0x0 (0)",
"cmp w20, #0x0 (0)",
"cset x20, eq",
"bfxil x4, x20, #0, #8"
]
@@ -1589,7 +1589,7 @@
"cnt v2.16b, v2.16b",
"umov w20, v2.b[0]",
"and x20, x20, #0x1",
"cmp x20, #0x0 (0)",
"cmp w20, #0x0 (0)",
"cset x20, eq",
"bfxil x4, x20, #0, #8"
]
@@ -1604,7 +1604,7 @@
"cnt v2.16b, v2.16b",
"umov w20, v2.b[0]",
"and x20, x20, #0x1",
"cmp x20, #0x0 (0)",
"cmp w20, #0x0 (0)",
"cset x20, ne",
"bfxil x4, x20, #0, #8"
]
@@ -1644,12 +1644,12 @@
"ubfx w21, w20, #30, #1",
"lsr w22, w20, #31",
"ubfx w20, w20, #28, #1",
"cmp x21, #0x1 (1)",
"cset x21, eq",
"cmp w21, #0x1 (1)",
"cset w21, eq",
"cmp w22, w20",
"cset x20, ne",
"orr x20, x21, x20",
"cmp x20, #0x1 (1)",
"cset w20, ne",
"orr w20, w21, w20",
"cmp w20, #0x1 (1)",
"cset x20, eq",
"bfxil x4, x20, #0, #8"
]
@@ -1663,12 +1663,12 @@
"ubfx w21, w20, #30, #1",
"lsr w22, w20, #31",
"ubfx w20, w20, #28, #1",
"cmp x21, #0x0 (0)",
"cset x21, eq",
"cmp w21, #0x0 (0)",
"cset w21, eq",
"cmp w22, w20",
"cset x20, eq",
"and x20, x21, x20",
"cmp x20, #0x1 (1)",
"cset w20, eq",
"and w20, w21, w20",
"cmp w20, #0x1 (1)",
"cset x20, eq",
"bfxil x4, x20, #0, #8"
]