xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file provides ARM specific target descriptions.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "ARMMCTargetDesc.h"
14e8d8bef9SDimitry Andric #include "ARMAddressingModes.h"
150b57cec5SDimitry Andric #include "ARMBaseInfo.h"
160b57cec5SDimitry Andric #include "ARMInstPrinter.h"
170b57cec5SDimitry Andric #include "ARMMCAsmInfo.h"
180b57cec5SDimitry Andric #include "TargetInfo/ARMTargetInfo.h"
19e8d8bef9SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCELFStreamer.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCInstrAnalysis.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
250b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
260b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
270b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
280b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
29349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
300b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
3106c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric using namespace llvm;
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric #define GET_REGINFO_MC_DESC
360b57cec5SDimitry Andric #include "ARMGenRegisterInfo.inc"
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric static bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
390b57cec5SDimitry Andric                                   std::string &Info) {
4006c3fb27SDimitry Andric   if (STI.hasFeature(llvm::ARM::HasV7Ops) &&
410b57cec5SDimitry Andric       (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
420b57cec5SDimitry Andric       (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
430b57cec5SDimitry Andric       // Checks for the deprecated CP15ISB encoding:
440b57cec5SDimitry Andric       // mcr p15, #0, rX, c7, c5, #4
450b57cec5SDimitry Andric       (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) {
460b57cec5SDimitry Andric     if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
470b57cec5SDimitry Andric       if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
480b57cec5SDimitry Andric         Info = "deprecated since v7, use 'isb'";
490b57cec5SDimitry Andric         return true;
500b57cec5SDimitry Andric       }
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric       // Checks for the deprecated CP15DSB encoding:
530b57cec5SDimitry Andric       // mcr p15, #0, rX, c7, c10, #4
540b57cec5SDimitry Andric       if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
550b57cec5SDimitry Andric         Info = "deprecated since v7, use 'dsb'";
560b57cec5SDimitry Andric         return true;
570b57cec5SDimitry Andric       }
580b57cec5SDimitry Andric     }
590b57cec5SDimitry Andric     // Checks for the deprecated CP15DMB encoding:
600b57cec5SDimitry Andric     // mcr p15, #0, rX, c7, c10, #5
610b57cec5SDimitry Andric     if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
620b57cec5SDimitry Andric         (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
630b57cec5SDimitry Andric       Info = "deprecated since v7, use 'dmb'";
640b57cec5SDimitry Andric       return true;
650b57cec5SDimitry Andric     }
660b57cec5SDimitry Andric   }
6706c3fb27SDimitry Andric   if (STI.hasFeature(llvm::ARM::HasV7Ops) &&
685ffd83dbSDimitry Andric       ((MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 10) ||
695ffd83dbSDimitry Andric        (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 11))) {
705ffd83dbSDimitry Andric     Info = "since v7, cp10 and cp11 are reserved for advanced SIMD or floating "
715ffd83dbSDimitry Andric            "point instructions";
725ffd83dbSDimitry Andric     return true;
735ffd83dbSDimitry Andric   }
745ffd83dbSDimitry Andric   return false;
755ffd83dbSDimitry Andric }
765ffd83dbSDimitry Andric 
775ffd83dbSDimitry Andric static bool getMRCDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
785ffd83dbSDimitry Andric                                   std::string &Info) {
7906c3fb27SDimitry Andric   if (STI.hasFeature(llvm::ARM::HasV7Ops) &&
805ffd83dbSDimitry Andric       ((MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 10) ||
815ffd83dbSDimitry Andric        (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 11))) {
825ffd83dbSDimitry Andric     Info = "since v7, cp10 and cp11 are reserved for advanced SIMD or floating "
835ffd83dbSDimitry Andric            "point instructions";
845ffd83dbSDimitry Andric     return true;
855ffd83dbSDimitry Andric   }
860b57cec5SDimitry Andric   return false;
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric static bool getARMStoreDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
900b57cec5SDimitry Andric                                        std::string &Info) {
9106c3fb27SDimitry Andric   assert(!STI.hasFeature(llvm::ARM::ModeThumb) &&
920b57cec5SDimitry Andric          "cannot predicate thumb instructions");
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
950b57cec5SDimitry Andric   for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
960b57cec5SDimitry Andric     assert(MI.getOperand(OI).isReg() && "expected register");
97fe6060f1SDimitry Andric     if (MI.getOperand(OI).getReg() == ARM::PC) {
98fe6060f1SDimitry Andric       Info = "use of PC in the list is deprecated";
990b57cec5SDimitry Andric       return true;
1000b57cec5SDimitry Andric     }
1010b57cec5SDimitry Andric   }
1020b57cec5SDimitry Andric   return false;
1030b57cec5SDimitry Andric }
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric static bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
1060b57cec5SDimitry Andric                                       std::string &Info) {
10706c3fb27SDimitry Andric   assert(!STI.hasFeature(llvm::ARM::ModeThumb) &&
1080b57cec5SDimitry Andric          "cannot predicate thumb instructions");
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
1110b57cec5SDimitry Andric   bool ListContainsPC = false, ListContainsLR = false;
1120b57cec5SDimitry Andric   for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
1130b57cec5SDimitry Andric     assert(MI.getOperand(OI).isReg() && "expected register");
1140b57cec5SDimitry Andric     switch (MI.getOperand(OI).getReg()) {
1150b57cec5SDimitry Andric     default:
1160b57cec5SDimitry Andric       break;
1170b57cec5SDimitry Andric     case ARM::LR:
1180b57cec5SDimitry Andric       ListContainsLR = true;
1190b57cec5SDimitry Andric       break;
1200b57cec5SDimitry Andric     case ARM::PC:
1210b57cec5SDimitry Andric       ListContainsPC = true;
1220b57cec5SDimitry Andric       break;
1230b57cec5SDimitry Andric     }
1240b57cec5SDimitry Andric   }
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric   if (ListContainsPC && ListContainsLR) {
1270b57cec5SDimitry Andric     Info = "use of LR and PC simultaneously in the list is deprecated";
1280b57cec5SDimitry Andric     return true;
1290b57cec5SDimitry Andric   }
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   return false;
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric #define GET_INSTRINFO_MC_DESC
135753f127fSDimitry Andric #define ENABLE_INSTR_PREDICATE_VERIFIER
1360b57cec5SDimitry Andric #include "ARMGenInstrInfo.inc"
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric #define GET_SUBTARGETINFO_MC_DESC
1390b57cec5SDimitry Andric #include "ARMGenSubtargetInfo.inc"
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
1420b57cec5SDimitry Andric   std::string ARMArchFeature;
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   ARM::ArchKind ArchID = ARM::parseArch(TT.getArchName());
1450b57cec5SDimitry Andric   if (ArchID != ARM::ArchKind::INVALID &&  (CPU.empty() || CPU == "generic"))
1460b57cec5SDimitry Andric     ARMArchFeature = (ARMArchFeature + "+" + ARM::getArchName(ArchID)).str();
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric   if (TT.isThumb()) {
1490b57cec5SDimitry Andric     if (!ARMArchFeature.empty())
1500b57cec5SDimitry Andric       ARMArchFeature += ",";
1510b57cec5SDimitry Andric     ARMArchFeature += "+thumb-mode,+v4t";
1520b57cec5SDimitry Andric   }
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric   if (TT.isOSNaCl()) {
1550b57cec5SDimitry Andric     if (!ARMArchFeature.empty())
1560b57cec5SDimitry Andric       ARMArchFeature += ",";
1570b57cec5SDimitry Andric     ARMArchFeature += "+nacl-trap";
1580b57cec5SDimitry Andric   }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   if (TT.isOSWindows()) {
1610b57cec5SDimitry Andric     if (!ARMArchFeature.empty())
1620b57cec5SDimitry Andric       ARMArchFeature += ",";
1630b57cec5SDimitry Andric     ARMArchFeature += "+noarm";
1640b57cec5SDimitry Andric   }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   return ARMArchFeature;
1670b57cec5SDimitry Andric }
1680b57cec5SDimitry Andric 
169e8d8bef9SDimitry Andric bool ARM_MC::isPredicated(const MCInst &MI, const MCInstrInfo *MCII) {
170e8d8bef9SDimitry Andric   const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
171e8d8bef9SDimitry Andric   int PredOpIdx = Desc.findFirstPredOperandIdx();
172e8d8bef9SDimitry Andric   return PredOpIdx != -1 && MI.getOperand(PredOpIdx).getImm() != ARMCC::AL;
173e8d8bef9SDimitry Andric }
174e8d8bef9SDimitry Andric 
175e8d8bef9SDimitry Andric bool ARM_MC::isCPSRDefined(const MCInst &MI, const MCInstrInfo *MCII) {
176e8d8bef9SDimitry Andric   const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
177e8d8bef9SDimitry Andric   for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
178e8d8bef9SDimitry Andric     const MCOperand &MO = MI.getOperand(I);
179e8d8bef9SDimitry Andric     if (MO.isReg() && MO.getReg() == ARM::CPSR &&
180bdd1243dSDimitry Andric         Desc.operands()[I].isOptionalDef())
181e8d8bef9SDimitry Andric       return true;
182e8d8bef9SDimitry Andric   }
183e8d8bef9SDimitry Andric   return false;
184e8d8bef9SDimitry Andric }
185e8d8bef9SDimitry Andric 
186fe6060f1SDimitry Andric uint64_t ARM_MC::evaluateBranchTarget(const MCInstrDesc &InstDesc,
187fe6060f1SDimitry Andric                                       uint64_t Addr, int64_t Imm) {
188fe6060f1SDimitry Andric   // For ARM instructions the PC offset is 8 bytes, for Thumb instructions it
189fe6060f1SDimitry Andric   // is 4 bytes.
190fe6060f1SDimitry Andric   uint64_t Offset =
191fe6060f1SDimitry Andric       ((InstDesc.TSFlags & ARMII::FormMask) == ARMII::ThumbFrm) ? 4 : 8;
192fe6060f1SDimitry Andric 
193fe6060f1SDimitry Andric   // A Thumb instruction BLX(i) can be 16-bit aligned while targets Arm code
194fe6060f1SDimitry Andric   // which is 32-bit aligned. The target address for the case is calculated as
195fe6060f1SDimitry Andric   //   targetAddress = Align(PC,4) + imm32;
196fe6060f1SDimitry Andric   // where
197fe6060f1SDimitry Andric   //   Align(x, y) = y * (x DIV y);
198fe6060f1SDimitry Andric   if (InstDesc.getOpcode() == ARM::tBLXi)
199fe6060f1SDimitry Andric     Addr &= ~0x3;
200fe6060f1SDimitry Andric 
201fe6060f1SDimitry Andric   return Addr + Imm + Offset;
202fe6060f1SDimitry Andric }
203fe6060f1SDimitry Andric 
2040b57cec5SDimitry Andric MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT,
2050b57cec5SDimitry Andric                                                   StringRef CPU, StringRef FS) {
2060b57cec5SDimitry Andric   std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
2070b57cec5SDimitry Andric   if (!FS.empty()) {
2080b57cec5SDimitry Andric     if (!ArchFS.empty())
2090b57cec5SDimitry Andric       ArchFS = (Twine(ArchFS) + "," + FS).str();
2100b57cec5SDimitry Andric     else
2115ffd83dbSDimitry Andric       ArchFS = std::string(FS);
2120b57cec5SDimitry Andric   }
2130b57cec5SDimitry Andric 
214e8d8bef9SDimitry Andric   return createARMMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, ArchFS);
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric static MCInstrInfo *createARMMCInstrInfo() {
2180b57cec5SDimitry Andric   MCInstrInfo *X = new MCInstrInfo();
2190b57cec5SDimitry Andric   InitARMMCInstrInfo(X);
2200b57cec5SDimitry Andric   return X;
2210b57cec5SDimitry Andric }
2220b57cec5SDimitry Andric 
223e8d8bef9SDimitry Andric void ARM_MC::initLLVMToCVRegMapping(MCRegisterInfo *MRI) {
224e8d8bef9SDimitry Andric   // Mapping from CodeView to MC register id.
225e8d8bef9SDimitry Andric   static const struct {
226e8d8bef9SDimitry Andric     codeview::RegisterId CVReg;
227e8d8bef9SDimitry Andric     MCPhysReg Reg;
228e8d8bef9SDimitry Andric   } RegMap[] = {
229e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R0, ARM::R0},
230e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R1, ARM::R1},
231e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R2, ARM::R2},
232e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R3, ARM::R3},
233e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R4, ARM::R4},
234e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R5, ARM::R5},
235e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R6, ARM::R6},
236e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R7, ARM::R7},
237e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R8, ARM::R8},
238e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R9, ARM::R9},
239e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R10, ARM::R10},
240e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R11, ARM::R11},
241e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_R12, ARM::R12},
242e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_SP, ARM::SP},
243e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_LR, ARM::LR},
244e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_PC, ARM::PC},
245e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_CPSR, ARM::CPSR},
246e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FPSCR, ARM::FPSCR},
247e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FPEXC, ARM::FPEXC},
248e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS0, ARM::S0},
249e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS1, ARM::S1},
250e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS2, ARM::S2},
251e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS3, ARM::S3},
252e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS4, ARM::S4},
253e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS5, ARM::S5},
254e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS6, ARM::S6},
255e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS7, ARM::S7},
256e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS8, ARM::S8},
257e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS9, ARM::S9},
258e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS10, ARM::S10},
259e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS11, ARM::S11},
260e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS12, ARM::S12},
261e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS13, ARM::S13},
262e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS14, ARM::S14},
263e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS15, ARM::S15},
264e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS16, ARM::S16},
265e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS17, ARM::S17},
266e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS18, ARM::S18},
267e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS19, ARM::S19},
268e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS20, ARM::S20},
269e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS21, ARM::S21},
270e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS22, ARM::S22},
271e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS23, ARM::S23},
272e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS24, ARM::S24},
273e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS25, ARM::S25},
274e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS26, ARM::S26},
275e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS27, ARM::S27},
276e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS28, ARM::S28},
277e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS29, ARM::S29},
278e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS30, ARM::S30},
279e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_FS31, ARM::S31},
280e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND0, ARM::D0},
281e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND1, ARM::D1},
282e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND2, ARM::D2},
283e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND3, ARM::D3},
284e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND4, ARM::D4},
285e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND5, ARM::D5},
286e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND6, ARM::D6},
287e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND7, ARM::D7},
288e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND8, ARM::D8},
289e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND9, ARM::D9},
290e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND10, ARM::D10},
291e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND11, ARM::D11},
292e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND12, ARM::D12},
293e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND13, ARM::D13},
294e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND14, ARM::D14},
295e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND15, ARM::D15},
296e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND16, ARM::D16},
297e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND17, ARM::D17},
298e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND18, ARM::D18},
299e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND19, ARM::D19},
300e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND20, ARM::D20},
301e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND21, ARM::D21},
302e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND22, ARM::D22},
303e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND23, ARM::D23},
304e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND24, ARM::D24},
305e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND25, ARM::D25},
306e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND26, ARM::D26},
307e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND27, ARM::D27},
308e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND28, ARM::D28},
309e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND29, ARM::D29},
310e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND30, ARM::D30},
311e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_ND31, ARM::D31},
312e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ0, ARM::Q0},
313e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ1, ARM::Q1},
314e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ2, ARM::Q2},
315e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ3, ARM::Q3},
316e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ4, ARM::Q4},
317e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ5, ARM::Q5},
318e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ6, ARM::Q6},
319e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ7, ARM::Q7},
320e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ8, ARM::Q8},
321e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ9, ARM::Q9},
322e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ10, ARM::Q10},
323e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ11, ARM::Q11},
324e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ12, ARM::Q12},
325e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ13, ARM::Q13},
326e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ14, ARM::Q14},
327e8d8bef9SDimitry Andric       {codeview::RegisterId::ARM_NQ15, ARM::Q15},
328e8d8bef9SDimitry Andric   };
32904eeddc0SDimitry Andric   for (const auto &I : RegMap)
33004eeddc0SDimitry Andric     MRI->mapLLVMRegToCVReg(I.Reg, static_cast<int>(I.CVReg));
331e8d8bef9SDimitry Andric }
332e8d8bef9SDimitry Andric 
3330b57cec5SDimitry Andric static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) {
3340b57cec5SDimitry Andric   MCRegisterInfo *X = new MCRegisterInfo();
3350b57cec5SDimitry Andric   InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
336e8d8bef9SDimitry Andric   ARM_MC::initLLVMToCVRegMapping(X);
3370b57cec5SDimitry Andric   return X;
3380b57cec5SDimitry Andric }
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI,
341480093f4SDimitry Andric                                      const Triple &TheTriple,
342480093f4SDimitry Andric                                      const MCTargetOptions &Options) {
3430b57cec5SDimitry Andric   MCAsmInfo *MAI;
3440b57cec5SDimitry Andric   if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO())
3450b57cec5SDimitry Andric     MAI = new ARMMCAsmInfoDarwin(TheTriple);
3460b57cec5SDimitry Andric   else if (TheTriple.isWindowsMSVCEnvironment())
3470b57cec5SDimitry Andric     MAI = new ARMCOFFMCAsmInfoMicrosoft();
3480b57cec5SDimitry Andric   else if (TheTriple.isOSWindows())
3490b57cec5SDimitry Andric     MAI = new ARMCOFFMCAsmInfoGNU();
3500b57cec5SDimitry Andric   else
3510b57cec5SDimitry Andric     MAI = new ARMELFMCAsmInfo(TheTriple);
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric   unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
3545ffd83dbSDimitry Andric   MAI->addInitialFrameState(MCCFIInstruction::cfiDefCfa(nullptr, Reg, 0));
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric   return MAI;
3570b57cec5SDimitry Andric }
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
3600b57cec5SDimitry Andric                                      std::unique_ptr<MCAsmBackend> &&MAB,
3610b57cec5SDimitry Andric                                      std::unique_ptr<MCObjectWriter> &&OW,
362*0fca6ea1SDimitry Andric                                      std::unique_ptr<MCCodeEmitter> &&Emitter) {
3630b57cec5SDimitry Andric   return createARMELFStreamer(
364*0fca6ea1SDimitry Andric       Ctx, std::move(MAB), std::move(OW), std::move(Emitter),
365480093f4SDimitry Andric       (T.getArch() == Triple::thumb || T.getArch() == Triple::thumbeb),
366480093f4SDimitry Andric       T.isAndroid());
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric static MCStreamer *
3700b57cec5SDimitry Andric createARMMachOStreamer(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&MAB,
3710b57cec5SDimitry Andric                        std::unique_ptr<MCObjectWriter> &&OW,
372*0fca6ea1SDimitry Andric                        std::unique_ptr<MCCodeEmitter> &&Emitter) {
3730b57cec5SDimitry Andric   return createMachOStreamer(Ctx, std::move(MAB), std::move(OW),
374*0fca6ea1SDimitry Andric                              std::move(Emitter), false);
3750b57cec5SDimitry Andric }
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric static MCInstPrinter *createARMMCInstPrinter(const Triple &T,
3780b57cec5SDimitry Andric                                              unsigned SyntaxVariant,
3790b57cec5SDimitry Andric                                              const MCAsmInfo &MAI,
3800b57cec5SDimitry Andric                                              const MCInstrInfo &MII,
3810b57cec5SDimitry Andric                                              const MCRegisterInfo &MRI) {
3820b57cec5SDimitry Andric   if (SyntaxVariant == 0)
3830b57cec5SDimitry Andric     return new ARMInstPrinter(MAI, MII, MRI);
3840b57cec5SDimitry Andric   return nullptr;
3850b57cec5SDimitry Andric }
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric static MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT,
3880b57cec5SDimitry Andric                                                    MCContext &Ctx) {
3890b57cec5SDimitry Andric   if (TT.isOSBinFormatMachO())
3900b57cec5SDimitry Andric     return createARMMachORelocationInfo(Ctx);
3910b57cec5SDimitry Andric   // Default to the stock relocation info.
3920b57cec5SDimitry Andric   return llvm::createMCRelocationInfo(TT, Ctx);
3930b57cec5SDimitry Andric }
3940b57cec5SDimitry Andric 
3950b57cec5SDimitry Andric namespace {
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric class ARMMCInstrAnalysis : public MCInstrAnalysis {
3980b57cec5SDimitry Andric public:
3990b57cec5SDimitry Andric   ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   bool isUnconditionalBranch(const MCInst &Inst) const override {
4020b57cec5SDimitry Andric     // BCCs with the "always" predicate are unconditional branches.
4030b57cec5SDimitry Andric     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
4040b57cec5SDimitry Andric       return true;
4050b57cec5SDimitry Andric     return MCInstrAnalysis::isUnconditionalBranch(Inst);
4060b57cec5SDimitry Andric   }
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric   bool isConditionalBranch(const MCInst &Inst) const override {
4090b57cec5SDimitry Andric     // BCCs with the "always" predicate are unconditional branches.
4100b57cec5SDimitry Andric     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
4110b57cec5SDimitry Andric       return false;
4120b57cec5SDimitry Andric     return MCInstrAnalysis::isConditionalBranch(Inst);
4130b57cec5SDimitry Andric   }
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
4160b57cec5SDimitry Andric                       uint64_t &Target) const override {
417fe6060f1SDimitry Andric     const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
4180b57cec5SDimitry Andric 
419fe6060f1SDimitry Andric     // Find the PC-relative immediate operand in the instruction.
420fe6060f1SDimitry Andric     for (unsigned OpNum = 0; OpNum < Desc.getNumOperands(); ++OpNum) {
421fe6060f1SDimitry Andric       if (Inst.getOperand(OpNum).isImm() &&
422bdd1243dSDimitry Andric           Desc.operands()[OpNum].OperandType == MCOI::OPERAND_PCREL) {
423fe6060f1SDimitry Andric         int64_t Imm = Inst.getOperand(OpNum).getImm();
424fe6060f1SDimitry Andric         Target = ARM_MC::evaluateBranchTarget(Desc, Addr, Imm);
4250b57cec5SDimitry Andric         return true;
4260b57cec5SDimitry Andric       }
427fe6060f1SDimitry Andric     }
428fe6060f1SDimitry Andric     return false;
429fe6060f1SDimitry Andric   }
430349cc55cSDimitry Andric 
431bdd1243dSDimitry Andric   std::optional<uint64_t>
432bdd1243dSDimitry Andric   evaluateMemoryOperandAddress(const MCInst &Inst, const MCSubtargetInfo *STI,
433bdd1243dSDimitry Andric                                uint64_t Addr, uint64_t Size) const override;
4340b57cec5SDimitry Andric };
4350b57cec5SDimitry Andric 
436349cc55cSDimitry Andric } // namespace
437349cc55cSDimitry Andric 
438bdd1243dSDimitry Andric static std::optional<uint64_t>
439349cc55cSDimitry Andric // NOLINTNEXTLINE(readability-identifier-naming)
440349cc55cSDimitry Andric evaluateMemOpAddrForAddrMode_i12(const MCInst &Inst, const MCInstrDesc &Desc,
441349cc55cSDimitry Andric                                  unsigned MemOpIndex, uint64_t Addr) {
442349cc55cSDimitry Andric   if (MemOpIndex + 1 >= Desc.getNumOperands())
443bdd1243dSDimitry Andric     return std::nullopt;
444349cc55cSDimitry Andric 
445349cc55cSDimitry Andric   const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
446349cc55cSDimitry Andric   const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
447349cc55cSDimitry Andric   if (!MO1.isReg() || MO1.getReg() != ARM::PC || !MO2.isImm())
448bdd1243dSDimitry Andric     return std::nullopt;
449349cc55cSDimitry Andric 
450349cc55cSDimitry Andric   int32_t OffImm = (int32_t)MO2.getImm();
451349cc55cSDimitry Andric   // Special value for #-0. All others are normal.
452349cc55cSDimitry Andric   if (OffImm == INT32_MIN)
453349cc55cSDimitry Andric     OffImm = 0;
454349cc55cSDimitry Andric   return Addr + OffImm;
455349cc55cSDimitry Andric }
456349cc55cSDimitry Andric 
457bdd1243dSDimitry Andric static std::optional<uint64_t>
458bdd1243dSDimitry Andric evaluateMemOpAddrForAddrMode3(const MCInst &Inst, const MCInstrDesc &Desc,
459bdd1243dSDimitry Andric                               unsigned MemOpIndex, uint64_t Addr) {
460349cc55cSDimitry Andric   if (MemOpIndex + 2 >= Desc.getNumOperands())
461bdd1243dSDimitry Andric     return std::nullopt;
462349cc55cSDimitry Andric 
463349cc55cSDimitry Andric   const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
464349cc55cSDimitry Andric   const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
465349cc55cSDimitry Andric   const MCOperand &MO3 = Inst.getOperand(MemOpIndex + 2);
466349cc55cSDimitry Andric   if (!MO1.isReg() || MO1.getReg() != ARM::PC || MO2.getReg() || !MO3.isImm())
467bdd1243dSDimitry Andric     return std::nullopt;
468349cc55cSDimitry Andric 
469349cc55cSDimitry Andric   unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
470349cc55cSDimitry Andric   ARM_AM::AddrOpc Op = ARM_AM::getAM3Op(MO3.getImm());
471349cc55cSDimitry Andric 
472349cc55cSDimitry Andric   if (Op == ARM_AM::sub)
473349cc55cSDimitry Andric     return Addr - ImmOffs;
474349cc55cSDimitry Andric   return Addr + ImmOffs;
475349cc55cSDimitry Andric }
476349cc55cSDimitry Andric 
477bdd1243dSDimitry Andric static std::optional<uint64_t>
478bdd1243dSDimitry Andric evaluateMemOpAddrForAddrMode5(const MCInst &Inst, const MCInstrDesc &Desc,
479bdd1243dSDimitry Andric                               unsigned MemOpIndex, uint64_t Addr) {
480349cc55cSDimitry Andric   if (MemOpIndex + 1 >= Desc.getNumOperands())
481bdd1243dSDimitry Andric     return std::nullopt;
482349cc55cSDimitry Andric 
483349cc55cSDimitry Andric   const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
484349cc55cSDimitry Andric   const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
485349cc55cSDimitry Andric   if (!MO1.isReg() || MO1.getReg() != ARM::PC || !MO2.isImm())
486bdd1243dSDimitry Andric     return std::nullopt;
487349cc55cSDimitry Andric 
488349cc55cSDimitry Andric   unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
489349cc55cSDimitry Andric   ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm());
490349cc55cSDimitry Andric 
491349cc55cSDimitry Andric   if (Op == ARM_AM::sub)
492349cc55cSDimitry Andric     return Addr - ImmOffs * 4;
493349cc55cSDimitry Andric   return Addr + ImmOffs * 4;
494349cc55cSDimitry Andric }
495349cc55cSDimitry Andric 
496bdd1243dSDimitry Andric static std::optional<uint64_t>
497349cc55cSDimitry Andric evaluateMemOpAddrForAddrMode5FP16(const MCInst &Inst, const MCInstrDesc &Desc,
498349cc55cSDimitry Andric                                   unsigned MemOpIndex, uint64_t Addr) {
499349cc55cSDimitry Andric   if (MemOpIndex + 1 >= Desc.getNumOperands())
500bdd1243dSDimitry Andric     return std::nullopt;
501349cc55cSDimitry Andric 
502349cc55cSDimitry Andric   const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
503349cc55cSDimitry Andric   const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
504349cc55cSDimitry Andric   if (!MO1.isReg() || MO1.getReg() != ARM::PC || !MO2.isImm())
505bdd1243dSDimitry Andric     return std::nullopt;
506349cc55cSDimitry Andric 
507349cc55cSDimitry Andric   unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
508349cc55cSDimitry Andric   ARM_AM::AddrOpc Op = ARM_AM::getAM5FP16Op(MO2.getImm());
509349cc55cSDimitry Andric 
510349cc55cSDimitry Andric   if (Op == ARM_AM::sub)
511349cc55cSDimitry Andric     return Addr - ImmOffs * 2;
512349cc55cSDimitry Andric   return Addr + ImmOffs * 2;
513349cc55cSDimitry Andric }
514349cc55cSDimitry Andric 
515bdd1243dSDimitry Andric static std::optional<uint64_t>
516349cc55cSDimitry Andric // NOLINTNEXTLINE(readability-identifier-naming)
517349cc55cSDimitry Andric evaluateMemOpAddrForAddrModeT2_i8s4(const MCInst &Inst, const MCInstrDesc &Desc,
518349cc55cSDimitry Andric                                     unsigned MemOpIndex, uint64_t Addr) {
519349cc55cSDimitry Andric   if (MemOpIndex + 1 >= Desc.getNumOperands())
520bdd1243dSDimitry Andric     return std::nullopt;
521349cc55cSDimitry Andric 
522349cc55cSDimitry Andric   const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
523349cc55cSDimitry Andric   const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
524349cc55cSDimitry Andric   if (!MO1.isReg() || MO1.getReg() != ARM::PC || !MO2.isImm())
525bdd1243dSDimitry Andric     return std::nullopt;
526349cc55cSDimitry Andric 
527349cc55cSDimitry Andric   int32_t OffImm = (int32_t)MO2.getImm();
528349cc55cSDimitry Andric   assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
529349cc55cSDimitry Andric 
530349cc55cSDimitry Andric   // Special value for #-0. All others are normal.
531349cc55cSDimitry Andric   if (OffImm == INT32_MIN)
532349cc55cSDimitry Andric     OffImm = 0;
533349cc55cSDimitry Andric   return Addr + OffImm;
534349cc55cSDimitry Andric }
535349cc55cSDimitry Andric 
536bdd1243dSDimitry Andric static std::optional<uint64_t>
537349cc55cSDimitry Andric // NOLINTNEXTLINE(readability-identifier-naming)
538349cc55cSDimitry Andric evaluateMemOpAddrForAddrModeT2_pc(const MCInst &Inst, const MCInstrDesc &Desc,
539349cc55cSDimitry Andric                                   unsigned MemOpIndex, uint64_t Addr) {
540349cc55cSDimitry Andric   const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
541349cc55cSDimitry Andric   if (!MO1.isImm())
542bdd1243dSDimitry Andric     return std::nullopt;
543349cc55cSDimitry Andric 
544349cc55cSDimitry Andric   int32_t OffImm = (int32_t)MO1.getImm();
545349cc55cSDimitry Andric 
546349cc55cSDimitry Andric   // Special value for #-0. All others are normal.
547349cc55cSDimitry Andric   if (OffImm == INT32_MIN)
548349cc55cSDimitry Andric     OffImm = 0;
549349cc55cSDimitry Andric   return Addr + OffImm;
550349cc55cSDimitry Andric }
551349cc55cSDimitry Andric 
552bdd1243dSDimitry Andric static std::optional<uint64_t>
553349cc55cSDimitry Andric // NOLINTNEXTLINE(readability-identifier-naming)
554349cc55cSDimitry Andric evaluateMemOpAddrForAddrModeT1_s(const MCInst &Inst, const MCInstrDesc &Desc,
555349cc55cSDimitry Andric                                  unsigned MemOpIndex, uint64_t Addr) {
556349cc55cSDimitry Andric   return evaluateMemOpAddrForAddrModeT2_pc(Inst, Desc, MemOpIndex, Addr);
557349cc55cSDimitry Andric }
558349cc55cSDimitry Andric 
559bdd1243dSDimitry Andric std::optional<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
560349cc55cSDimitry Andric     const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr,
561349cc55cSDimitry Andric     uint64_t Size) const {
562349cc55cSDimitry Andric   const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
563349cc55cSDimitry Andric 
564349cc55cSDimitry Andric   // Only load instructions can have PC-relative memory addressing.
565349cc55cSDimitry Andric   if (!Desc.mayLoad())
566bdd1243dSDimitry Andric     return std::nullopt;
567349cc55cSDimitry Andric 
568349cc55cSDimitry Andric   // PC-relative addressing does not update the base register.
569349cc55cSDimitry Andric   uint64_t TSFlags = Desc.TSFlags;
570349cc55cSDimitry Andric   unsigned IndexMode =
571349cc55cSDimitry Andric       (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
572349cc55cSDimitry Andric   if (IndexMode != ARMII::IndexModeNone)
573bdd1243dSDimitry Andric     return std::nullopt;
574349cc55cSDimitry Andric 
575349cc55cSDimitry Andric   // Find the memory addressing operand in the instruction.
576349cc55cSDimitry Andric   unsigned OpIndex = Desc.NumDefs;
577349cc55cSDimitry Andric   while (OpIndex < Desc.getNumOperands() &&
578bdd1243dSDimitry Andric          Desc.operands()[OpIndex].OperandType != MCOI::OPERAND_MEMORY)
579349cc55cSDimitry Andric     ++OpIndex;
580349cc55cSDimitry Andric   if (OpIndex == Desc.getNumOperands())
581bdd1243dSDimitry Andric     return std::nullopt;
582349cc55cSDimitry Andric 
583349cc55cSDimitry Andric   // Base address for PC-relative addressing is always 32-bit aligned.
584349cc55cSDimitry Andric   Addr &= ~0x3;
585349cc55cSDimitry Andric 
586349cc55cSDimitry Andric   // For ARM instructions the PC offset is 8 bytes, for Thumb instructions it
587349cc55cSDimitry Andric   // is 4 bytes.
588349cc55cSDimitry Andric   switch (Desc.TSFlags & ARMII::FormMask) {
589349cc55cSDimitry Andric   default:
590349cc55cSDimitry Andric     Addr += 8;
591349cc55cSDimitry Andric     break;
592349cc55cSDimitry Andric   case ARMII::ThumbFrm:
593349cc55cSDimitry Andric     Addr += 4;
594349cc55cSDimitry Andric     break;
595349cc55cSDimitry Andric   // VLDR* instructions share the same opcode (and thus the same form) for Arm
596349cc55cSDimitry Andric   // and Thumb. Use a bit longer route through STI in that case.
597349cc55cSDimitry Andric   case ARMII::VFPLdStFrm:
59806c3fb27SDimitry Andric     Addr += STI->hasFeature(ARM::ModeThumb) ? 4 : 8;
599349cc55cSDimitry Andric     break;
600349cc55cSDimitry Andric   }
601349cc55cSDimitry Andric 
602349cc55cSDimitry Andric   // Eveluate the address depending on the addressing mode
603349cc55cSDimitry Andric   unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
604349cc55cSDimitry Andric   switch (AddrMode) {
605349cc55cSDimitry Andric   default:
606bdd1243dSDimitry Andric     return std::nullopt;
607349cc55cSDimitry Andric   case ARMII::AddrMode_i12:
608349cc55cSDimitry Andric     return evaluateMemOpAddrForAddrMode_i12(Inst, Desc, OpIndex, Addr);
609349cc55cSDimitry Andric   case ARMII::AddrMode3:
610349cc55cSDimitry Andric     return evaluateMemOpAddrForAddrMode3(Inst, Desc, OpIndex, Addr);
611349cc55cSDimitry Andric   case ARMII::AddrMode5:
612349cc55cSDimitry Andric     return evaluateMemOpAddrForAddrMode5(Inst, Desc, OpIndex, Addr);
613349cc55cSDimitry Andric   case ARMII::AddrMode5FP16:
614349cc55cSDimitry Andric     return evaluateMemOpAddrForAddrMode5FP16(Inst, Desc, OpIndex, Addr);
615349cc55cSDimitry Andric   case ARMII::AddrModeT2_i8s4:
616349cc55cSDimitry Andric     return evaluateMemOpAddrForAddrModeT2_i8s4(Inst, Desc, OpIndex, Addr);
617349cc55cSDimitry Andric   case ARMII::AddrModeT2_pc:
618349cc55cSDimitry Andric     return evaluateMemOpAddrForAddrModeT2_pc(Inst, Desc, OpIndex, Addr);
619349cc55cSDimitry Andric   case ARMII::AddrModeT1_s:
620349cc55cSDimitry Andric     return evaluateMemOpAddrForAddrModeT1_s(Inst, Desc, OpIndex, Addr);
621349cc55cSDimitry Andric   }
6220b57cec5SDimitry Andric }
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) {
6250b57cec5SDimitry Andric   return new ARMMCInstrAnalysis(Info);
6260b57cec5SDimitry Andric }
6270b57cec5SDimitry Andric 
6285ffd83dbSDimitry Andric bool ARM::isCDECoproc(size_t Coproc, const MCSubtargetInfo &STI) {
6295ffd83dbSDimitry Andric   // Unfortunately we don't have ARMTargetInfo in the disassembler, so we have
6305ffd83dbSDimitry Andric   // to rely on feature bits.
6315ffd83dbSDimitry Andric   if (Coproc >= 8)
6325ffd83dbSDimitry Andric     return false;
6335ffd83dbSDimitry Andric   return STI.getFeatureBits()[ARM::FeatureCoprocCDE0 + Coproc];
6345ffd83dbSDimitry Andric }
6355ffd83dbSDimitry Andric 
6360b57cec5SDimitry Andric // Force static initialization.
637480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMTargetMC() {
6380b57cec5SDimitry Andric   for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget(),
6390b57cec5SDimitry Andric                     &getTheThumbLETarget(), &getTheThumbBETarget()}) {
6400b57cec5SDimitry Andric     // Register the MC asm info.
6410b57cec5SDimitry Andric     RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo);
6420b57cec5SDimitry Andric 
6430b57cec5SDimitry Andric     // Register the MC instruction info.
6440b57cec5SDimitry Andric     TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo);
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric     // Register the MC register info.
6470b57cec5SDimitry Andric     TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo);
6480b57cec5SDimitry Andric 
6490b57cec5SDimitry Andric     // Register the MC subtarget info.
6500b57cec5SDimitry Andric     TargetRegistry::RegisterMCSubtargetInfo(*T,
6510b57cec5SDimitry Andric                                             ARM_MC::createARMMCSubtargetInfo);
6520b57cec5SDimitry Andric 
6530b57cec5SDimitry Andric     TargetRegistry::RegisterELFStreamer(*T, createELFStreamer);
6540b57cec5SDimitry Andric     TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer);
6550b57cec5SDimitry Andric     TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer);
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric     // Register the obj target streamer.
6580b57cec5SDimitry Andric     TargetRegistry::RegisterObjectTargetStreamer(*T,
6590b57cec5SDimitry Andric                                                  createARMObjectTargetStreamer);
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric     // Register the asm streamer.
6620b57cec5SDimitry Andric     TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer);
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric     // Register the null TargetStreamer.
6650b57cec5SDimitry Andric     TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer);
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric     // Register the MCInstPrinter.
6680b57cec5SDimitry Andric     TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter);
6690b57cec5SDimitry Andric 
6700b57cec5SDimitry Andric     // Register the MC relocation info.
6710b57cec5SDimitry Andric     TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo);
6720b57cec5SDimitry Andric   }
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   // Register the MC instruction analyzer.
675fe6060f1SDimitry Andric   for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget(),
676fe6060f1SDimitry Andric                     &getTheThumbLETarget(), &getTheThumbBETarget()})
6770b57cec5SDimitry Andric     TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis);
6780b57cec5SDimitry Andric 
6790b57cec5SDimitry Andric   for (Target *T : {&getTheARMLETarget(), &getTheThumbLETarget()}) {
6800b57cec5SDimitry Andric     TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter);
6810b57cec5SDimitry Andric     TargetRegistry::RegisterMCAsmBackend(*T, createARMLEAsmBackend);
6820b57cec5SDimitry Andric   }
6830b57cec5SDimitry Andric   for (Target *T : {&getTheARMBETarget(), &getTheThumbBETarget()}) {
6840b57cec5SDimitry Andric     TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter);
6850b57cec5SDimitry Andric     TargetRegistry::RegisterMCAsmBackend(*T, createARMBEAsmBackend);
6860b57cec5SDimitry Andric   }
6870b57cec5SDimitry Andric }
688