From df903ac5d1894a41ddefde98d701828fad60a409 Mon Sep 17 00:00:00 2001 From: Rodrigo Rocha Date: Fri, 25 Apr 2025 23:51:12 +0100 Subject: [PATCH 1/5] Optimize the code generation of createLoadImmediate for AArch64. --- .../Target/AArch64/AArch64MCPlusBuilder.cpp | 28 +++++-- bolt/unittests/Core/MCPlusBuilder.cpp | 84 +++++++++++++++++++ 2 files changed, 104 insertions(+), 8 deletions(-) diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp index e00d6a18b0f6c..0aa9504f50a15 100644 --- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -2173,14 +2173,26 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { InstructionListType createLoadImmediate(const MCPhysReg Dest, uint64_t Imm) const override { - InstructionListType Insts(4); - int Shift = 48; - for (int I = 0; I < 4; I++, Shift -= 16) { - Insts[I].setOpcode(AArch64::MOVKXi); - Insts[I].addOperand(MCOperand::createReg(Dest)); - Insts[I].addOperand(MCOperand::createReg(Dest)); - Insts[I].addOperand(MCOperand::createImm((Imm >> Shift) & 0xFFFF)); - Insts[I].addOperand(MCOperand::createImm(Shift)); + InstructionListType Insts; + for (int I = 0, Shift = 0; I < 4; I++, Shift += 16) { + uint16_t HalfWord = (Imm >> Shift) & 0xFFFF; + if (!HalfWord) + continue; + MCInst Inst; + if (Insts.size() == 0) { + Inst.setOpcode(AArch64::MOVZXi); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createImm(HalfWord)); + Inst.addOperand(MCOperand::createImm(Shift)); + Insts.push_back(Inst); + } else { + Inst.setOpcode(AArch64::MOVKXi); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createImm(HalfWord)); + Inst.addOperand(MCOperand::createImm(Shift)); + Insts.push_back(Inst); + } } return Insts; } diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp index 7016dec0e3574..ac0529cb09a7b 100644 --- a/bolt/unittests/Core/MCPlusBuilder.cpp +++ b/bolt/unittests/Core/MCPlusBuilder.cpp @@ -167,6 +167,90 @@ TEST_P(MCPlusBuilderTester, AArch64_CmpJNE) { ASSERT_EQ(Label, BB->getLabel()); } +TEST_P(MCPlusBuilderTester, AArch64_LoadImm32) { + if (GetParam() != Triple::aarch64) + GTEST_SKIP(); + BinaryFunction *BF = BC->createInjectedBinaryFunction("BF", true); + std::unique_ptr BB = BF->createBasicBlock(); + + InstructionListType Instrs = BC->MIB->createLoadImmediate(AArch64::X0, 2); + BB->addInstructions(Instrs.begin(), Instrs.end()); + + ASSERT_EQ(BB->size(), 1); + auto II = BB->begin(); + // mov x0, #2 + ASSERT_EQ(II->getOpcode(), AArch64::MOVZXi); + ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(1).getImm(), 2); + ASSERT_EQ(II->getOperand(2).getImm(), 0); +} + +TEST_P(MCPlusBuilderTester, AArch64_LoadImm64) { + if (GetParam() != Triple::aarch64) + GTEST_SKIP(); + BinaryFunction *BF = BC->createInjectedBinaryFunction("BF", true); + std::unique_ptr BB = BF->createBasicBlock(); + + int64_t Imm = ((uint64_t)4) << 48 | ((uint64_t)3) << 32 | 2 << 16 | 1; + InstructionListType Instrs = BC->MIB->createLoadImmediate(AArch64::X0, Imm); + BB->addInstructions(Instrs.begin(), Instrs.end()); + + ASSERT_EQ(BB->size(), 4); + auto II = BB->begin(); + // mov x0, #1 + ASSERT_EQ(II->getOpcode(), AArch64::MOVZXi); + ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(1).getImm(), 1); + ASSERT_EQ(II->getOperand(2).getImm(), 0); + II++; + // movk x0, #2, lsl #16 + ASSERT_EQ(II->getOpcode(), AArch64::MOVKXi); + ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(1).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(2).getImm(), 2); + ASSERT_EQ(II->getOperand(3).getImm(), 16); + II++; + // movk x0, #3, lsl #32 + ASSERT_EQ(II->getOpcode(), AArch64::MOVKXi); + ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(1).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(2).getImm(), 3); + ASSERT_EQ(II->getOperand(3).getImm(), 32); + II++; + // movk x0, #4, lsl #48 + ASSERT_EQ(II->getOpcode(), AArch64::MOVKXi); + ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(1).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(2).getImm(), 4); + ASSERT_EQ(II->getOperand(3).getImm(), 48); +} + +TEST_P(MCPlusBuilderTester, AArch64_LoadImm64Partial) { + if (GetParam() != Triple::aarch64) + GTEST_SKIP(); + BinaryFunction *BF = BC->createInjectedBinaryFunction("BF", true); + std::unique_ptr BB = BF->createBasicBlock(); + + int64_t Imm = ((uint64_t)4) << 48 | 2 << 16; + InstructionListType Instrs = BC->MIB->createLoadImmediate(AArch64::X0, Imm); + BB->addInstructions(Instrs.begin(), Instrs.end()); + + ASSERT_EQ(BB->size(), 2); + auto II = BB->begin(); + // mov x0, #2, lsl #16 + ASSERT_EQ(II->getOpcode(), AArch64::MOVZXi); + ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(1).getImm(), 2); + ASSERT_EQ(II->getOperand(2).getImm(), 16); + II++; + // movk x0, #4, lsl #48 + ASSERT_EQ(II->getOpcode(), AArch64::MOVKXi); + ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(1).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(2).getImm(), 4); + ASSERT_EQ(II->getOperand(3).getImm(), 48); +} + TEST_P(MCPlusBuilderTester, testAccessedRegsImplicitDef) { if (GetParam() != Triple::aarch64) GTEST_SKIP(); From 3721648acb6e549265945124653641b773c5848b Mon Sep 17 00:00:00 2001 From: Rodrigo Rocha Date: Mon, 28 Apr 2025 21:10:47 +0100 Subject: [PATCH 2/5] [BOLT] Fixed createLoadImmediate when Imm=0 --- .../Target/AArch64/AArch64MCPlusBuilder.cpp | 44 ++++++++++++------- bolt/unittests/Core/MCPlusBuilder.cpp | 21 ++++++++- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp index 0aa9504f50a15..1ac6001d428cc 100644 --- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -2174,24 +2174,34 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { InstructionListType createLoadImmediate(const MCPhysReg Dest, uint64_t Imm) const override { InstructionListType Insts; - for (int I = 0, Shift = 0; I < 4; I++, Shift += 16) { - uint16_t HalfWord = (Imm >> Shift) & 0xFFFF; - if (!HalfWord) - continue; + if (Imm == 0) { MCInst Inst; - if (Insts.size() == 0) { - Inst.setOpcode(AArch64::MOVZXi); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createImm(HalfWord)); - Inst.addOperand(MCOperand::createImm(Shift)); - Insts.push_back(Inst); - } else { - Inst.setOpcode(AArch64::MOVKXi); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createImm(HalfWord)); - Inst.addOperand(MCOperand::createImm(Shift)); - Insts.push_back(Inst); + Inst.setOpcode(AArch64::ORRXrs); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createReg(AArch64::XZR)); + Inst.addOperand(MCOperand::createReg(AArch64::XZR)); + Inst.addOperand(MCOperand::createImm(0)); + Insts.push_back(Inst); + } else { + for (int I = 0, Shift = 0; I < 4; I++, Shift += 16) { + uint16_t HalfWord = (Imm >> Shift) & 0xFFFF; + if (!HalfWord) + continue; + MCInst Inst; + if (Insts.size() == 0) { + Inst.setOpcode(AArch64::MOVZXi); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createImm(HalfWord)); + Inst.addOperand(MCOperand::createImm(Shift)); + Insts.push_back(Inst); + } else { + Inst.setOpcode(AArch64::MOVKXi); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createImm(HalfWord)); + Inst.addOperand(MCOperand::createImm(Shift)); + Insts.push_back(Inst); + } } } return Insts; diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp index ac0529cb09a7b..326d484f0a39e 100644 --- a/bolt/unittests/Core/MCPlusBuilder.cpp +++ b/bolt/unittests/Core/MCPlusBuilder.cpp @@ -167,7 +167,26 @@ TEST_P(MCPlusBuilderTester, AArch64_CmpJNE) { ASSERT_EQ(Label, BB->getLabel()); } -TEST_P(MCPlusBuilderTester, AArch64_LoadImm32) { +TEST_P(MCPlusBuilderTester, AArch64_LoadZero) { + if (GetParam() != Triple::aarch64) + GTEST_SKIP(); + BinaryFunction *BF = BC->createInjectedBinaryFunction("BF", true); + std::unique_ptr BB = BF->createBasicBlock(); + + InstructionListType Instrs = BC->MIB->createLoadImmediate(AArch64::X0, 0); + BB->addInstructions(Instrs.begin(), Instrs.end()); + + ASSERT_EQ(BB->size(), 1); + auto II = BB->begin(); + // mov x0, xzr <=> orr x0, xzr, xzr, lsl #0 + ASSERT_EQ(II->getOpcode(), AArch64::ORRXrs); + ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X0); + ASSERT_EQ(II->getOperand(1).getReg(), AArch64::XZR); + ASSERT_EQ(II->getOperand(2).getReg(), AArch64::XZR); + ASSERT_EQ(II->getOperand(3).getImm(), 0); +} + +TEST_P(MCPlusBuilderTester, AArch64_LoadImm16) { if (GetParam() != Triple::aarch64) GTEST_SKIP(); BinaryFunction *BF = BC->createInjectedBinaryFunction("BF", true); From 08330cf710887b981bd131b3e1f3851cb8ecd549 Mon Sep 17 00:00:00 2001 From: Rodrigo Rocha Date: Thu, 15 May 2025 14:35:42 +0100 Subject: [PATCH 3/5] Modify createLoadImmediate to use AArch64_IMM::expandMOVImm --- .../Target/AArch64/AArch64MCPlusBuilder.cpp | 93 +++++++++++++++---- bolt/unittests/Core/MCPlusBuilder.cpp | 28 +++--- 2 files changed, 88 insertions(+), 33 deletions(-) diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp index 1ac6001d428cc..f2a4162ef6c2f 100644 --- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "AArch64ExpandImm.h" #include "AArch64InstrInfo.h" #include "AArch64MCSymbolizer.h" #include "MCTargetDesc/AArch64AddressingModes.h" @@ -2173,35 +2174,87 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { InstructionListType createLoadImmediate(const MCPhysReg Dest, uint64_t Imm) const override { + const MCRegisterClass RC = RegInfo->getRegClass(Dest); + unsigned BitSize = RC.getSizeInBits(); InstructionListType Insts; - if (Imm == 0) { - MCInst Inst; - Inst.setOpcode(AArch64::ORRXrs); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createReg(AArch64::XZR)); - Inst.addOperand(MCOperand::createReg(AArch64::XZR)); - Inst.addOperand(MCOperand::createImm(0)); - Insts.push_back(Inst); - } else { - for (int I = 0, Shift = 0; I < 4; I++, Shift += 16) { - uint16_t HalfWord = (Imm >> Shift) & 0xFFFF; - if (!HalfWord) - continue; + SmallVector IIMs; + AArch64_IMM::expandMOVImm(Imm, BitSize, IIMs); + assert(IIMs.size() != 0); + for (auto I = IIMs.begin(), E = IIMs.end(); I != E; ++I) { + switch (I->Opcode) { + default: + llvm_unreachable("unhandled!"); + break; + + case AArch64::ORRWri: + case AArch64::ORRXri: + if (I->Op1 == 0) { + MCInst Inst; + Inst.setOpcode(I->Opcode); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createReg(BitSize == 32 ? AArch64::WZR + : AArch64::XZR)); + Inst.addOperand(MCOperand::createImm(I->Op2)); + Insts.push_back(Inst); + } else { + MCInst Inst; + Inst.setOpcode(I->Opcode); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createImm(I->Op2)); + Insts.push_back(Inst); + } + break; + case AArch64::ORRWrs: + case AArch64::ORRXrs: { MCInst Inst; - if (Insts.size() == 0) { - Inst.setOpcode(AArch64::MOVZXi); + Inst.setOpcode(I->Opcode); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createImm(I->Op2)); + Insts.push_back(Inst); + } break; + case AArch64::ANDXri: + case AArch64::EORXri: + if (I->Op1 == 0) { + MCInst Inst; + Inst.setOpcode(I->Opcode); Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createImm(HalfWord)); - Inst.addOperand(MCOperand::createImm(Shift)); + Inst.addOperand(MCOperand::createReg(BitSize == 32 ? AArch64::WZR + : AArch64::XZR)); + Inst.addOperand(MCOperand::createImm(I->Op2)); Insts.push_back(Inst); } else { - Inst.setOpcode(AArch64::MOVKXi); + MCInst Inst; + Inst.setOpcode(I->Opcode); Inst.addOperand(MCOperand::createReg(Dest)); Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createImm(HalfWord)); - Inst.addOperand(MCOperand::createImm(Shift)); + Inst.addOperand(MCOperand::createImm(I->Op2)); Insts.push_back(Inst); } + break; + case AArch64::MOVNWi: + case AArch64::MOVNXi: + case AArch64::MOVZWi: + case AArch64::MOVZXi: { + MCInst Inst; + Inst.setOpcode(I->Opcode); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createImm(I->Op1)); + Inst.addOperand(MCOperand::createImm(I->Op2)); + Insts.push_back(Inst); + } break; + case AArch64::MOVKWi: + case AArch64::MOVKXi: { + MCInst Inst; + Inst.setOpcode(I->Opcode); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createReg(Dest)); + Inst.addOperand(MCOperand::createImm(I->Op1)); + Inst.addOperand(MCOperand::createImm(I->Op2)); + Insts.push_back(Inst); + } break; } } return Insts; diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp index 326d484f0a39e..0a39e2860506f 100644 --- a/bolt/unittests/Core/MCPlusBuilder.cpp +++ b/bolt/unittests/Core/MCPlusBuilder.cpp @@ -9,6 +9,8 @@ #ifdef AARCH64_AVAILABLE #include "AArch64Subtarget.h" #include "MCTargetDesc/AArch64MCTargetDesc.h" +#include "AArch64.h" +#include "MCTargetDesc/AArch64AddressingModes.h" #endif // AARCH64_AVAILABLE #ifdef X86_AVAILABLE @@ -178,12 +180,11 @@ TEST_P(MCPlusBuilderTester, AArch64_LoadZero) { ASSERT_EQ(BB->size(), 1); auto II = BB->begin(); - // mov x0, xzr <=> orr x0, xzr, xzr, lsl #0 - ASSERT_EQ(II->getOpcode(), AArch64::ORRXrs); + // mov x0, #0 + ASSERT_EQ(II->getOpcode(), AArch64::MOVZXi); ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X0); - ASSERT_EQ(II->getOperand(1).getReg(), AArch64::XZR); - ASSERT_EQ(II->getOperand(2).getReg(), AArch64::XZR); - ASSERT_EQ(II->getOperand(3).getImm(), 0); + ASSERT_EQ(II->getOperand(1).getImm(), 0); + ASSERT_EQ(II->getOperand(2).getImm(), 0); } TEST_P(MCPlusBuilderTester, AArch64_LoadImm16) { @@ -256,18 +257,19 @@ TEST_P(MCPlusBuilderTester, AArch64_LoadImm64Partial) { ASSERT_EQ(BB->size(), 2); auto II = BB->begin(); - // mov x0, #2, lsl #16 - ASSERT_EQ(II->getOpcode(), AArch64::MOVZXi); + // orr x0, xzr, #0x20000 + ASSERT_EQ(II->getOpcode(), AArch64::ORRXri); ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X0); - ASSERT_EQ(II->getOperand(1).getImm(), 2); - ASSERT_EQ(II->getOperand(2).getImm(), 16); + ASSERT_EQ(II->getOperand(1).getReg(), AArch64::XZR); + ASSERT_EQ(II->getOperand(2).getImm(), + AArch64_AM::encodeLogicalImmediate(2 << 16, 64)); II++; - // movk x0, #4, lsl #48 - ASSERT_EQ(II->getOpcode(), AArch64::MOVKXi); + // orr x0, x0, #0x4000000000000 + ASSERT_EQ(II->getOpcode(), AArch64::ORRXri); ASSERT_EQ(II->getOperand(0).getReg(), AArch64::X0); ASSERT_EQ(II->getOperand(1).getReg(), AArch64::X0); - ASSERT_EQ(II->getOperand(2).getImm(), 4); - ASSERT_EQ(II->getOperand(3).getImm(), 48); + ASSERT_EQ(II->getOperand(2).getImm(), + AArch64_AM::encodeLogicalImmediate(((uint64_t)4) << 48, 64)); } TEST_P(MCPlusBuilderTester, testAccessedRegsImplicitDef) { From d9b6bf1bf1b3b26d03b95522fb56b646e0a95fb1 Mon Sep 17 00:00:00 2001 From: Rodrigo Rocha Date: Thu, 15 May 2025 14:45:17 +0100 Subject: [PATCH 4/5] Fixed code format --- bolt/unittests/Core/MCPlusBuilder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp index 0a39e2860506f..d44ba8061f80f 100644 --- a/bolt/unittests/Core/MCPlusBuilder.cpp +++ b/bolt/unittests/Core/MCPlusBuilder.cpp @@ -7,10 +7,10 @@ //===----------------------------------------------------------------------===// #ifdef AARCH64_AVAILABLE -#include "AArch64Subtarget.h" -#include "MCTargetDesc/AArch64MCTargetDesc.h" #include "AArch64.h" +#include "AArch64Subtarget.h" #include "MCTargetDesc/AArch64AddressingModes.h" +#include "MCTargetDesc/AArch64MCTargetDesc.h" #endif // AARCH64_AVAILABLE #ifdef X86_AVAILABLE From 19c3613b7614875e3cefe36ad972de8b5de20c27 Mon Sep 17 00:00:00 2001 From: Rodrigo Rocha Date: Sun, 8 Jun 2025 00:45:05 +0100 Subject: [PATCH 5/5] Modified createLoadImmediate to use MCInstBuilder --- .../Target/AArch64/AArch64MCPlusBuilder.cpp | 76 +++++++++---------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp index f2a4162ef6c2f..191eae68fee40 100644 --- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -2186,73 +2186,71 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { llvm_unreachable("unhandled!"); break; + // ORR , , # + // ORR , , # case AArch64::ORRWri: case AArch64::ORRXri: if (I->Op1 == 0) { - MCInst Inst; - Inst.setOpcode(I->Opcode); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createReg(BitSize == 32 ? AArch64::WZR - : AArch64::XZR)); - Inst.addOperand(MCOperand::createImm(I->Op2)); + MCInst Inst = MCInstBuilder(I->Opcode) + .addReg(Dest) + .addReg(BitSize == 32 ? AArch64::WZR : AArch64::XZR) + .addImm(I->Op2); Insts.push_back(Inst); } else { - MCInst Inst; - Inst.setOpcode(I->Opcode); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createImm(I->Op2)); + MCInst Inst = + MCInstBuilder(I->Opcode).addReg(Dest).addReg(Dest).addImm(I->Op2); Insts.push_back(Inst); } break; + // ORR , , , # + // ORR , , , # case AArch64::ORRWrs: case AArch64::ORRXrs: { - MCInst Inst; - Inst.setOpcode(I->Opcode); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createImm(I->Op2)); + MCInst Inst = MCInstBuilder(I->Opcode) + .addReg(Dest) + .addReg(Dest) + .addReg(Dest) + .addImm(I->Op1) // Shift type + .addImm(I->Op2); Insts.push_back(Inst); } break; + // AND Xd, Xn, #imm + // EOR Xd, Xn, #imm case AArch64::ANDXri: case AArch64::EORXri: if (I->Op1 == 0) { - MCInst Inst; - Inst.setOpcode(I->Opcode); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createReg(BitSize == 32 ? AArch64::WZR - : AArch64::XZR)); - Inst.addOperand(MCOperand::createImm(I->Op2)); + MCInst Inst = MCInstBuilder(I->Opcode) + .addReg(Dest) + .addReg(BitSize == 32 ? AArch64::WZR : AArch64::XZR) + .addImm(I->Op2); Insts.push_back(Inst); } else { - MCInst Inst; - Inst.setOpcode(I->Opcode); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createImm(I->Op2)); + MCInst Inst = + MCInstBuilder(I->Opcode).addReg(Dest).addReg(Dest).addImm(I->Op2); Insts.push_back(Inst); } break; + // MOVZ Wd, #imm16, LSL #shift + // MOVZ Xd, #imm16, LSL #shift + // MOVN Wd, #imm16, LSL #shift + // MOVN Xd, #imm16, LSL #shift case AArch64::MOVNWi: case AArch64::MOVNXi: case AArch64::MOVZWi: case AArch64::MOVZXi: { - MCInst Inst; - Inst.setOpcode(I->Opcode); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createImm(I->Op1)); - Inst.addOperand(MCOperand::createImm(I->Op2)); + MCInst Inst = + MCInstBuilder(I->Opcode).addReg(Dest).addImm(I->Op1).addImm(I->Op2); Insts.push_back(Inst); } break; + // MOVK Wd, #imm16, LSL #shift + // MOVK Xd, #imm16, LSL #shift case AArch64::MOVKWi: case AArch64::MOVKXi: { - MCInst Inst; - Inst.setOpcode(I->Opcode); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createReg(Dest)); - Inst.addOperand(MCOperand::createImm(I->Op1)); - Inst.addOperand(MCOperand::createImm(I->Op2)); + MCInst Inst = MCInstBuilder(I->Opcode) + .addReg(Dest) + .addReg(Dest) + .addImm(I->Op1) + .addImm(I->Op2); Insts.push_back(Inst); } break; }