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