Merge pull request #3100 from Sonicadvance1/optimize_cmov

OpcodeDispatcher: Optimize cmov
This commit is contained in:
Alyssa Rosenzweig authored and GitHub committed 2023-09-15 15:17:51 -04:00
commit c8e7c347c3
7 files changed
+1341 -1268

No files matched your search

@@ -1061,6 +1061,233 @@ OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, OrderedNode *TrueValue, Ord
return SrcCond;
}
OrderedNode *OpDispatchBuilder::SelectCCExplicitSize(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
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_OF_LOC);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_NEQ},
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x1:{ // JNO - Jump if OF == 0
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_OF_LOC);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_EQ},
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x2: { // JC - Jump if CF == 1
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_CF_LOC);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_NEQ},
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x3: { // JNC - Jump if CF == 0
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_CF_LOC);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_EQ},
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x4: { // JE - Jump if ZF == 1
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_ZF_LOC);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_NEQ},
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x5: { // JNE - Jump if ZF == 0
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_ZF_LOC);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{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(OpSize::i32Bit, Flag1, Flag2);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{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(OpSize::i32Bit, Flag1, Flag2);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_EQ},
Check, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x8: { // JS - Jump if SF == 1
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_SF_LOC);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_NEQ},
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0x9: { // JNS - Jump if SF == 0
auto Flag = GetRFLAG(FEXCore::X86State::RFLAG_SF_LOC);
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_EQ},
Flag, ZeroConst, TrueValue, FalseValue);
break;
}
case 0xA: { // JP - Jump if PF == 1
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_NEQ}, LoadPF(), ZeroConst, TrueValue, FalseValue);
break;
}
case 0xB: { // JNP - Jump if PF == 0
SrcCond = _Select(ResultSize, OpSize::i32Bit, CondClassType{COND_EQ}, LoadPF(), 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(ResultSize, OpSize::i32Bit, CondClassType{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(ResultSize, OpSize::i32Bit, CondClassType{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(OpSize::i32Bit, OpSize::i32Bit, CondClassType{COND_EQ},
Flag1, OneConst, OneConst, ZeroConst);
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);
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(OpSize::i32Bit, OpSize::i32Bit, CondClassType{COND_EQ},
Flag1, ZeroConst, OneConst, ZeroConst);
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);
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(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_SGT}, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue); break;
// SLE
case 0xE: SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_SLE}, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue); break;
// SGE
case 0xD: SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_SGE}, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue); break;
// SL
case 0xC: SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_SLT}, flagsOpDestSigned, flagsOpSrcSigned, TrueValue, FalseValue); 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(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_UGT}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue); break;
// UBE
case 0x6: SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_ULE}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue); break;
// NE
case 0x5: SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_NEQ}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue); break;
// EQ/Zero
case 0x4: SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_EQ}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue); break;
// UAE
case 0x3: SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_UGE}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue); break;
// UBelow
case 0x2: SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_ULT}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue); break;
//default: printf("Missed Condition %04X OP_CMP\n", OP); break;
}
}
else if (flagsOp == SelectionFlag::AND) {
switch(OP) {
case 0x4: SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_EQ}, flagsOpDest, ZeroConst, TrueValue, FalseValue); break;
case 0x5: SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_NEQ}, flagsOpDest, ZeroConst, TrueValue, FalseValue); 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(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_FLU}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue);
break;
case 0x3: // CF == 0 // greater or equal (and not unordered) // N==V // ge
SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_FGE}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue);
break;
case 0x6: // CF == 1 || ZF == 1 // less or equal or unordered // Z==1 OR N!=V // le
SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_FLEU}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue);
break;
case 0x7: // CF == 0 && ZF == 0 // greater (and not unordered) // C==1 AND V=0 // hi
SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_FGT}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue);
break;
case 0xA: // PF = 1 // unordered // V==1 // vs
SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_FU}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue);
break;
case 0xB: // PF = 0 // not unordered // V==0 // vc
SrcCond = _Select(ResultSize, IR::SizeToOpSize(flagsOpSize), CondClassType{COND_FNU}, flagsOpDest, flagsOpSrc, TrueValue, FalseValue);
break;
default:
// TODO: Add more optimized cases
break;
}
}
return SrcCond;
}
void OpDispatchBuilder::SETccOp(OpcodeArgs) {
// Calculate flags early.
CalculateDeferredFlags();
@@ -1074,13 +1301,22 @@ void OpDispatchBuilder::SETccOp(OpcodeArgs) {
}
void OpDispatchBuilder::CMOVOp(OpcodeArgs) {
const uint8_t GPRSize = CTX->GetGPRSize();
// Calculate flags early.
CalculateDeferredFlags();
OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1);
// Destination is always a GPR.
OrderedNode *Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, GPRSize, Op->Flags, -1);
OrderedNode *Src{};
if (Op->Src[0].IsGPR()) {
Src = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], GPRSize, Op->Flags, -1);
}
else {
Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
}
auto SrcCond = SelectCC(Op->OP & 0xF, Src, Dest);
auto SrcCond = SelectCCExplicitSize(Op->OP & 0xF, IR::SizeToOpSize(std::max<uint8_t>(4u, GetSrcSize(Op))), Src, Dest);
StoreResult(GPRClass, Op, SrcCond, -1);
}
@@ -869,8 +869,9 @@ private:
}
}
OrderedNode* CachedNZCV = {};
uint32_t PossiblySetNZCVBits = 0;
OrderedNode* CachedNZCV{};
bool NZCVDirty{};
uint32_t PossiblySetNZCVBits{};
fextl::map<uint64_t, JumpTargetInfo> JumpTargets;
bool HandledLock{false};
@@ -1115,11 +1116,13 @@ private:
void SetNZCV(OrderedNode *Value) {
CachedNZCV = Value;
NZCVDirty = true;
}
void ZeroNZCV() {
CachedNZCV = _Constant(0);
PossiblySetNZCVBits = 0;
NZCVDirty = true;
}
void ZeroCV() {
@@ -1152,6 +1155,7 @@ private:
// Mask off just the N bit, which now equals the sign bit
CachedNZCV = _And(OpSize::i32Bit, Shifted, _Constant(1u << NBit));
PossiblySetNZCVBits = (1u << NBit);
NZCVDirty = true;
}
void SetNZ_ZeroCV(unsigned SrcSize, OrderedNode *Res) {
@@ -1160,6 +1164,7 @@ private:
if (SrcSize >= 4) {
CachedNZCV = _TestNZ(SrcSize, Res);
PossiblySetNZCVBits = (1u << 31) | (1u << 30);
NZCVDirty = true;
} else {
// N
SetN_ZeroZCV(SrcSize, Res);
@@ -1274,7 +1279,9 @@ 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);
/**
* @name Deferred RFLAG calculation and generation.
@@ -272,10 +272,11 @@ void OpDispatchBuilder::CalculateAF(OpSize OpSize, OrderedNode *Res, OrderedNode
void OpDispatchBuilder::CalculateDeferredFlags(uint32_t FlagsToCalculateMask) {
if (CurrentDeferredFlags.Type == FlagsGenerationType::TYPE_NONE) {
// Nothing to do
if (CachedNZCV)
if (NZCVDirty && CachedNZCV)
_StoreFlag(CachedNZCV, FEXCore::X86State::RFLAG_NZCV_LOC);
CachedNZCV = nullptr;
NZCVDirty = false;
return;
}
@@ -459,10 +460,11 @@ void OpDispatchBuilder::CalculateDeferredFlags(uint32_t FlagsToCalculateMask) {
// Done calculating
CurrentDeferredFlags.Type = FlagsGenerationType::TYPE_NONE;
if (CachedNZCV)
if (NZCVDirty && CachedNZCV)
_StoreFlag(CachedNZCV, FEXCore::X86State::RFLAG_NZCV_LOC);
CachedNZCV = nullptr;
NZCVDirty = false;
}
void OpDispatchBuilder::CalculateFlags_ADC(uint8_t SrcSize, OrderedNode *Res, OrderedNode *Src1, OrderedNode *Src2, OrderedNode *CF) {
+63 -66
View File
@@ -3100,7 +3100,7 @@
"ExpectedArm64ASM": []
},
"pushf": {
"ExpectedInstructionCount": 43,
"ExpectedInstructionCount": 42,
"Optimal": "No",
"Comment": "0x9c",
"ExpectedArm64ASM": [
@@ -3142,15 +3142,14 @@
"orr x21, x21, x22, lsl #20",
"ldrb w22, [x28, #725]",
"orr x21, x21, x22, lsl #21",
"and x22, x20, #0xc0000000",
"orr x21, x21, x22, lsr #24",
"orr x21, x21, #0x2",
"str x21, [x8, #-8]!",
"str w20, [x28, #728]"
"and x20, x20, #0xc0000000",
"orr x20, x21, x20, lsr #24",
"orr x20, x20, #0x2",
"str x20, [x8, #-8]!"
]
},
"pushfq": {
"ExpectedInstructionCount": 43,
"ExpectedInstructionCount": 42,
"Optimal": "No",
"Comment": "0x9c",
"ExpectedArm64ASM": [
@@ -3192,11 +3191,10 @@
"orr x21, x21, x22, lsl #20",
"ldrb w22, [x28, #725]",
"orr x21, x21, x22, lsl #21",
"and x22, x20, #0xc0000000",
"orr x21, x21, x22, lsr #24",
"orr x21, x21, #0x2",
"str x21, [x8, #-8]!",
"str w20, [x28, #728]"
"and x20, x20, #0xc0000000",
"orr x20, x21, x20, lsr #24",
"orr x20, x20, #0x2",
"str x20, [x8, #-8]!"
]
},
"popf": {
@@ -3273,7 +3271,7 @@
]
},
"lahf": {
"ExpectedInstructionCount": 19,
"ExpectedInstructionCount": 18,
"Optimal": "Yes",
"Comment": "0x9f",
"ExpectedArm64ASM": [
@@ -3291,11 +3289,10 @@
"eor w22, w22, w23",
"ubfx w22, w22, #4, #1",
"orr x21, x21, x22, lsl #4",
"and x22, x20, #0xc0000000",
"orr x21, x21, x22, lsr #24",
"orr x21, x21, #0x2",
"bfi x4, x21, #8, #8",
"str w20, [x28, #728]"
"and x20, x20, #0xc0000000",
"orr x20, x21, x20, lsr #24",
"orr x20, x20, #0x2",
"bfi x4, x20, #8, #8"
]
},
"db 0x48, 0xa1; dq 0x00000000e0000008": {
@@ -3736,12 +3733,12 @@
"and w21, w21, w22",
"ubfx w21, w21, #7, #1",
"orr w21, w24, w21, lsl #28",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"add x10, x10, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbnz w22, #-0x68"
"ubfx w21, w21, #30, #1",
"cbnz w21, #-0x68"
]
},
"repz cmpsw": {
@@ -3775,12 +3772,12 @@
"and w21, w21, w22",
"ubfx w21, w21, #15, #1",
"orr w21, w24, w21, lsl #28",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"add x10, x10, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbnz w22, #-0x68"
"ubfx w21, w21, #30, #1",
"cbnz w21, #-0x68"
]
},
"repz cmpsd": {
@@ -3803,12 +3800,12 @@
"cmp w22, w21",
"mrs x21, nzcv",
"eor w21, w21, #0x20000000",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"add x10, x10, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbnz w22, #-0x3c"
"ubfx w21, w21, #30, #1",
"cbnz w21, #-0x3c"
]
},
"repz cmpsq": {
@@ -3831,12 +3828,12 @@
"cmp x22, x21",
"mrs x21, nzcv",
"eor w21, w21, #0x20000000",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"add x10, x10, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbnz w22, #-0x3c"
"ubfx w21, w21, #30, #1",
"cbnz w21, #-0x3c"
]
},
"repnz cmpsb": {
@@ -3870,12 +3867,12 @@
"and w21, w21, w22",
"ubfx w21, w21, #7, #1",
"orr w21, w24, w21, lsl #28",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"add x10, x10, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbz w22, #-0x68"
"ubfx w21, w21, #30, #1",
"cbz w21, #-0x68"
]
},
"repnz cmpsw": {
@@ -3909,12 +3906,12 @@
"and w21, w21, w22",
"ubfx w21, w21, #15, #1",
"orr w21, w24, w21, lsl #28",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"add x10, x10, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbz w22, #-0x68"
"ubfx w21, w21, #30, #1",
"cbz w21, #-0x68"
]
},
"repnz cmpsd": {
@@ -3937,12 +3934,12 @@
"cmp w22, w21",
"mrs x21, nzcv",
"eor w21, w21, #0x20000000",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"add x10, x10, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbz w22, #-0x3c"
"ubfx w21, w21, #30, #1",
"cbz w21, #-0x3c"
]
},
"repnz cmpsq": {
@@ -3965,12 +3962,12 @@
"cmp x22, x21",
"mrs x21, nzcv",
"eor w21, w21, #0x20000000",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"add x10, x10, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbz w22, #-0x3c"
"ubfx w21, w21, #30, #1",
"cbz w21, #-0x3c"
]
},
"test al, 1": {
@@ -4460,11 +4457,11 @@
"and w21, w22, w21",
"ubfx w21, w21, #7, #1",
"orr w21, w24, w21, lsl #28",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbnz w22, #-0x64"
"ubfx w21, w21, #30, #1",
"cbnz w21, #-0x64"
]
},
"repz scasw": {
@@ -4498,11 +4495,11 @@
"and w21, w22, w21",
"ubfx w21, w21, #15, #1",
"orr w21, w24, w21, lsl #28",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbnz w22, #-0x64"
"ubfx w21, w21, #30, #1",
"cbnz w21, #-0x64"
]
},
"repz scasd": {
@@ -4525,11 +4522,11 @@
"cmp w21, w22",
"mrs x21, nzcv",
"eor w21, w21, #0x20000000",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbnz w22, #-0x38"
"ubfx w21, w21, #30, #1",
"cbnz w21, #-0x38"
]
},
"repz scasq": {
@@ -4551,11 +4548,11 @@
"cmp x4, x21",
"mrs x21, nzcv",
"eor w21, w21, #0x20000000",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbnz w22, #-0x34"
"ubfx w21, w21, #30, #1",
"cbnz w21, #-0x34"
]
},
"repnz scasb": {
@@ -4589,11 +4586,11 @@
"and w21, w22, w21",
"ubfx w21, w21, #7, #1",
"orr w21, w24, w21, lsl #28",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbz w22, #-0x64"
"ubfx w21, w21, #30, #1",
"cbz w21, #-0x64"
]
},
"repnz scasw": {
@@ -4627,11 +4624,11 @@
"and w21, w22, w21",
"ubfx w21, w21, #15, #1",
"orr w21, w24, w21, lsl #28",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbz w22, #-0x64"
"ubfx w21, w21, #30, #1",
"cbz w21, #-0x64"
]
},
"repnz scasd": {
@@ -4654,11 +4651,11 @@
"cmp w21, w22",
"mrs x21, nzcv",
"eor w21, w21, #0x20000000",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbz w22, #-0x38"
"ubfx w21, w21, #30, #1",
"cbz w21, #-0x38"
]
},
"repnz scasq": {
@@ -4680,11 +4677,11 @@
"cmp x4, x21",
"mrs x21, nzcv",
"eor w21, w21, #0x20000000",
"str w21, [x28, #728]",
"sub x5, x5, #0x1 (1)",
"add x11, x11, x20",
"ubfx w22, w21, #30, #1",
"str w21, [x28, #728]",
"cbz w22, #-0x34"
"ubfx w21, w21, #30, #1",
"cbz w21, #-0x34"
]
},
"mov al, 0xff": {
@@ -563,18 +563,17 @@
]
},
"salc": {
"ExpectedInstructionCount": 8,
"ExpectedInstructionCount": 7,
"Optimal": "No",
"Comment": "0xd6",
"ExpectedArm64ASM": [
"uxtb w20, w4",
"ldr w21, [x28, #728]",
"ubfx w22, w21, #29, #1",
"add w20, w20, w22",
"uxtb w22, w4",
"sub w20, w22, w20",
"bfxil w4, w20, #0, #8",
"str w21, [x28, #728]"
"ubfx w21, w21, #29, #1",
"add w20, w20, w21",
"uxtb w21, w4",
"sub w20, w21, w20",
"bfxil w4, w20, #0, #8"
]
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff