Merge pull request #3218 from Sonicadvance1/opt_df

OpcodeDispatcher: Optimize DF pointer offset calculation
This commit is contained in:
Ryan Houdek authored and GitHub committed 2023-10-23 11:41:22 -07:00
commit 63e4c3682d
10 files changed
+393 -266

No files matched your search

@@ -187,6 +187,16 @@ DEF_OP(Sub) {
}
}
DEF_OP(SubShift) {
auto Op = IROp->C<IR::IROp_SubShift>();
const uint8_t OpSize = IROp->Size;
LOGMAN_THROW_AA_FMT(OpSize == 4 || OpSize == 8, "Unsupported {} size: {}", __func__, OpSize);
const auto EmitSize = OpSize == 8 ? ARMEmitter::Size::i64Bit : ARMEmitter::Size::i32Bit;
sub(EmitSize, GetReg(Node), GetReg(Op->Src1.ID()), GetReg(Op->Src2.ID()), ConvertIRShiftType(Op->Shift), Op->ShiftAmount);
}
DEF_OP(SubNZCV) {
auto Op = IROp->C<IR::IROp_SubNZCV>();
const IR::OpSize OpSize = Op->Size;
@@ -116,6 +116,15 @@ private:
return PhyReg;
}
// Converts IR-base shift type to ARMEmitter shift type.
// Will be a no-op, only a type conversion since the two definitions match.
[[nodiscard]] ARMEmitter::ShiftType ConvertIRShiftType(IR::ShiftType Shift) const {
return Shift == IR::ShiftType::LSL ? ARMEmitter::ShiftType::LSL :
Shift == IR::ShiftType::LSR ? ARMEmitter::ShiftType::LSR :
Shift == IR::ShiftType::ASR ? ARMEmitter::ShiftType::ASR :
ARMEmitter::ShiftType::ROR;
}
[[nodiscard]] bool IsFPR(IR::NodeID Node) const;
[[nodiscard]] bool IsGPR(IR::NodeID Node) const;
[[nodiscard]] bool IsGPRPair(IR::NodeID Node) const;
@@ -3858,14 +3858,10 @@ void OpDispatchBuilder::STOSOp(OpcodeArgs) {
// Store to memory where RDI points
_StoreMemAutoTSO(GPRClass, Size, Dest, Src, Size);
auto SizeConst = _Constant(Size);
auto NegSizeConst = _Constant(-Size);
// Calculate direction.
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
auto PtrDir = _Select(FEXCore::IR::COND_EQ,
DF, _Constant(0),
SizeConst, NegSizeConst);
auto SizeConst = _Constant(Size);
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
// Offset the pointer
OrderedNode *TailDest = LoadGPRRegister(X86State::REG_RDI);
@@ -3927,8 +3923,7 @@ void OpDispatchBuilder::MOVSOp(OpcodeArgs) {
}
else {
auto SizeConst = _Constant(Size);
auto NegSizeConst = _Constant(-Size);
auto PtrDir = _Select(FEXCore::IR::COND_EQ, DF, _Constant(0), SizeConst, NegSizeConst);
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
OrderedNode *RSI = LoadGPRRegister(X86State::REG_RSI);
OrderedNode *RDI = LoadGPRRegister(X86State::REG_RDI);
@@ -3974,9 +3969,8 @@ void OpDispatchBuilder::CMPSOp(OpcodeArgs) {
GenerateFlags_SUB(Op, Result, Src2, Src1);
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
auto PtrDir = _Select(FEXCore::IR::COND_EQ,
DF, _Constant(0),
_Constant(Size), _Constant(-Size));
auto SizeConst = _Constant(Size);
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
// Offset the pointer
Dest_RDI = _Add(OpSize::i64Bit, Dest_RDI, PtrDir);
@@ -3994,9 +3988,8 @@ void OpDispatchBuilder::CMPSOp(OpcodeArgs) {
// read DF once
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
auto PtrDir = _Select(FEXCore::IR::COND_EQ,
DF, _Constant(0),
_Constant(Size), _Constant(-Size));
auto SizeConst = _Constant(Size);
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
auto JumpStart = _Jump();
// Make sure to start a new block after ending this one
@@ -4088,13 +4081,9 @@ void OpDispatchBuilder::LODSOp(OpcodeArgs) {
StoreResult(GPRClass, Op, Src, -1);
auto SizeConst = _Constant(Size);
auto NegSizeConst = _Constant(-Size);
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
auto PtrDir = _Select(FEXCore::IR::COND_EQ,
DF, _Constant(0),
SizeConst, NegSizeConst);
auto SizeConst = _Constant(Size);
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
// Offset the pointer
OrderedNode *TailDest_RSI = LoadGPRRegister(X86State::REG_RSI);
@@ -4113,13 +4102,9 @@ void OpDispatchBuilder::LODSOp(OpcodeArgs) {
// May or may not matter
// Read DF once
auto SizeConst = _Constant(Size);
auto NegSizeConst = _Constant(-Size);
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
auto PtrDir = _Select(FEXCore::IR::COND_EQ,
DF, _Constant(0),
SizeConst, NegSizeConst);
auto SizeConst = _Constant(Size);
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
auto JumpStart = _Jump();
// Make sure to start a new block after ending this one
@@ -4194,13 +4179,9 @@ void OpDispatchBuilder::SCASOp(OpcodeArgs) {
OrderedNode* Result = _Sub(Size == 8 ? OpSize::i64Bit : OpSize::i32Bit, Src1, Src2);
GenerateFlags_SUB(Op, Result, Src1, Src2);
auto SizeConst = _Constant(Size);
auto NegSizeConst = _Constant(-Size);
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
auto PtrDir = _Select(FEXCore::IR::COND_EQ,
DF, _Constant(0),
SizeConst, NegSizeConst);
auto SizeConst = _Constant(Size);
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
// Offset the pointer
OrderedNode *TailDest_RDI = LoadGPRRegister(X86State::REG_RDI);
@@ -4215,14 +4196,9 @@ void OpDispatchBuilder::SCASOp(OpcodeArgs) {
bool REPE = Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_REP_PREFIX;
// read DF once
auto SizeConst = _Constant(Size);
auto NegSizeConst = _Constant(-Size);
auto DF = GetRFLAG(FEXCore::X86State::RFLAG_DF_LOC);
auto PtrDir = _Select(FEXCore::IR::COND_EQ,
DF, _Constant(0),
SizeConst, NegSizeConst);
auto SizeConst = _Constant(Size);
auto PtrDir = _SubShift(IR::SizeToOpSize(CTX->GetGPRSize()), SizeConst, DF, ShiftType::LSL, FEXCore::ilog2(Size) + 1);
auto JumpStart = _Jump();
// Make sure to start a new block after ending this one
+12 -1
View File
@@ -158,7 +158,8 @@
"RoundType": "RoundType",
"FloatCompareOp": "FloatCompareOp",
"NamedVectorConstant": "FEXCore::IR::NamedVectorConstant",
"IndexNamedVectorConstant": "FEXCore::IR::IndexNamedVectorConstant"
"IndexNamedVectorConstant": "FEXCore::IR::IndexNamedVectorConstant",
"ShiftType": "FEXCore::IR::ShiftType"
},
"Ops": {
"Misc": {
@@ -953,6 +954,16 @@
"Size == FEXCore::IR::OpSize::i32Bit || Size == FEXCore::IR::OpSize::i64Bit"
]
},
"GPR = SubShift OpSize:#Size, GPR:$Src1, GPR:$Src2, ShiftType:$Shift{ShiftType::LSL}, u8:$ShiftAmount{0}": {
"Desc": [ "Integer Sub with shifted register",
"Will truncate to 64 or 32bits"
],
"DestSize": "Size",
"EmitValidation": [
"Size == FEXCore::IR::OpSize::i32Bit || Size == FEXCore::IR::OpSize::i64Bit",
"_Shift != ShiftType::ROR"
]
},
"GPR = SubNZCV OpSize:$Size, GPR:$Src1, GPR:$Src2, u8:$InvertCarry": {
"Desc": ["Return NZCV for the difference of two GPRs. ",
"If InvertCarry is nonzero, carry flag uses x86 definition, inverted from arm64.",
+10
View File
@@ -257,6 +257,16 @@ static void PrintArg(fextl::stringstream *out, [[maybe_unused]] IRListView const
*out << static_cast<uint32_t>(Arg.si_code) << "}";
}
static void PrintArg(fextl::stringstream *out, [[maybe_unused]] IRListView const* IR, FEXCore::IR::ShiftType Arg) {
switch (Arg) {
case ShiftType::LSL: *out << "LSL"; break;
case ShiftType::LSR: *out << "LSR"; break;
case ShiftType::ASR: *out << "ASR"; break;
case ShiftType::ROR: *out << "ROR"; break;
default: *out << "<Unknown Shift Type>"; break;
}
}
void Dump(fextl::stringstream *out, IRListView const* IR, IR::RegisterAllocationData *RAData) {
auto HeaderOp = IR->GetHeader();
@@ -420,7 +420,6 @@ bool ConstProp::ZextAndMaskingElimination(IREmitter *IREmit, const IRListView& C
}
break;
}
case OP_AND: {
// if AND's arguments are imms, they are masking
for (int i = 0; i < IR::GetArgs(IROp->Op); i++) {
@@ -648,13 +647,31 @@ bool ConstProp::ConstantPropagation(IREmitter *IREmit, const IRListView& Current
auto Op = IROp->C<IR::IROp_Add>();
uint64_t Constant1{};
uint64_t Constant2{};
bool IsConstant1 = IREmit->IsValueConstant(Op->Header.Args[0], &Constant1);
bool IsConstant2 = IREmit->IsValueConstant(Op->Header.Args[1], &Constant2);
if (IREmit->IsValueConstant(Op->Header.Args[0], &Constant1) &&
IREmit->IsValueConstant(Op->Header.Args[1], &Constant2)) {
if (IsConstant1 && IsConstant2) {
uint64_t NewConstant = (Constant1 + Constant2) & getMask(Op) ;
IREmit->ReplaceWithConstant(CodeNode, NewConstant);
Changed = true;
}
else if (IsConstant2 && !IsImmAddSub(Constant2) && IsImmAddSub(-Constant2)) {
// If the second argument is constant, the immediate is not ImmAddSub, but when negated is.
// This means we can convert the operation in to a subtract.
// Change the IR operation itself.
IROp->Op = OP_SUB;
// Set the write cursor to just before this operation.
auto CodeIter = CurrentIR.at(CodeNode);
--CodeIter;
IREmit->SetWriteCursor(std::get<0>(*CodeIter));
// Negate the constant.
auto NegConstant = IREmit->_Constant(-Constant2);
// Replace the second source with the negated constant.
IREmit->ReplaceNodeArgument(CodeNode, Op->Src2_Index, NegConstant);
Changed = true;
}
break;
}
case OP_SUB: {
@@ -670,6 +687,21 @@ bool ConstProp::ConstantPropagation(IREmitter *IREmit, const IRListView& Current
}
break;
}
case OP_SUBSHIFT: {
auto Op = IROp->C<IR::IROp_SubShift>();
uint64_t Constant1, Constant2;
if (IREmit->IsValueConstant(IROp->Args[0], &Constant1) &&
IREmit->IsValueConstant(IROp->Args[1], &Constant2) &&
Op->Shift == IR::ShiftType::LSL) {
// Optimize the LSL case when we know both sources are constant.
// This is a pattern that shows up with direction flag calculations if DF was set just before the operation.
uint64_t NewConstant = (Constant1 - (Constant2 << Op->ShiftAmount)) & getMask(Op);
IREmit->ReplaceWithConstant(CodeNode, NewConstant);
Changed = true;
}
break;
}
case OP_AND: {
auto Op = IROp->CW<IR::IROp_And>();
uint64_t Constant1{};
+7
View File
@@ -564,6 +564,13 @@ enum class FloatCompareOp : uint8_t {
ORD,
};
enum class ShiftType : uint8_t {
LSL = 0,
LSR,
ASR,
ROR,
};
// Converts a size stored as an integer in to an OpSize enum.
// This is a nop operation and will be eliminated by the compiler.
static inline OpSize SizeToOpSize(uint8_t Size) {
@@ -59,6 +59,166 @@
"fadd s0, s16, s18",
"mov v16.s[0], v0.s[0]"
]
},
"positive movsb": {
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": [
"When direction flag is a compile time constant we can optimize",
"loads and stores can turn in to post-increment when known"
],
"x86Insts": [
"cld",
"movsb"
],
"ExpectedArm64ASM": [
"mov w20, #0x0",
"strb w20, [x28, #714]",
"ldrb w20, [x10]",
"strb w20, [x11]",
"add x10, x10, #0x1 (1)",
"add x11, x11, #0x1 (1)"
]
},
"positive movsw": {
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": [
"When direction flag is a compile time constant we can optimize",
"loads and stores can turn in to post-increment when known"
],
"x86Insts": [
"cld",
"movsw"
],
"ExpectedArm64ASM": [
"mov w20, #0x0",
"strb w20, [x28, #714]",
"ldrh w20, [x10]",
"strh w20, [x11]",
"add x10, x10, #0x2 (2)",
"add x11, x11, #0x2 (2)"
]
},
"positive movsd": {
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": [
"When direction flag is a compile time constant we can optimize",
"loads and stores can turn in to post-increment when known"
],
"x86Insts": [
"cld",
"movsd"
],
"ExpectedArm64ASM": [
"mov w20, #0x0",
"strb w20, [x28, #714]",
"ldr w20, [x10]",
"str w20, [x11]",
"add x10, x10, #0x4 (4)",
"add x11, x11, #0x4 (4)"
]
},
"positive movsq": {
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": [
"When direction flag is a compile time constant we can optimize",
"loads and stores can turn in to post-increment when known"
],
"x86Insts": [
"cld",
"movsq"
],
"ExpectedArm64ASM": [
"mov w20, #0x0",
"strb w20, [x28, #714]",
"ldr x20, [x10]",
"str x20, [x11]",
"add x10, x10, #0x8 (8)",
"add x11, x11, #0x8 (8)"
]
},
"negative movsb": {
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": [
"When direction flag is a compile time constant we can optimize",
"loads and stores can turn in to post-increment when known"
],
"x86Insts": [
"std",
"movsb"
],
"ExpectedArm64ASM": [
"mov w20, #0x1",
"strb w20, [x28, #714]",
"ldrb w20, [x10]",
"strb w20, [x11]",
"sub x10, x10, #0x1 (1)",
"sub x11, x11, #0x1 (1)"
]
},
"negative movsw": {
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": [
"When direction flag is a compile time constant we can optimize",
"loads and stores can turn in to post-increment when known"
],
"x86Insts": [
"std",
"movsw"
],
"ExpectedArm64ASM": [
"mov w20, #0x1",
"strb w20, [x28, #714]",
"ldrh w20, [x10]",
"strh w20, [x11]",
"sub x10, x10, #0x2 (2)",
"sub x11, x11, #0x2 (2)"
]
},
"negative movsd": {
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": [
"When direction flag is a compile time constant we can optimize",
"loads and stores can turn in to post-increment when known"
],
"x86Insts": [
"std",
"movsd"
],
"ExpectedArm64ASM": [
"mov w20, #0x1",
"strb w20, [x28, #714]",
"ldr w20, [x10]",
"str w20, [x11]",
"sub x10, x10, #0x4 (4)",
"sub x11, x11, #0x4 (4)"
]
},
"negative movsq": {
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": [
"When direction flag is a compile time constant we can optimize",
"loads and stores can turn in to post-increment when known"
],
"x86Insts": [
"std",
"movsq"
],
"ExpectedArm64ASM": [
"mov w20, #0x1",
"strb w20, [x28, #714]",
"ldr x20, [x10]",
"str x20, [x11]",
"sub x10, x10, #0x8 (8)",
"sub x11, x11, #0x8 (8)"
]
}
}
}
+133 -221
View File
@@ -321,7 +321,7 @@
"ExpectedArm64ASM": [
"mov x20, #0xffffffffffffffff",
"mov x21, x4",
"add x4, x21, x20",
"sub x4, x21, #0x1 (1)",
"eor x22, x21, x20",
"strb w22, [x28, #708]",
"strb w4, [x28, #706]",
@@ -3643,18 +3643,15 @@
]
},
"movsb": {
"ExpectedInstructionCount": 9,
"Optimal": "No",
"ExpectedInstructionCount": 7,
"Optimal": "Yes",
"Comment": [
"Direction flag increment/decrement location can be made with a single sbfx",
"0xa4"
],
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x1",
"mov x22, #0xffffffffffffffff",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #1",
"ldrb w21, [x10]",
"strb w21, [x11]",
"add x10, x10, x20",
@@ -3662,18 +3659,15 @@
]
},
"movsw": {
"ExpectedInstructionCount": 9,
"Optimal": "No",
"ExpectedInstructionCount": 7,
"Optimal": "Yes",
"Comment": [
"Direction flag increment/decrement location can be made with a tst+mov+csel triple",
"0xa5"
],
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x2",
"mov x22, #0xfffffffffffffffe",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #2",
"ldrh w21, [x10]",
"strh w21, [x11]",
"add x10, x10, x20",
@@ -3681,18 +3675,15 @@
]
},
"movsd": {
"ExpectedInstructionCount": 9,
"Optimal": "No",
"ExpectedInstructionCount": 7,
"Optimal": "Yes",
"Comment": [
"Direction flag increment/decrement location can be made with a tst+mov+csel triple",
"0xa5"
],
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x4",
"mov x22, #0xfffffffffffffffc",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #3",
"ldr w21, [x10]",
"str w21, [x11]",
"add x10, x10, x20",
@@ -3700,18 +3691,15 @@
]
},
"movsq": {
"ExpectedInstructionCount": 9,
"Optimal": "No",
"ExpectedInstructionCount": 7,
"Optimal": "Yes",
"Comment": [
"Direction flag increment/decrement location can be made with a tst+mov+csel triple",
"0xa5"
],
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x8",
"mov x22, #0xfffffffffffffff8",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #4",
"ldr x21, [x10]",
"str x21, [x11]",
"add x10, x10, x20",
@@ -3863,10 +3851,9 @@
]
},
"cmpsb": {
"ExpectedInstructionCount": 24,
"ExpectedInstructionCount": 22,
"Optimal": "No",
"Comment": [
"Direction flag increment/decrement location can be made with a single sbfx",
"0xa6"
],
"ExpectedArm64ASM": [
@@ -3875,9 +3862,7 @@
"sub w22, w21, w20",
"ldrb w23, [x28, #714]",
"mov w24, #0x1",
"mov x25, #0xffffffffffffffff",
"cmp x23, #0x0 (0)",
"csel x23, x24, x25, eq",
"sub x23, x24, x23, lsl #1",
"add x11, x11, x23",
"add x10, x10, x23",
"eor w23, w21, w20",
@@ -3897,10 +3882,9 @@
]
},
"cmpsw": {
"ExpectedInstructionCount": 24,
"ExpectedInstructionCount": 22,
"Optimal": "No",
"Comment": [
"Direction flag increment/decrement location can be made with a tst+mov+csel triple",
"0xa7"
],
"ExpectedArm64ASM": [
@@ -3909,9 +3893,7 @@
"sub w22, w21, w20",
"ldrb w23, [x28, #714]",
"mov w24, #0x2",
"mov x25, #0xfffffffffffffffe",
"cmp x23, #0x0 (0)",
"csel x23, x24, x25, eq",
"sub x23, x24, x23, lsl #2",
"add x11, x11, x23",
"add x10, x10, x23",
"eor w23, w21, w20",
@@ -3931,10 +3913,9 @@
]
},
"cmpsd": {
"ExpectedInstructionCount": 17,
"ExpectedInstructionCount": 15,
"Optimal": "No",
"Comment": [
"Direction flag increment/decrement location can be made with a tst+mov+csel triple",
"0xa7"
],
"ExpectedArm64ASM": [
@@ -3943,9 +3924,7 @@
"sub w22, w21, w20",
"ldrb w23, [x28, #714]",
"mov w24, #0x4",
"mov x25, #0xfffffffffffffffc",
"cmp x23, #0x0 (0)",
"csel x23, x24, x25, eq",
"sub x23, x24, x23, lsl #3",
"add x11, x11, x23",
"add x10, x10, x23",
"eor w23, w21, w20",
@@ -3958,10 +3937,9 @@
]
},
"cmpsq": {
"ExpectedInstructionCount": 17,
"ExpectedInstructionCount": 15,
"Optimal": "No",
"Comment": [
"Direction flag increment/decrement location can be made with a tst+mov+csel triple",
"0xa7"
],
"ExpectedArm64ASM": [
@@ -3970,9 +3948,7 @@
"sub x22, x21, x20",
"ldrb w23, [x28, #714]",
"mov w24, #0x8",
"mov x25, #0xfffffffffffffff8",
"cmp x23, #0x0 (0)",
"csel x23, x24, x25, eq",
"sub x23, x24, x23, lsl #4",
"add x11, x11, x23",
"add x10, x10, x23",
"eor x23, x21, x20",
@@ -3985,15 +3961,13 @@
]
},
"repz cmpsb": {
"ExpectedInstructionCount": 28,
"ExpectedInstructionCount": 26,
"Optimal": "No",
"Comment": "0xa6",
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x1",
"mov x22, #0xffffffffffffffff",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #1",
"cbz x5, #+0x5c",
"ldrb w21, [x11]",
"ldrb w22, [x10]",
@@ -4020,15 +3994,13 @@
]
},
"repz cmpsw": {
"ExpectedInstructionCount": 28,
"ExpectedInstructionCount": 26,
"Optimal": "No",
"Comment": "0xa7",
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x2",
"mov x22, #0xfffffffffffffffe",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #2",
"cbz x5, #+0x5c",
"ldrh w21, [x11]",
"ldrh w22, [x10]",
@@ -4055,15 +4027,13 @@
]
},
"repz cmpsd": {
"ExpectedInstructionCount": 21,
"ExpectedInstructionCount": 19,
"Optimal": "No",
"Comment": "0xa7",
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x4",
"mov x22, #0xfffffffffffffffc",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #3",
"cbz x5, #+0x40",
"ldr w21, [x11]",
"ldr w22, [x10]",
@@ -4083,15 +4053,13 @@
]
},
"repz cmpsq": {
"ExpectedInstructionCount": 21,
"ExpectedInstructionCount": 19,
"Optimal": "No",
"Comment": "0xa7",
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x8",
"mov x22, #0xfffffffffffffff8",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #4",
"cbz x5, #+0x40",
"ldr x21, [x11]",
"ldr x22, [x10]",
@@ -4111,15 +4079,13 @@
]
},
"repnz cmpsb": {
"ExpectedInstructionCount": 28,
"ExpectedInstructionCount": 26,
"Optimal": "No",
"Comment": "0xa6",
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x1",
"mov x22, #0xffffffffffffffff",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #1",
"cbz x5, #+0x5c",
"ldrb w21, [x11]",
"ldrb w22, [x10]",
@@ -4146,15 +4112,13 @@
]
},
"repnz cmpsw": {
"ExpectedInstructionCount": 28,
"ExpectedInstructionCount": 26,
"Optimal": "No",
"Comment": "0xa7",
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x2",
"mov x22, #0xfffffffffffffffe",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #2",
"cbz x5, #+0x5c",
"ldrh w21, [x11]",
"ldrh w22, [x10]",
@@ -4181,15 +4145,13 @@
]
},
"repnz cmpsd": {
"ExpectedInstructionCount": 21,
"ExpectedInstructionCount": 19,
"Optimal": "No",
"Comment": "0xa7",
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x4",
"mov x22, #0xfffffffffffffffc",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #3",
"cbz x5, #+0x40",
"ldr w21, [x11]",
"ldr w22, [x10]",
@@ -4209,15 +4171,13 @@
]
},
"repnz cmpsq": {
"ExpectedInstructionCount": 21,
"ExpectedInstructionCount": 19,
"Optimal": "No",
"Comment": "0xa7",
"ExpectedArm64ASM": [
"ldrb w20, [x28, #714]",
"mov w21, #0x8",
"mov x22, #0xfffffffffffffff8",
"cmp x20, #0x0 (0)",
"csel x20, x21, x22, eq",
"sub x20, x21, x20, lsl #4",
"cbz x5, #+0x40",
"ldr x21, [x11]",
"ldr x22, [x10]",
@@ -4340,61 +4300,53 @@
]
},
"stosb": {
"ExpectedInstructionCount": 8,
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": "0xaa",
"ExpectedArm64ASM": [
"uxtb w20, w4",
"strb w20, [x11]",
"mov w20, #0x1",
"mov x21, #0xffffffffffffffff",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x1",
"sub x20, x21, x20, lsl #1",
"add x11, x11, x20"
]
},
"stosw": {
"ExpectedInstructionCount": 8,
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": "0xab",
"ExpectedArm64ASM": [
"uxth w20, w4",
"strh w20, [x11]",
"mov w20, #0x2",
"mov x21, #0xfffffffffffffffe",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x2",
"sub x20, x21, x20, lsl #2",
"add x11, x11, x20"
]
},
"stosd": {
"ExpectedInstructionCount": 8,
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": "0xab",
"ExpectedArm64ASM": [
"mov w20, w4",
"str w20, [x11]",
"mov w20, #0x4",
"mov x21, #0xfffffffffffffffc",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x4",
"sub x20, x21, x20, lsl #3",
"add x11, x11, x20"
]
},
"stosq": {
"ExpectedInstructionCount": 7,
"ExpectedInstructionCount": 5,
"Optimal": "No",
"Comment": "0xab",
"ExpectedArm64ASM": [
"str x4, [x11]",
"mov w20, #0x8",
"mov x21, #0xfffffffffffffff8",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x8",
"sub x20, x21, x20, lsl #4",
"add x11, x11, x20"
]
},
@@ -4498,73 +4450,63 @@
]
},
"lodsb": {
"ExpectedInstructionCount": 8,
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": "0xac",
"ExpectedArm64ASM": [
"ldrb w20, [x10]",
"bfxil x4, x20, #0, #8",
"mov w20, #0x1",
"mov x21, #0xffffffffffffffff",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x1",
"sub x20, x21, x20, lsl #1",
"add x10, x10, x20"
]
},
"lodsw": {
"ExpectedInstructionCount": 8,
"ExpectedInstructionCount": 6,
"Optimal": "No",
"Comment": "0xad",
"ExpectedArm64ASM": [
"ldrh w20, [x10]",
"bfxil x4, x20, #0, #16",
"mov w20, #0x2",
"mov x21, #0xfffffffffffffffe",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x2",
"sub x20, x21, x20, lsl #2",
"add x10, x10, x20"
]
},
"lodsd": {
"ExpectedInstructionCount": 7,
"ExpectedInstructionCount": 5,
"Optimal": "No",
"Comment": "0xad",
"ExpectedArm64ASM": [
"ldr w4, [x10]",
"mov w20, #0x4",
"mov x21, #0xfffffffffffffffc",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x4",
"sub x20, x21, x20, lsl #3",
"add x10, x10, x20"
]
},
"lodsq": {
"ExpectedInstructionCount": 7,
"ExpectedInstructionCount": 5,
"Optimal": "No",
"Comment": "0xad",
"ExpectedArm64ASM": [
"ldr x4, [x10]",
"mov w20, #0x8",
"mov x21, #0xfffffffffffffff8",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x8",
"sub x20, x21, x20, lsl #4",
"add x10, x10, x20"
]
},
"rep lodsb": {
"ExpectedInstructionCount": 11,
"ExpectedInstructionCount": 9,
"Optimal": "No",
"Comment": "0xac",
"ExpectedArm64ASM": [
"mov w20, #0x1",
"mov x21, #0xffffffffffffffff",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x1",
"sub x20, x21, x20, lsl #1",
"cbz x5, #+0x18",
"ldrb w21, [x10]",
"bfxil x4, x21, #0, #8",
@@ -4574,15 +4516,13 @@
]
},
"rep lodsw": {
"ExpectedInstructionCount": 11,
"ExpectedInstructionCount": 9,
"Optimal": "No",
"Comment": "0xad",
"ExpectedArm64ASM": [
"mov w20, #0x2",
"mov x21, #0xfffffffffffffffe",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x2",
"sub x20, x21, x20, lsl #2",
"cbz x5, #+0x18",
"ldrh w21, [x10]",
"bfxil x4, x21, #0, #16",
@@ -4592,15 +4532,13 @@
]
},
"rep lodsd": {
"ExpectedInstructionCount": 10,
"ExpectedInstructionCount": 8,
"Optimal": "No",
"Comment": "0xad",
"ExpectedArm64ASM": [
"mov w20, #0x4",
"mov x21, #0xfffffffffffffffc",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x4",
"sub x20, x21, x20, lsl #3",
"cbz x5, #+0x14",
"ldr w4, [x10]",
"sub x5, x5, #0x1 (1)",
@@ -4609,15 +4547,13 @@
]
},
"rep lodsq": {
"ExpectedInstructionCount": 10,
"ExpectedInstructionCount": 8,
"Optimal": "No",
"Comment": "0xad",
"ExpectedArm64ASM": [
"mov w20, #0x8",
"mov x21, #0xfffffffffffffff8",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x8",
"sub x20, x21, x20, lsl #4",
"cbz x5, #+0x14",
"ldr x4, [x10]",
"sub x5, x5, #0x1 (1)",
@@ -4626,18 +4562,16 @@
]
},
"scasb": {
"ExpectedInstructionCount": 23,
"ExpectedInstructionCount": 21,
"Optimal": "No",
"Comment": "0xae",
"ExpectedArm64ASM": [
"uxtb w20, w4",
"ldrb w21, [x11]",
"sub w22, w20, w21",
"mov w23, #0x1",
"mov x24, #0xffffffffffffffff",
"ldrb w25, [x28, #714]",
"cmp x25, #0x0 (0)",
"csel x23, x23, x24, eq",
"ldrb w23, [x28, #714]",
"mov w24, #0x1",
"sub x23, x24, x23, lsl #1",
"add x11, x11, x23",
"eor w23, w20, w21",
"strb w23, [x28, #708]",
@@ -4656,18 +4590,16 @@
]
},
"scasw": {
"ExpectedInstructionCount": 23,
"ExpectedInstructionCount": 21,
"Optimal": "No",
"Comment": "0xaf",
"ExpectedArm64ASM": [
"uxth w20, w4",
"ldrh w21, [x11]",
"sub w22, w20, w21",
"mov w23, #0x2",
"mov x24, #0xfffffffffffffffe",
"ldrb w25, [x28, #714]",
"cmp x25, #0x0 (0)",
"csel x23, x23, x24, eq",
"ldrb w23, [x28, #714]",
"mov w24, #0x2",
"sub x23, x24, x23, lsl #2",
"add x11, x11, x23",
"eor w23, w20, w21",
"strb w23, [x28, #708]",
@@ -4686,18 +4618,16 @@
]
},
"scasd": {
"ExpectedInstructionCount": 16,
"ExpectedInstructionCount": 14,
"Optimal": "No",
"Comment": "0xaf",
"ExpectedArm64ASM": [
"mov w20, w4",
"ldr w21, [x11]",
"sub w22, w20, w21",
"mov w23, #0x4",
"mov x24, #0xfffffffffffffffc",
"ldrb w25, [x28, #714]",
"cmp x25, #0x0 (0)",
"csel x23, x23, x24, eq",
"ldrb w23, [x28, #714]",
"mov w24, #0x4",
"sub x23, x24, x23, lsl #3",
"add x11, x11, x23",
"eor w23, w20, w21",
"strb w23, [x28, #708]",
@@ -4709,17 +4639,15 @@
]
},
"scasq": {
"ExpectedInstructionCount": 15,
"ExpectedInstructionCount": 13,
"Optimal": "No",
"Comment": "0xaf",
"ExpectedArm64ASM": [
"ldr x20, [x11]",
"sub x21, x4, x20",
"mov w22, #0x8",
"mov x23, #0xfffffffffffffff8",
"ldrb w24, [x28, #714]",
"cmp x24, #0x0 (0)",
"csel x22, x22, x23, eq",
"ldrb w22, [x28, #714]",
"mov w23, #0x8",
"sub x22, x23, x22, lsl #4",
"add x11, x11, x22",
"eor x22, x4, x20",
"strb w22, [x28, #708]",
@@ -4731,15 +4659,13 @@
]
},
"repz scasb": {
"ExpectedInstructionCount": 27,
"ExpectedInstructionCount": 25,
"Optimal": "No",
"Comment": "0xae",
"ExpectedArm64ASM": [
"mov w20, #0x1",
"mov x21, #0xffffffffffffffff",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x1",
"sub x20, x21, x20, lsl #1",
"cbz x5, #+0x58",
"uxtb w21, w4",
"ldrb w22, [x11]",
@@ -4765,15 +4691,13 @@
]
},
"repz scasw": {
"ExpectedInstructionCount": 27,
"ExpectedInstructionCount": 25,
"Optimal": "No",
"Comment": "0xaf",
"ExpectedArm64ASM": [
"mov w20, #0x2",
"mov x21, #0xfffffffffffffffe",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x2",
"sub x20, x21, x20, lsl #2",
"cbz x5, #+0x58",
"uxth w21, w4",
"ldrh w22, [x11]",
@@ -4799,15 +4723,13 @@
]
},
"repz scasd": {
"ExpectedInstructionCount": 20,
"ExpectedInstructionCount": 18,
"Optimal": "No",
"Comment": "0xaf",
"ExpectedArm64ASM": [
"mov w20, #0x4",
"mov x21, #0xfffffffffffffffc",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x4",
"sub x20, x21, x20, lsl #3",
"cbz x5, #+0x3c",
"mov w21, w4",
"ldr w22, [x11]",
@@ -4826,15 +4748,13 @@
]
},
"repz scasq": {
"ExpectedInstructionCount": 19,
"ExpectedInstructionCount": 17,
"Optimal": "No",
"Comment": "0xaf",
"ExpectedArm64ASM": [
"mov w20, #0x8",
"mov x21, #0xfffffffffffffff8",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x8",
"sub x20, x21, x20, lsl #4",
"cbz x5, #+0x38",
"ldr x21, [x11]",
"sub x22, x4, x21",
@@ -4852,15 +4772,13 @@
]
},
"repnz scasb": {
"ExpectedInstructionCount": 27,
"ExpectedInstructionCount": 25,
"Optimal": "No",
"Comment": "0xae",
"ExpectedArm64ASM": [
"mov w20, #0x1",
"mov x21, #0xffffffffffffffff",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x1",
"sub x20, x21, x20, lsl #1",
"cbz x5, #+0x58",
"uxtb w21, w4",
"ldrb w22, [x11]",
@@ -4886,15 +4804,13 @@
]
},
"repnz scasw": {
"ExpectedInstructionCount": 27,
"ExpectedInstructionCount": 25,
"Optimal": "No",
"Comment": "0xaf",
"ExpectedArm64ASM": [
"mov w20, #0x2",
"mov x21, #0xfffffffffffffffe",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x2",
"sub x20, x21, x20, lsl #2",
"cbz x5, #+0x58",
"uxth w21, w4",
"ldrh w22, [x11]",
@@ -4920,15 +4836,13 @@
]
},
"repnz scasd": {
"ExpectedInstructionCount": 20,
"ExpectedInstructionCount": 18,
"Optimal": "No",
"Comment": "0xaf",
"ExpectedArm64ASM": [
"mov w20, #0x4",
"mov x21, #0xfffffffffffffffc",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x4",
"sub x20, x21, x20, lsl #3",
"cbz x5, #+0x3c",
"mov w21, w4",
"ldr w22, [x11]",
@@ -4947,15 +4861,13 @@
]
},
"repnz scasq": {
"ExpectedInstructionCount": 19,
"ExpectedInstructionCount": 17,
"Optimal": "No",
"Comment": "0xaf",
"ExpectedArm64ASM": [
"mov w20, #0x8",
"mov x21, #0xfffffffffffffff8",
"ldrb w22, [x28, #714]",
"cmp x22, #0x0 (0)",
"csel x20, x20, x21, eq",
"ldrb w20, [x28, #714]",
"mov w21, #0x8",
"sub x20, x21, x20, lsl #4",
"cbz x5, #+0x38",
"ldr x21, [x11]",
"sub x22, x4, x21",
@@ -653,7 +653,7 @@
"ExpectedArm64ASM": [
"mov x20, #0xffffffffffffff00",
"mov x21, x4",
"add x4, x21, x20",
"sub x4, x21, #0x100 (256)",
"strb w21, [x28, #708]",
"strb w4, [x28, #706]",
"cmn x21, x20",
@@ -1186,7 +1186,7 @@
"ExpectedArm64ASM": [
"mov x20, #0xffffffffffffffff",
"mov x21, x4",
"add x4, x21, x20",
"sub x4, x21, #0x1 (1)",
"eor x22, x21, x20",
"strb w22, [x28, #708]",
"strb w4, [x28, #706]",