From 728d3f8ac796278d355b9246feb8f57666fdeeac Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 26 Sep 2023 18:33:00 -0400 Subject: [PATCH 1/6] InstCountCI: Add a case with a hi 8-bit reg Noticeably different code pattern. Signed-off-by: Alyssa Rosenzweig --- unittests/InstructionCountCI/Primary.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/unittests/InstructionCountCI/Primary.json b/unittests/InstructionCountCI/Primary.json index 22257edc1..f7d776eba 100644 --- a/unittests/InstructionCountCI/Primary.json +++ b/unittests/InstructionCountCI/Primary.json @@ -330,6 +330,22 @@ "str w20, [x28, #728]" ] }, + "or bl, bh": { + "ExpectedInstructionCount": 9, + "Optimal": "No", + "Comment": "", + "ExpectedArm64ASM": [ + "ubfx w20, w7, #8, #8", + "uxtb w21, w7", + "orr w20, w21, w20", + "bfxil x7, x20, #0, #8", + "strb w20, [x28, #706]", + "lsl w20, w20, #24", + "tst w20, w20", + "mrs x20, nzcv", + "str w20, [x28, #728]" + ] + }, "or bl, cl": { "ExpectedInstructionCount": 9, "Optimal": "No", From 92211bf8c6c89dee114d96261a35b7dde55a71ee Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 26 Sep 2023 19:07:13 -0400 Subject: [PATCH 2/6] OpcodeDispatcher: Add AllowUpperGarbage option To load 8-bit sources without bfe'ing for al/bl/cl if the caller knows it doesn't need masking behaviour, but without lying about the size so the extract for ah/bh/ch will still work properly. Signed-off-by: Alyssa Rosenzweig --- FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp | 12 ++++++------ FEXCore/Source/Interface/Core/OpcodeDispatcher.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 14efbfbe8..32c673135 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -4990,7 +4990,7 @@ void OpDispatchBuilder::UpdatePrefixFromSegment(OrderedNode *Segment, uint32_t S } } -OrderedNode *OpDispatchBuilder::LoadSource_WithOpSize(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp const& Op, FEXCore::X86Tables::DecodedOperand const& Operand, uint8_t OpSize, uint32_t Flags, int8_t Align, bool LoadData, bool ForceLoad, MemoryAccessType AccessType) { +OrderedNode *OpDispatchBuilder::LoadSource_WithOpSize(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp const& Op, FEXCore::X86Tables::DecodedOperand const& Operand, uint8_t OpSize, uint32_t Flags, int8_t Align, bool LoadData, bool ForceLoad, MemoryAccessType AccessType, bool AllowUpperGarbage) { LOGMAN_THROW_A_FMT(Operand.IsGPR() || Operand.IsLiteral() || Operand.IsGPRDirect() || @@ -5035,7 +5035,7 @@ OrderedNode *OpDispatchBuilder::LoadSource_WithOpSize(FEXCore::IR::RegisterClass } } else { - Src = LoadGPRRegister(gpr, OpSize, highIndex ? 8 : 0); + Src = LoadGPRRegister(gpr, OpSize, highIndex ? 8 : 0, AllowUpperGarbage); } } else if (Operand.IsGPRDirect()) { @@ -5158,14 +5158,14 @@ OrderedNode *OpDispatchBuilder::GetRelocatedPC(FEXCore::X86Tables::DecodedOp con return _EntrypointOffset(IR::SizeToOpSize(GPRSize), Op->PC + Op->InstSize + Offset - Entry); } -OrderedNode *OpDispatchBuilder::LoadGPRRegister(uint32_t GPR, int8_t Size, uint8_t Offset) { +OrderedNode *OpDispatchBuilder::LoadGPRRegister(uint32_t GPR, int8_t Size, uint8_t Offset, bool AllowUpperGarbage) { const uint8_t GPRSize = CTX->GetGPRSize(); if (Size == -1) { Size = GPRSize; } OrderedNode *Reg = _LoadRegister(false, offsetof(FEXCore::Core::CPUState, gregs[GPR]), GPRClass, GPRFixedClass, GPRSize); - if (Size != GPRSize || Offset != 0) { + if ((!AllowUpperGarbage && (Size != GPRSize)) || Offset != 0) { // Extract the subregister if requested. Reg = _Bfe(IR::SizeToOpSize(std::max(4u, Size)), Size * 8, Offset, Reg); } @@ -5207,9 +5207,9 @@ void OpDispatchBuilder::StoreXMMRegister(uint32_t XMM, OrderedNode *const Src) { _StoreRegister(Src, false, VectorOffset, FPRClass, FPRFixedClass, VectorSize); } -OrderedNode *OpDispatchBuilder::LoadSource(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp const& Op, FEXCore::X86Tables::DecodedOperand const& Operand, uint32_t Flags, int8_t Align, bool LoadData, bool ForceLoad, MemoryAccessType AccessType) { +OrderedNode *OpDispatchBuilder::LoadSource(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp const& Op, FEXCore::X86Tables::DecodedOperand const& Operand, uint32_t Flags, int8_t Align, bool LoadData, bool ForceLoad, MemoryAccessType AccessType, bool AllowUpperGarbage) { const uint8_t OpSize = GetSrcSize(Op); - return LoadSource_WithOpSize(Class, Op, Operand, OpSize, Flags, Align, LoadData, ForceLoad, AccessType); + return LoadSource_WithOpSize(Class, Op, Operand, OpSize, Flags, Align, LoadData, ForceLoad, AccessType, AllowUpperGarbage); } void OpDispatchBuilder::StoreResult_WithOpSize(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp Op, FEXCore::X86Tables::DecodedOperand const& Operand, OrderedNode *const Src, uint8_t OpSize, int8_t Align, MemoryAccessType AccessType) { diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index aa37aa19e..72ef0b4b6 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -1055,14 +1055,14 @@ private: // Non-temporal streaming ACCESS_STREAM, }; - OrderedNode *LoadGPRRegister(uint32_t GPR, int8_t Size = -1, uint8_t Offset = 0); + OrderedNode *LoadGPRRegister(uint32_t GPR, int8_t Size = -1, uint8_t Offset = 0, bool AllowUpperGarbage = false); OrderedNode *LoadXMMRegister(uint32_t XMM); void StoreGPRRegister(uint32_t GPR, OrderedNode *const Src, int8_t Size = -1, uint8_t Offset = 0); void StoreXMMRegister(uint32_t XMM, OrderedNode *const Src); OrderedNode *GetRelocatedPC(FEXCore::X86Tables::DecodedOp const& Op, int64_t Offset = 0); - OrderedNode *LoadSource(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp const& Op, FEXCore::X86Tables::DecodedOperand const& Operand, uint32_t Flags, int8_t Align, bool LoadData = true, bool ForceLoad = false, MemoryAccessType AccessType = MemoryAccessType::ACCESS_DEFAULT); - OrderedNode *LoadSource_WithOpSize(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp const& Op, FEXCore::X86Tables::DecodedOperand const& Operand, uint8_t OpSize, uint32_t Flags, int8_t Align, bool LoadData = true, bool ForceLoad = false, MemoryAccessType AccessType = MemoryAccessType::ACCESS_DEFAULT); + OrderedNode *LoadSource(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp const& Op, FEXCore::X86Tables::DecodedOperand const& Operand, uint32_t Flags, int8_t Align, bool LoadData = true, bool ForceLoad = false, MemoryAccessType AccessType = MemoryAccessType::ACCESS_DEFAULT, bool AllowUpperGarbage = false); + OrderedNode *LoadSource_WithOpSize(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp const& Op, FEXCore::X86Tables::DecodedOperand const& Operand, uint8_t OpSize, uint32_t Flags, int8_t Align, bool LoadData = true, bool ForceLoad = false, MemoryAccessType AccessType = MemoryAccessType::ACCESS_DEFAULT, bool AllowUpperGarbage = false); void StoreResult_WithOpSize(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp Op, FEXCore::X86Tables::DecodedOperand const& Operand, OrderedNode *const Src, uint8_t OpSize, int8_t Align, MemoryAccessType AccessType = MemoryAccessType::ACCESS_DEFAULT); void StoreResult(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp Op, FEXCore::X86Tables::DecodedOperand const& Operand, OrderedNode *const Src, int8_t Align, MemoryAccessType AccessType = MemoryAccessType::ACCESS_DEFAULT); void StoreResult(FEXCore::IR::RegisterClassType Class, FEXCore::X86Tables::DecodedOp Op, OrderedNode *const Src, int8_t Align, MemoryAccessType AccessType = MemoryAccessType::ACCESS_DEFAULT); From 45a645fbbc9c8ec8cbeb5a695ac956675f718454 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 25 Sep 2023 19:29:04 -0400 Subject: [PATCH 3/6] OpcodeDispatcher: Don't mask logic op inputs Pointless, upper bits ignored anyway. Deletes piles of uxt and even some 32-bit instruction moves. Signed-off-by: Alyssa Rosenzweig --- FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 32c673135..916244db8 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5430,8 +5430,13 @@ void OpDispatchBuilder::ALUOpImpl(OpcodeArgs, FEXCore::IR::IROps ALUIROp, FEXCor auto Size = GetDstSize(Op); const auto OpSize = Size == 8 ? OpSize::i64Bit : OpSize::i32Bit; + // Logical ops can tolerate garbage in the upper bits, so don't mask. + bool AllowUpperGarbage = ALUIROp == FEXCore::IR::IROps::OP_AND || + ALUIROp == FEXCore::IR::IROps::OP_XOR || + ALUIROp == FEXCore::IR::IROps::OP_OR; + // X86 basic ALU ops just do the operation between the destination and a single source - OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1); + OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1, true, false, MemoryAccessType::ACCESS_DEFAULT, AllowUpperGarbage); OrderedNode *Result{}; OrderedNode *Dest{}; @@ -5453,7 +5458,7 @@ void OpDispatchBuilder::ALUOpImpl(OpcodeArgs, FEXCore::IR::IROps ALUIROp, FEXCor Result = ALUOp; } else { - Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1); + Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1, true, false, MemoryAccessType::ACCESS_DEFAULT, AllowUpperGarbage); /* On x86, the canonical way to zero a register is XOR with itself... * because modern x86 detects this pattern in hardware. arm64 does not From a4de1649444975ca555ea00aa2c424458c4ba094 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 26 Sep 2023 19:21:07 -0400 Subject: [PATCH 4/6] OpcodeDispatcher: Use lshr for ah/bh with AllowUpperGarbage If we ever get around to fusing ops with shifts in the ConstProp optimizer (may or may not be worthwhile), this will delete an instruction from things like "or al, bh". Even though lsr is the same speed as bfe on Firestorm, I feel if you ask for garbage you should get garbage C: Signed-off-by: Alyssa Rosenzweig --- FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 916244db8..b3c342111 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5167,7 +5167,11 @@ OrderedNode *OpDispatchBuilder::LoadGPRRegister(uint32_t GPR, int8_t Size, uint8 if ((!AllowUpperGarbage && (Size != GPRSize)) || Offset != 0) { // Extract the subregister if requested. - Reg = _Bfe(IR::SizeToOpSize(std::max(4u, Size)), Size * 8, Offset, Reg); + const auto OpSize = IR::SizeToOpSize(std::max(4u, Size)); + if (AllowUpperGarbage) + Reg = _Lshr(OpSize, Reg, _Constant(Offset)); + else + Reg = _Bfe(OpSize, Size * 8, Offset, Reg); } return Reg; } From 3bb64c64e33cd87bbccba5d793edfb20cc409970 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 26 Sep 2023 20:29:21 -0400 Subject: [PATCH 5/6] OpcodeDispatcher: Don't mask for TEST Like AND. Signed-off-by: Alyssa Rosenzweig --- FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index b3c342111..d8090b36b 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -1372,8 +1372,8 @@ template void OpDispatchBuilder::TESTOp(OpcodeArgs) { // TEST is an instruction that does an AND between the sources // Result isn't stored in result, only writes to flags - OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[SrcIndex], Op->Flags, -1); - OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1); + OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[SrcIndex], Op->Flags, -1, true, false, MemoryAccessType::ACCESS_DEFAULT, true); + OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1, true, false, MemoryAccessType::ACCESS_DEFAULT, true); auto Size = GetDstSize(Op); From 095a36204676bb274eef722fa39a5bc5a4b89066 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 26 Sep 2023 20:30:09 -0400 Subject: [PATCH 6/6] InstCountCI: Update Signed-off-by: Alyssa Rosenzweig --- unittests/InstructionCountCI/Primary.json | 193 +++++++----------- .../InstructionCountCI/PrimaryGroup.json | 85 +++----- 2 files changed, 103 insertions(+), 175 deletions(-) diff --git a/unittests/InstructionCountCI/Primary.json b/unittests/InstructionCountCI/Primary.json index f7d776eba..36fb2d80d 100644 --- a/unittests/InstructionCountCI/Primary.json +++ b/unittests/InstructionCountCI/Primary.json @@ -331,13 +331,12 @@ ] }, "or bl, bh": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 8, "Optimal": "No", "Comment": "", "ExpectedArm64ASM": [ - "ubfx w20, w7, #8, #8", - "uxtb w21, w7", - "orr w20, w21, w20", + "lsr w20, w7, #8", + "orr w20, w7, w20", "bfxil x7, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -347,13 +346,11 @@ ] }, "or bl, cl": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x08", "ExpectedArm64ASM": [ - "uxtb w20, w5", - "uxtb w21, w7", - "orr w20, w21, w20", + "orr w20, w7, w5", "bfxil x7, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -363,13 +360,11 @@ ] }, "or bx, cx": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x09", "ExpectedArm64ASM": [ - "uxth w20, w5", - "uxth w21, w7", - "orr w20, w21, w20", + "orr w20, w7, w5", "bfxil x7, x20, #0, #16", "strb w20, [x28, #706]", "lsl w20, w20, #16", @@ -379,13 +374,11 @@ ] }, "or ebx, ecx": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "0x09", "ExpectedArm64ASM": [ - "mov w20, w5", - "mov w21, w7", - "orr w7, w21, w20", + "orr w7, w7, w5", "strb w7, [x28, #706]", "tst w7, w7", "mrs x20, nzcv", @@ -405,16 +398,14 @@ ] }, "db 0x0A, 0xcb": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": [ "0x0A", "or bl, cl but modrm.rm as source" ], "ExpectedArm64ASM": [ - "uxtb w20, w7", - "uxtb w21, w5", - "orr w20, w21, w20", + "orr w20, w5, w7", "bfxil x5, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -424,16 +415,14 @@ ] }, "db 0x66, 0x0B, 0xcb": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": [ "0x0B", "or bx, cx but modrm.rm as source" ], "ExpectedArm64ASM": [ - "uxth w20, w7", - "uxth w21, w5", - "orr w20, w21, w20", + "orr w20, w5, w7", "bfxil x5, x20, #0, #16", "strb w20, [x28, #706]", "lsl w20, w20, #16", @@ -443,16 +432,14 @@ ] }, "db 0x0B, 0xcb": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": [ "0x0B", "or ebx, ecx but modrm.rm as source" ], "ExpectedArm64ASM": [ - "mov w20, w7", - "mov w21, w5", - "orr w5, w21, w20", + "orr w5, w5, w7", "strb w5, [x28, #706]", "tst w5, w5", "mrs x20, nzcv", @@ -475,12 +462,11 @@ ] }, "or al, 1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x0C", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "orr w20, w20, #0x1", + "orr w20, w4, #0x1", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -530,12 +516,11 @@ ] }, "or al, -1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x0C", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "orr w20, w20, #0xff", + "orr w20, w4, #0xff", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -1466,13 +1451,11 @@ ] }, "and bl, cl": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x20", "ExpectedArm64ASM": [ - "uxtb w20, w5", - "uxtb w21, w7", - "and w20, w21, w20", + "and w20, w7, w5", "bfxil x7, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -1482,13 +1465,11 @@ ] }, "and bx, cx": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x21", "ExpectedArm64ASM": [ - "uxth w20, w5", - "uxth w21, w7", - "and w20, w21, w20", + "and w20, w7, w5", "bfxil x7, x20, #0, #16", "strb w20, [x28, #706]", "lsl w20, w20, #16", @@ -1498,13 +1479,11 @@ ] }, "and ebx, ecx": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "0x21", "ExpectedArm64ASM": [ - "mov w20, w5", - "mov w21, w7", - "and w7, w21, w20", + "and w7, w7, w5", "strb w7, [x28, #706]", "tst w7, w7", "mrs x20, nzcv", @@ -1524,16 +1503,14 @@ ] }, "db 0x22, 0xcb": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": [ "0x22", "and bl, cl but modrm.rm as source" ], "ExpectedArm64ASM": [ - "uxtb w20, w7", - "uxtb w21, w5", - "and w20, w21, w20", + "and w20, w5, w7", "bfxil x5, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -1543,16 +1520,14 @@ ] }, "db 0x66, 0x23, 0xcb": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": [ "0x23", "and bx, cx but modrm.rm as source" ], "ExpectedArm64ASM": [ - "uxth w20, w7", - "uxth w21, w5", - "and w20, w21, w20", + "and w20, w5, w7", "bfxil x5, x20, #0, #16", "strb w20, [x28, #706]", "lsl w20, w20, #16", @@ -1562,16 +1537,14 @@ ] }, "db 0x23, 0xcb": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": [ "0x23", "and ebx, ecx but modrm.rm as source" ], "ExpectedArm64ASM": [ - "mov w20, w7", - "mov w21, w5", - "and w5, w21, w20", + "and w5, w5, w7", "strb w5, [x28, #706]", "tst w5, w5", "mrs x20, nzcv", @@ -1594,12 +1567,11 @@ ] }, "and al, 1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x24", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "and w20, w20, #0x1", + "and w20, w4, #0x1", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -1649,12 +1621,11 @@ ] }, "and al, -1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x24", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "and w20, w20, #0xff", + "and w20, w4, #0xff", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -2037,13 +2008,11 @@ ] }, "xor bl, cl": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x30", "ExpectedArm64ASM": [ - "uxtb w20, w5", - "uxtb w21, w7", - "eor w20, w21, w20", + "eor w20, w7, w5", "bfxil x7, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -2053,13 +2022,11 @@ ] }, "xor bx, cx": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x31", "ExpectedArm64ASM": [ - "uxth w20, w5", - "uxth w21, w7", - "eor w20, w21, w20", + "eor w20, w7, w5", "bfxil x7, x20, #0, #16", "strb w20, [x28, #706]", "lsl w20, w20, #16", @@ -2069,13 +2036,11 @@ ] }, "xor ebx, ecx": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "0x31", "ExpectedArm64ASM": [ - "mov w20, w5", - "mov w21, w7", - "eor w7, w21, w20", + "eor w7, w7, w5", "strb w7, [x28, #706]", "tst w7, w7", "mrs x20, nzcv", @@ -2095,16 +2060,14 @@ ] }, "db 0x32, 0xcb": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": [ "0x32", "xor bl, cl but modrm.rm as source" ], "ExpectedArm64ASM": [ - "uxtb w20, w7", - "uxtb w21, w5", - "eor w20, w21, w20", + "eor w20, w5, w7", "bfxil x5, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -2114,16 +2077,14 @@ ] }, "db 0x66, 0x33, 0xcb": { - "ExpectedInstructionCount": 9, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": [ "0x33", "xor bx, cx but modrm.rm as source" ], "ExpectedArm64ASM": [ - "uxth w20, w7", - "uxth w21, w5", - "eor w20, w21, w20", + "eor w20, w5, w7", "bfxil x5, x20, #0, #16", "strb w20, [x28, #706]", "lsl w20, w20, #16", @@ -2133,16 +2094,14 @@ ] }, "db 0x33, 0xcb": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": [ "0x33", "xor ebx, ecx but modrm.rm as source" ], "ExpectedArm64ASM": [ - "mov w20, w7", - "mov w21, w5", - "eor w5, w21, w20", + "eor w5, w5, w7", "strb w5, [x28, #706]", "tst w5, w5", "mrs x20, nzcv", @@ -2165,12 +2124,11 @@ ] }, "xor al, 1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x34", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "eor w20, w20, #0x1", + "eor w20, w4, #0x1", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -2244,12 +2202,11 @@ ] }, "xor al, -1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0x34", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "eor w20, w20, #0xff", + "eor w20, w4, #0xff", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -2794,13 +2751,11 @@ ] }, "test al, bl": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 6, "Optimal": "No", "Comment": "0x84", "ExpectedArm64ASM": [ - "uxtb w20, w7", - "uxtb w21, w4", - "and w20, w21, w20", + "and w20, w4, w7", "strb w20, [x28, #706]", "lsl w20, w20, #24", "tst w20, w20", @@ -2809,13 +2764,11 @@ ] }, "test ax, bx": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 6, "Optimal": "No", "Comment": "0x84", "ExpectedArm64ASM": [ - "uxth w20, w7", - "uxth w21, w4", - "and w20, w21, w20", + "and w20, w4, w7", "strb w20, [x28, #706]", "lsl w20, w20, #16", "tst w20, w20", @@ -2824,13 +2777,11 @@ ] }, "test eax, ebx": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "0x84", "ExpectedArm64ASM": [ - "mov w20, w7", - "mov w21, w4", - "and w20, w21, w20", + "and w20, w4, w7", "strb w20, [x28, #706]", "tst w20, w20", "mrs x20, nzcv", @@ -4287,12 +4238,11 @@ ] }, "test al, 1": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Optimal": "No", "Comment": "0xa8", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "and w20, w20, #0x1", + "and w20, w4, #0x1", "strb w20, [x28, #706]", "lsl w20, w20, #24", "tst w20, w20", @@ -4301,12 +4251,11 @@ ] }, "test ax, 1": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Optimal": "No", "Comment": "0xa9", "ExpectedArm64ASM": [ - "uxth w20, w4", - "and w20, w20, #0x1", + "and w20, w4, #0x1", "strb w20, [x28, #706]", "lsl w20, w20, #16", "tst w20, w20", @@ -4315,12 +4264,11 @@ ] }, "test eax, 1": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "0xa9", "ExpectedArm64ASM": [ - "mov w20, w4", - "and w20, w20, #0x1", + "and w20, w4, #0x1", "strb w20, [x28, #706]", "tst w20, w20", "mrs x20, nzcv", @@ -4340,12 +4288,11 @@ ] }, "test al, -1": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Optimal": "No", "Comment": "0xa8", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "and w20, w20, #0xff", + "and w20, w4, #0xff", "strb w20, [x28, #706]", "lsl w20, w20, #24", "tst w20, w20", @@ -4354,12 +4301,11 @@ ] }, "test ax, -1": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Optimal": "No", "Comment": "0xa9", "ExpectedArm64ASM": [ - "uxth w20, w4", - "and w20, w20, #0xffff", + "and w20, w4, #0xffff", "strb w20, [x28, #706]", "lsl w20, w20, #16", "tst w20, w20", @@ -4368,14 +4314,13 @@ ] }, "test eax, -1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "0xa9", "ExpectedArm64ASM": [ "mov w20, #0xffff", "movk w20, #0xffff, lsl #16", - "mov w21, w4", - "and w20, w21, w20", + "and w20, w4, w20", "strb w20, [x28, #706]", "tst w20, w20", "mrs x20, nzcv", diff --git a/unittests/InstructionCountCI/PrimaryGroup.json b/unittests/InstructionCountCI/PrimaryGroup.json index bc887a7e3..0bb417746 100644 --- a/unittests/InstructionCountCI/PrimaryGroup.json +++ b/unittests/InstructionCountCI/PrimaryGroup.json @@ -34,12 +34,11 @@ ] }, "or al, 1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "GROUP1 0x80 /1", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "orr w20, w20, #0x1", + "orr w20, w4, #0x1", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -111,12 +110,11 @@ ] }, "and al, 1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "GROUP1 0x80 /4", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "and w20, w20, #0x1", + "and w20, w4, #0x1", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -147,12 +145,11 @@ ] }, "xor al, 1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "GROUP1 0x80 /6", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "eor w20, w20, #0x1", + "eor w20, w4, #0x1", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -204,12 +201,11 @@ ] }, "or al, -1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "GROUP1 0x80 /1", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "orr w20, w20, #0xff", + "orr w20, w4, #0xff", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -283,12 +279,11 @@ ] }, "and al, -1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "GROUP1 0x80 /4", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "and w20, w20, #0xff", + "and w20, w4, #0xff", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -320,12 +315,11 @@ ] }, "xor al, -1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "GROUP1 0x80 /6", "ExpectedArm64ASM": [ - "uxtb w20, w4", - "eor w20, w20, #0xff", + "eor w20, w4, #0xff", "bfxil x4, x20, #0, #8", "strb w20, [x28, #706]", "lsl w20, w20, #24", @@ -405,12 +399,11 @@ ] }, "or eax, 256": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "GROUP1 0x81 /1", "ExpectedArm64ASM": [ - "mov w20, w4", - "orr w4, w20, #0x100", + "orr w4, w4, #0x100", "strb w4, [x28, #706]", "tst w4, w4", "mrs x20, nzcv", @@ -510,12 +503,11 @@ ] }, "and eax, 256": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "GROUP1 0x81 /4", "ExpectedArm64ASM": [ - "mov w20, w4", - "and w4, w20, #0x100", + "and w4, w4, #0x100", "strb w4, [x28, #706]", "tst w4, w4", "mrs x20, nzcv", @@ -565,12 +557,11 @@ ] }, "xor eax, 256": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "GROUP1 0x81 /6", "ExpectedArm64ASM": [ - "mov w20, w4", - "eor w4, w20, #0x100", + "eor w4, w4, #0x100", "strb w4, [x28, #706]", "tst w4, w4", "mrs x20, nzcv", @@ -671,12 +662,11 @@ ] }, "or eax, -256": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "GROUP1 0x81 /1", "ExpectedArm64ASM": [ - "mov w20, w4", - "orr w4, w20, #0xffffff00", + "orr w4, w4, #0xffffff00", "strb w4, [x28, #706]", "tst w4, w4", "mrs x20, nzcv", @@ -776,12 +766,11 @@ ] }, "and eax, -256": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "GROUP1 0x81 /4", "ExpectedArm64ASM": [ - "mov w20, w4", - "and w4, w20, #0xffffff00", + "and w4, w4, #0xffffff00", "strb w4, [x28, #706]", "tst w4, w4", "mrs x20, nzcv", @@ -833,12 +822,11 @@ ] }, "xor eax, -256": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "GROUP1 0x81 /6", "ExpectedArm64ASM": [ - "mov w20, w4", - "eor w4, w20, #0xffffff00", + "eor w4, w4, #0xffffff00", "strb w4, [x28, #706]", "tst w4, w4", "mrs x20, nzcv", @@ -3378,12 +3366,11 @@ ] }, "test bl, 1": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Optimal": "No", "Comment": "GROUP2 0xf6 /0", "ExpectedArm64ASM": [ - "uxtb w20, w7", - "and w20, w20, #0x1", + "and w20, w7, #0x1", "strb w20, [x28, #706]", "lsl w20, w20, #24", "tst w20, w20", @@ -3497,12 +3484,11 @@ ] }, "test bx, 1": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Optimal": "No", "Comment": "GROUP2 0xf7 /0", "ExpectedArm64ASM": [ - "uxth w20, w7", - "and w20, w20, #0x1", + "and w20, w7, #0x1", "strb w20, [x28, #706]", "lsl w20, w20, #16", "tst w20, w20", @@ -3511,12 +3497,11 @@ ] }, "test ebx, 1": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": "GROUP2 0xf7 /0", "ExpectedArm64ASM": [ - "mov w20, w7", - "and w20, w20, #0x1", + "and w20, w7, #0x1", "strb w20, [x28, #706]", "tst w20, w20", "mrs x20, nzcv", @@ -3536,12 +3521,11 @@ ] }, "test bx, -1": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Optimal": "No", "Comment": "GROUP2 0xf7 /0", "ExpectedArm64ASM": [ - "uxth w20, w7", - "and w20, w20, #0xffff", + "and w20, w7, #0xffff", "strb w20, [x28, #706]", "lsl w20, w20, #16", "tst w20, w20", @@ -3550,14 +3534,13 @@ ] }, "test ebx, -1": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 7, "Optimal": "No", "Comment": "GROUP2 0xf7 /0", "ExpectedArm64ASM": [ "mov w20, #0xffff", "movk w20, #0xffff, lsl #16", - "mov w21, w7", - "and w20, w21, w20", + "and w20, w7, w20", "strb w20, [x28, #706]", "tst w20, w20", "mrs x20, nzcv",