xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
17330f729Sjoerg //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file provides ARM specific target descriptions.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg 
137330f729Sjoerg #include "ARMMCTargetDesc.h"
14*82d56013Sjoerg #include "ARMAddressingModes.h"
157330f729Sjoerg #include "ARMBaseInfo.h"
167330f729Sjoerg #include "ARMInstPrinter.h"
177330f729Sjoerg #include "ARMMCAsmInfo.h"
187330f729Sjoerg #include "TargetInfo/ARMTargetInfo.h"
197330f729Sjoerg #include "llvm/ADT/Triple.h"
20*82d56013Sjoerg #include "llvm/DebugInfo/CodeView/CodeView.h"
217330f729Sjoerg #include "llvm/MC/MCAsmBackend.h"
227330f729Sjoerg #include "llvm/MC/MCCodeEmitter.h"
237330f729Sjoerg #include "llvm/MC/MCELFStreamer.h"
247330f729Sjoerg #include "llvm/MC/MCInstrAnalysis.h"
257330f729Sjoerg #include "llvm/MC/MCInstrInfo.h"
267330f729Sjoerg #include "llvm/MC/MCObjectWriter.h"
277330f729Sjoerg #include "llvm/MC/MCRegisterInfo.h"
287330f729Sjoerg #include "llvm/MC/MCStreamer.h"
297330f729Sjoerg #include "llvm/MC/MCSubtargetInfo.h"
307330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
317330f729Sjoerg #include "llvm/Support/TargetParser.h"
327330f729Sjoerg #include "llvm/Support/TargetRegistry.h"
337330f729Sjoerg 
347330f729Sjoerg using namespace llvm;
357330f729Sjoerg 
367330f729Sjoerg #define GET_REGINFO_MC_DESC
377330f729Sjoerg #include "ARMGenRegisterInfo.inc"
387330f729Sjoerg 
getMCRDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)397330f729Sjoerg static bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
407330f729Sjoerg                                   std::string &Info) {
417330f729Sjoerg   if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
427330f729Sjoerg       (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
437330f729Sjoerg       (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
447330f729Sjoerg       // Checks for the deprecated CP15ISB encoding:
457330f729Sjoerg       // mcr p15, #0, rX, c7, c5, #4
467330f729Sjoerg       (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) {
477330f729Sjoerg     if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
487330f729Sjoerg       if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
497330f729Sjoerg         Info = "deprecated since v7, use 'isb'";
507330f729Sjoerg         return true;
517330f729Sjoerg       }
527330f729Sjoerg 
537330f729Sjoerg       // Checks for the deprecated CP15DSB encoding:
547330f729Sjoerg       // mcr p15, #0, rX, c7, c10, #4
557330f729Sjoerg       if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
567330f729Sjoerg         Info = "deprecated since v7, use 'dsb'";
577330f729Sjoerg         return true;
587330f729Sjoerg       }
597330f729Sjoerg     }
607330f729Sjoerg     // Checks for the deprecated CP15DMB encoding:
617330f729Sjoerg     // mcr p15, #0, rX, c7, c10, #5
627330f729Sjoerg     if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
637330f729Sjoerg         (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
647330f729Sjoerg       Info = "deprecated since v7, use 'dmb'";
657330f729Sjoerg       return true;
667330f729Sjoerg     }
677330f729Sjoerg   }
68*82d56013Sjoerg   if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
69*82d56013Sjoerg       ((MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 10) ||
70*82d56013Sjoerg        (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 11))) {
71*82d56013Sjoerg     Info = "since v7, cp10 and cp11 are reserved for advanced SIMD or floating "
72*82d56013Sjoerg            "point instructions";
73*82d56013Sjoerg     return true;
74*82d56013Sjoerg   }
75*82d56013Sjoerg   return false;
76*82d56013Sjoerg }
77*82d56013Sjoerg 
getMRCDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)78*82d56013Sjoerg static bool getMRCDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
79*82d56013Sjoerg                                   std::string &Info) {
80*82d56013Sjoerg   if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
81*82d56013Sjoerg       ((MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 10) ||
82*82d56013Sjoerg        (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 11))) {
83*82d56013Sjoerg     Info = "since v7, cp10 and cp11 are reserved for advanced SIMD or floating "
84*82d56013Sjoerg            "point instructions";
85*82d56013Sjoerg     return true;
86*82d56013Sjoerg   }
877330f729Sjoerg   return false;
887330f729Sjoerg }
897330f729Sjoerg 
getITDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)907330f729Sjoerg static bool getITDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
917330f729Sjoerg                                  std::string &Info) {
927330f729Sjoerg   if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && MI.getOperand(1).isImm() &&
937330f729Sjoerg       MI.getOperand(1).getImm() != 8) {
947330f729Sjoerg     Info = "applying IT instruction to more than one subsequent instruction is "
957330f729Sjoerg            "deprecated";
967330f729Sjoerg     return true;
977330f729Sjoerg   }
987330f729Sjoerg 
997330f729Sjoerg   return false;
1007330f729Sjoerg }
1017330f729Sjoerg 
getARMStoreDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)1027330f729Sjoerg static bool getARMStoreDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
1037330f729Sjoerg                                        std::string &Info) {
1047330f729Sjoerg   assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
1057330f729Sjoerg          "cannot predicate thumb instructions");
1067330f729Sjoerg 
1077330f729Sjoerg   assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
1087330f729Sjoerg   for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
1097330f729Sjoerg     assert(MI.getOperand(OI).isReg() && "expected register");
110*82d56013Sjoerg     if (MI.getOperand(OI).getReg() == ARM::PC) {
111*82d56013Sjoerg       Info = "use of PC in the list is deprecated";
1127330f729Sjoerg       return true;
1137330f729Sjoerg     }
1147330f729Sjoerg   }
1157330f729Sjoerg   return false;
1167330f729Sjoerg }
1177330f729Sjoerg 
getARMLoadDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)1187330f729Sjoerg static bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
1197330f729Sjoerg                                       std::string &Info) {
1207330f729Sjoerg   assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
1217330f729Sjoerg          "cannot predicate thumb instructions");
1227330f729Sjoerg 
1237330f729Sjoerg   assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
1247330f729Sjoerg   bool ListContainsPC = false, ListContainsLR = false;
1257330f729Sjoerg   for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
1267330f729Sjoerg     assert(MI.getOperand(OI).isReg() && "expected register");
1277330f729Sjoerg     switch (MI.getOperand(OI).getReg()) {
1287330f729Sjoerg     default:
1297330f729Sjoerg       break;
1307330f729Sjoerg     case ARM::LR:
1317330f729Sjoerg       ListContainsLR = true;
1327330f729Sjoerg       break;
1337330f729Sjoerg     case ARM::PC:
1347330f729Sjoerg       ListContainsPC = true;
1357330f729Sjoerg       break;
1367330f729Sjoerg     }
1377330f729Sjoerg   }
1387330f729Sjoerg 
1397330f729Sjoerg   if (ListContainsPC && ListContainsLR) {
1407330f729Sjoerg     Info = "use of LR and PC simultaneously in the list is deprecated";
1417330f729Sjoerg     return true;
1427330f729Sjoerg   }
1437330f729Sjoerg 
1447330f729Sjoerg   return false;
1457330f729Sjoerg }
1467330f729Sjoerg 
1477330f729Sjoerg #define GET_INSTRINFO_MC_DESC
1487330f729Sjoerg #include "ARMGenInstrInfo.inc"
1497330f729Sjoerg 
1507330f729Sjoerg #define GET_SUBTARGETINFO_MC_DESC
1517330f729Sjoerg #include "ARMGenSubtargetInfo.inc"
1527330f729Sjoerg 
ParseARMTriple(const Triple & TT,StringRef CPU)1537330f729Sjoerg std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
1547330f729Sjoerg   std::string ARMArchFeature;
1557330f729Sjoerg 
1567330f729Sjoerg   ARM::ArchKind ArchID = ARM::parseArch(TT.getArchName());
1577330f729Sjoerg   if (ArchID != ARM::ArchKind::INVALID &&  (CPU.empty() || CPU == "generic"))
1587330f729Sjoerg     ARMArchFeature = (ARMArchFeature + "+" + ARM::getArchName(ArchID)).str();
1597330f729Sjoerg 
1607330f729Sjoerg   if (TT.isThumb()) {
1617330f729Sjoerg     if (!ARMArchFeature.empty())
1627330f729Sjoerg       ARMArchFeature += ",";
1637330f729Sjoerg     ARMArchFeature += "+thumb-mode,+v4t";
1647330f729Sjoerg   }
1657330f729Sjoerg 
1667330f729Sjoerg   if (TT.isOSNaCl()) {
1677330f729Sjoerg     if (!ARMArchFeature.empty())
1687330f729Sjoerg       ARMArchFeature += ",";
1697330f729Sjoerg     ARMArchFeature += "+nacl-trap";
1707330f729Sjoerg   }
1717330f729Sjoerg 
1727330f729Sjoerg   if (TT.isOSWindows()) {
1737330f729Sjoerg     if (!ARMArchFeature.empty())
1747330f729Sjoerg       ARMArchFeature += ",";
1757330f729Sjoerg     ARMArchFeature += "+noarm";
1767330f729Sjoerg   }
1777330f729Sjoerg 
1787330f729Sjoerg   return ARMArchFeature;
1797330f729Sjoerg }
1807330f729Sjoerg 
isPredicated(const MCInst & MI,const MCInstrInfo * MCII)181*82d56013Sjoerg bool ARM_MC::isPredicated(const MCInst &MI, const MCInstrInfo *MCII) {
182*82d56013Sjoerg   const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
183*82d56013Sjoerg   int PredOpIdx = Desc.findFirstPredOperandIdx();
184*82d56013Sjoerg   return PredOpIdx != -1 && MI.getOperand(PredOpIdx).getImm() != ARMCC::AL;
185*82d56013Sjoerg }
186*82d56013Sjoerg 
isCPSRDefined(const MCInst & MI,const MCInstrInfo * MCII)187*82d56013Sjoerg bool ARM_MC::isCPSRDefined(const MCInst &MI, const MCInstrInfo *MCII) {
188*82d56013Sjoerg   const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
189*82d56013Sjoerg   for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
190*82d56013Sjoerg     const MCOperand &MO = MI.getOperand(I);
191*82d56013Sjoerg     if (MO.isReg() && MO.getReg() == ARM::CPSR &&
192*82d56013Sjoerg         Desc.OpInfo[I].isOptionalDef())
193*82d56013Sjoerg       return true;
194*82d56013Sjoerg   }
195*82d56013Sjoerg   return false;
196*82d56013Sjoerg }
197*82d56013Sjoerg 
createARMMCSubtargetInfo(const Triple & TT,StringRef CPU,StringRef FS)1987330f729Sjoerg MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT,
1997330f729Sjoerg                                                   StringRef CPU, StringRef FS) {
2007330f729Sjoerg   std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
2017330f729Sjoerg   if (!FS.empty()) {
2027330f729Sjoerg     if (!ArchFS.empty())
2037330f729Sjoerg       ArchFS = (Twine(ArchFS) + "," + FS).str();
2047330f729Sjoerg     else
205*82d56013Sjoerg       ArchFS = std::string(FS);
2067330f729Sjoerg   }
2077330f729Sjoerg 
208*82d56013Sjoerg   return createARMMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, ArchFS);
2097330f729Sjoerg }
2107330f729Sjoerg 
createARMMCInstrInfo()2117330f729Sjoerg static MCInstrInfo *createARMMCInstrInfo() {
2127330f729Sjoerg   MCInstrInfo *X = new MCInstrInfo();
2137330f729Sjoerg   InitARMMCInstrInfo(X);
2147330f729Sjoerg   return X;
2157330f729Sjoerg }
2167330f729Sjoerg 
initLLVMToCVRegMapping(MCRegisterInfo * MRI)217*82d56013Sjoerg void ARM_MC::initLLVMToCVRegMapping(MCRegisterInfo *MRI) {
218*82d56013Sjoerg   // Mapping from CodeView to MC register id.
219*82d56013Sjoerg   static const struct {
220*82d56013Sjoerg     codeview::RegisterId CVReg;
221*82d56013Sjoerg     MCPhysReg Reg;
222*82d56013Sjoerg   } RegMap[] = {
223*82d56013Sjoerg       {codeview::RegisterId::ARM_R0, ARM::R0},
224*82d56013Sjoerg       {codeview::RegisterId::ARM_R1, ARM::R1},
225*82d56013Sjoerg       {codeview::RegisterId::ARM_R2, ARM::R2},
226*82d56013Sjoerg       {codeview::RegisterId::ARM_R3, ARM::R3},
227*82d56013Sjoerg       {codeview::RegisterId::ARM_R4, ARM::R4},
228*82d56013Sjoerg       {codeview::RegisterId::ARM_R5, ARM::R5},
229*82d56013Sjoerg       {codeview::RegisterId::ARM_R6, ARM::R6},
230*82d56013Sjoerg       {codeview::RegisterId::ARM_R7, ARM::R7},
231*82d56013Sjoerg       {codeview::RegisterId::ARM_R8, ARM::R8},
232*82d56013Sjoerg       {codeview::RegisterId::ARM_R9, ARM::R9},
233*82d56013Sjoerg       {codeview::RegisterId::ARM_R10, ARM::R10},
234*82d56013Sjoerg       {codeview::RegisterId::ARM_R11, ARM::R11},
235*82d56013Sjoerg       {codeview::RegisterId::ARM_R12, ARM::R12},
236*82d56013Sjoerg       {codeview::RegisterId::ARM_SP, ARM::SP},
237*82d56013Sjoerg       {codeview::RegisterId::ARM_LR, ARM::LR},
238*82d56013Sjoerg       {codeview::RegisterId::ARM_PC, ARM::PC},
239*82d56013Sjoerg       {codeview::RegisterId::ARM_CPSR, ARM::CPSR},
240*82d56013Sjoerg       {codeview::RegisterId::ARM_FPSCR, ARM::FPSCR},
241*82d56013Sjoerg       {codeview::RegisterId::ARM_FPEXC, ARM::FPEXC},
242*82d56013Sjoerg       {codeview::RegisterId::ARM_FS0, ARM::S0},
243*82d56013Sjoerg       {codeview::RegisterId::ARM_FS1, ARM::S1},
244*82d56013Sjoerg       {codeview::RegisterId::ARM_FS2, ARM::S2},
245*82d56013Sjoerg       {codeview::RegisterId::ARM_FS3, ARM::S3},
246*82d56013Sjoerg       {codeview::RegisterId::ARM_FS4, ARM::S4},
247*82d56013Sjoerg       {codeview::RegisterId::ARM_FS5, ARM::S5},
248*82d56013Sjoerg       {codeview::RegisterId::ARM_FS6, ARM::S6},
249*82d56013Sjoerg       {codeview::RegisterId::ARM_FS7, ARM::S7},
250*82d56013Sjoerg       {codeview::RegisterId::ARM_FS8, ARM::S8},
251*82d56013Sjoerg       {codeview::RegisterId::ARM_FS9, ARM::S9},
252*82d56013Sjoerg       {codeview::RegisterId::ARM_FS10, ARM::S10},
253*82d56013Sjoerg       {codeview::RegisterId::ARM_FS11, ARM::S11},
254*82d56013Sjoerg       {codeview::RegisterId::ARM_FS12, ARM::S12},
255*82d56013Sjoerg       {codeview::RegisterId::ARM_FS13, ARM::S13},
256*82d56013Sjoerg       {codeview::RegisterId::ARM_FS14, ARM::S14},
257*82d56013Sjoerg       {codeview::RegisterId::ARM_FS15, ARM::S15},
258*82d56013Sjoerg       {codeview::RegisterId::ARM_FS16, ARM::S16},
259*82d56013Sjoerg       {codeview::RegisterId::ARM_FS17, ARM::S17},
260*82d56013Sjoerg       {codeview::RegisterId::ARM_FS18, ARM::S18},
261*82d56013Sjoerg       {codeview::RegisterId::ARM_FS19, ARM::S19},
262*82d56013Sjoerg       {codeview::RegisterId::ARM_FS20, ARM::S20},
263*82d56013Sjoerg       {codeview::RegisterId::ARM_FS21, ARM::S21},
264*82d56013Sjoerg       {codeview::RegisterId::ARM_FS22, ARM::S22},
265*82d56013Sjoerg       {codeview::RegisterId::ARM_FS23, ARM::S23},
266*82d56013Sjoerg       {codeview::RegisterId::ARM_FS24, ARM::S24},
267*82d56013Sjoerg       {codeview::RegisterId::ARM_FS25, ARM::S25},
268*82d56013Sjoerg       {codeview::RegisterId::ARM_FS26, ARM::S26},
269*82d56013Sjoerg       {codeview::RegisterId::ARM_FS27, ARM::S27},
270*82d56013Sjoerg       {codeview::RegisterId::ARM_FS28, ARM::S28},
271*82d56013Sjoerg       {codeview::RegisterId::ARM_FS29, ARM::S29},
272*82d56013Sjoerg       {codeview::RegisterId::ARM_FS30, ARM::S30},
273*82d56013Sjoerg       {codeview::RegisterId::ARM_FS31, ARM::S31},
274*82d56013Sjoerg       {codeview::RegisterId::ARM_ND0, ARM::D0},
275*82d56013Sjoerg       {codeview::RegisterId::ARM_ND1, ARM::D1},
276*82d56013Sjoerg       {codeview::RegisterId::ARM_ND2, ARM::D2},
277*82d56013Sjoerg       {codeview::RegisterId::ARM_ND3, ARM::D3},
278*82d56013Sjoerg       {codeview::RegisterId::ARM_ND4, ARM::D4},
279*82d56013Sjoerg       {codeview::RegisterId::ARM_ND5, ARM::D5},
280*82d56013Sjoerg       {codeview::RegisterId::ARM_ND6, ARM::D6},
281*82d56013Sjoerg       {codeview::RegisterId::ARM_ND7, ARM::D7},
282*82d56013Sjoerg       {codeview::RegisterId::ARM_ND8, ARM::D8},
283*82d56013Sjoerg       {codeview::RegisterId::ARM_ND9, ARM::D9},
284*82d56013Sjoerg       {codeview::RegisterId::ARM_ND10, ARM::D10},
285*82d56013Sjoerg       {codeview::RegisterId::ARM_ND11, ARM::D11},
286*82d56013Sjoerg       {codeview::RegisterId::ARM_ND12, ARM::D12},
287*82d56013Sjoerg       {codeview::RegisterId::ARM_ND13, ARM::D13},
288*82d56013Sjoerg       {codeview::RegisterId::ARM_ND14, ARM::D14},
289*82d56013Sjoerg       {codeview::RegisterId::ARM_ND15, ARM::D15},
290*82d56013Sjoerg       {codeview::RegisterId::ARM_ND16, ARM::D16},
291*82d56013Sjoerg       {codeview::RegisterId::ARM_ND17, ARM::D17},
292*82d56013Sjoerg       {codeview::RegisterId::ARM_ND18, ARM::D18},
293*82d56013Sjoerg       {codeview::RegisterId::ARM_ND19, ARM::D19},
294*82d56013Sjoerg       {codeview::RegisterId::ARM_ND20, ARM::D20},
295*82d56013Sjoerg       {codeview::RegisterId::ARM_ND21, ARM::D21},
296*82d56013Sjoerg       {codeview::RegisterId::ARM_ND22, ARM::D22},
297*82d56013Sjoerg       {codeview::RegisterId::ARM_ND23, ARM::D23},
298*82d56013Sjoerg       {codeview::RegisterId::ARM_ND24, ARM::D24},
299*82d56013Sjoerg       {codeview::RegisterId::ARM_ND25, ARM::D25},
300*82d56013Sjoerg       {codeview::RegisterId::ARM_ND26, ARM::D26},
301*82d56013Sjoerg       {codeview::RegisterId::ARM_ND27, ARM::D27},
302*82d56013Sjoerg       {codeview::RegisterId::ARM_ND28, ARM::D28},
303*82d56013Sjoerg       {codeview::RegisterId::ARM_ND29, ARM::D29},
304*82d56013Sjoerg       {codeview::RegisterId::ARM_ND30, ARM::D30},
305*82d56013Sjoerg       {codeview::RegisterId::ARM_ND31, ARM::D31},
306*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ0, ARM::Q0},
307*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ1, ARM::Q1},
308*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ2, ARM::Q2},
309*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ3, ARM::Q3},
310*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ4, ARM::Q4},
311*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ5, ARM::Q5},
312*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ6, ARM::Q6},
313*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ7, ARM::Q7},
314*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ8, ARM::Q8},
315*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ9, ARM::Q9},
316*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ10, ARM::Q10},
317*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ11, ARM::Q11},
318*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ12, ARM::Q12},
319*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ13, ARM::Q13},
320*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ14, ARM::Q14},
321*82d56013Sjoerg       {codeview::RegisterId::ARM_NQ15, ARM::Q15},
322*82d56013Sjoerg   };
323*82d56013Sjoerg   for (unsigned I = 0; I < array_lengthof(RegMap); ++I)
324*82d56013Sjoerg     MRI->mapLLVMRegToCVReg(RegMap[I].Reg, static_cast<int>(RegMap[I].CVReg));
325*82d56013Sjoerg }
326*82d56013Sjoerg 
createARMMCRegisterInfo(const Triple & Triple)3277330f729Sjoerg static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) {
3287330f729Sjoerg   MCRegisterInfo *X = new MCRegisterInfo();
3297330f729Sjoerg   InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
330*82d56013Sjoerg   ARM_MC::initLLVMToCVRegMapping(X);
3317330f729Sjoerg   return X;
3327330f729Sjoerg }
3337330f729Sjoerg 
createARMMCAsmInfo(const MCRegisterInfo & MRI,const Triple & TheTriple,const MCTargetOptions & Options)3347330f729Sjoerg static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI,
3357330f729Sjoerg                                      const Triple &TheTriple,
3367330f729Sjoerg                                      const MCTargetOptions &Options) {
3377330f729Sjoerg   MCAsmInfo *MAI;
3387330f729Sjoerg   if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO())
3397330f729Sjoerg     MAI = new ARMMCAsmInfoDarwin(TheTriple);
3407330f729Sjoerg   else if (TheTriple.isWindowsMSVCEnvironment())
3417330f729Sjoerg     MAI = new ARMCOFFMCAsmInfoMicrosoft();
3427330f729Sjoerg   else if (TheTriple.isOSWindows())
3437330f729Sjoerg     MAI = new ARMCOFFMCAsmInfoGNU();
3447330f729Sjoerg   else
3457330f729Sjoerg     MAI = new ARMELFMCAsmInfo(TheTriple);
3467330f729Sjoerg 
3477330f729Sjoerg   unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
348*82d56013Sjoerg   MAI->addInitialFrameState(MCCFIInstruction::cfiDefCfa(nullptr, Reg, 0));
3497330f729Sjoerg 
3507330f729Sjoerg   return MAI;
3517330f729Sjoerg }
3527330f729Sjoerg 
createELFStreamer(const Triple & T,MCContext & Ctx,std::unique_ptr<MCAsmBackend> && MAB,std::unique_ptr<MCObjectWriter> && OW,std::unique_ptr<MCCodeEmitter> && Emitter,bool RelaxAll)3537330f729Sjoerg static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
3547330f729Sjoerg                                      std::unique_ptr<MCAsmBackend> &&MAB,
3557330f729Sjoerg                                      std::unique_ptr<MCObjectWriter> &&OW,
3567330f729Sjoerg                                      std::unique_ptr<MCCodeEmitter> &&Emitter,
3577330f729Sjoerg                                      bool RelaxAll) {
3587330f729Sjoerg   return createARMELFStreamer(
3597330f729Sjoerg       Ctx, std::move(MAB), std::move(OW), std::move(Emitter), false,
360*82d56013Sjoerg       (T.getArch() == Triple::thumb || T.getArch() == Triple::thumbeb),
361*82d56013Sjoerg       T.isAndroid());
3627330f729Sjoerg }
3637330f729Sjoerg 
3647330f729Sjoerg static MCStreamer *
createARMMachOStreamer(MCContext & Ctx,std::unique_ptr<MCAsmBackend> && MAB,std::unique_ptr<MCObjectWriter> && OW,std::unique_ptr<MCCodeEmitter> && Emitter,bool RelaxAll,bool DWARFMustBeAtTheEnd)3657330f729Sjoerg createARMMachOStreamer(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&MAB,
3667330f729Sjoerg                        std::unique_ptr<MCObjectWriter> &&OW,
3677330f729Sjoerg                        std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
3687330f729Sjoerg                        bool DWARFMustBeAtTheEnd) {
3697330f729Sjoerg   return createMachOStreamer(Ctx, std::move(MAB), std::move(OW),
3707330f729Sjoerg                              std::move(Emitter), false, DWARFMustBeAtTheEnd);
3717330f729Sjoerg }
3727330f729Sjoerg 
createARMMCInstPrinter(const Triple & T,unsigned SyntaxVariant,const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)3737330f729Sjoerg static MCInstPrinter *createARMMCInstPrinter(const Triple &T,
3747330f729Sjoerg                                              unsigned SyntaxVariant,
3757330f729Sjoerg                                              const MCAsmInfo &MAI,
3767330f729Sjoerg                                              const MCInstrInfo &MII,
3777330f729Sjoerg                                              const MCRegisterInfo &MRI) {
3787330f729Sjoerg   if (SyntaxVariant == 0)
3797330f729Sjoerg     return new ARMInstPrinter(MAI, MII, MRI);
3807330f729Sjoerg   return nullptr;
3817330f729Sjoerg }
3827330f729Sjoerg 
createARMMCRelocationInfo(const Triple & TT,MCContext & Ctx)3837330f729Sjoerg static MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT,
3847330f729Sjoerg                                                    MCContext &Ctx) {
3857330f729Sjoerg   if (TT.isOSBinFormatMachO())
3867330f729Sjoerg     return createARMMachORelocationInfo(Ctx);
3877330f729Sjoerg   // Default to the stock relocation info.
3887330f729Sjoerg   return llvm::createMCRelocationInfo(TT, Ctx);
3897330f729Sjoerg }
3907330f729Sjoerg 
3917330f729Sjoerg namespace {
3927330f729Sjoerg 
3937330f729Sjoerg class ARMMCInstrAnalysis : public MCInstrAnalysis {
3947330f729Sjoerg public:
ARMMCInstrAnalysis(const MCInstrInfo * Info)3957330f729Sjoerg   ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
3967330f729Sjoerg 
isUnconditionalBranch(const MCInst & Inst) const3977330f729Sjoerg   bool isUnconditionalBranch(const MCInst &Inst) const override {
3987330f729Sjoerg     // BCCs with the "always" predicate are unconditional branches.
3997330f729Sjoerg     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
4007330f729Sjoerg       return true;
4017330f729Sjoerg     return MCInstrAnalysis::isUnconditionalBranch(Inst);
4027330f729Sjoerg   }
4037330f729Sjoerg 
isConditionalBranch(const MCInst & Inst) const4047330f729Sjoerg   bool isConditionalBranch(const MCInst &Inst) const override {
4057330f729Sjoerg     // BCCs with the "always" predicate are unconditional branches.
4067330f729Sjoerg     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
4077330f729Sjoerg       return false;
4087330f729Sjoerg     return MCInstrAnalysis::isConditionalBranch(Inst);
4097330f729Sjoerg   }
4107330f729Sjoerg 
evaluateBranch(const MCInst & Inst,uint64_t Addr,uint64_t Size,uint64_t & Target) const4117330f729Sjoerg   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
4127330f729Sjoerg                       uint64_t &Target) const override {
413*82d56013Sjoerg     const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
4147330f729Sjoerg 
415*82d56013Sjoerg     // Find the PC-relative immediate operand in the instruction.
416*82d56013Sjoerg     bool FoundImm = false;
417*82d56013Sjoerg     int64_t Imm;
418*82d56013Sjoerg     for (unsigned OpNum = 0; OpNum < Desc.getNumOperands(); ++OpNum) {
419*82d56013Sjoerg       if (Inst.getOperand(OpNum).isImm() &&
420*82d56013Sjoerg           Desc.OpInfo[OpNum].OperandType == MCOI::OPERAND_PCREL) {
421*82d56013Sjoerg         Imm = Inst.getOperand(OpNum).getImm();
422*82d56013Sjoerg         FoundImm = true;
423*82d56013Sjoerg       }
424*82d56013Sjoerg     }
425*82d56013Sjoerg     if (!FoundImm)
4267330f729Sjoerg       return false;
4277330f729Sjoerg 
428*82d56013Sjoerg     // For ARM instructions the PC offset is 8 bytes, for Thumb instructions it
429*82d56013Sjoerg     // is 4 bytes.
430*82d56013Sjoerg     uint64_t Offset = ((Desc.TSFlags & ARMII::FormMask) == ARMII::ThumbFrm) ? 4 : 8;
431*82d56013Sjoerg 
432*82d56013Sjoerg     Target = Addr + Imm + Offset;
4337330f729Sjoerg     return true;
4347330f729Sjoerg   }
4357330f729Sjoerg };
4367330f729Sjoerg 
4377330f729Sjoerg }
4387330f729Sjoerg 
createARMMCInstrAnalysis(const MCInstrInfo * Info)4397330f729Sjoerg static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) {
4407330f729Sjoerg   return new ARMMCInstrAnalysis(Info);
4417330f729Sjoerg }
4427330f729Sjoerg 
isCDECoproc(size_t Coproc,const MCSubtargetInfo & STI)443*82d56013Sjoerg bool ARM::isCDECoproc(size_t Coproc, const MCSubtargetInfo &STI) {
444*82d56013Sjoerg   // Unfortunately we don't have ARMTargetInfo in the disassembler, so we have
445*82d56013Sjoerg   // to rely on feature bits.
446*82d56013Sjoerg   if (Coproc >= 8)
447*82d56013Sjoerg     return false;
448*82d56013Sjoerg   return STI.getFeatureBits()[ARM::FeatureCoprocCDE0 + Coproc];
4497330f729Sjoerg }
4507330f729Sjoerg 
4517330f729Sjoerg // Force static initialization.
LLVMInitializeARMTargetMC()452*82d56013Sjoerg extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMTargetMC() {
4537330f729Sjoerg   for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget(),
4547330f729Sjoerg                     &getTheThumbLETarget(), &getTheThumbBETarget()}) {
4557330f729Sjoerg     // Register the MC asm info.
4567330f729Sjoerg     RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo);
4577330f729Sjoerg 
4587330f729Sjoerg     // Register the MC instruction info.
4597330f729Sjoerg     TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo);
4607330f729Sjoerg 
4617330f729Sjoerg     // Register the MC register info.
4627330f729Sjoerg     TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo);
4637330f729Sjoerg 
4647330f729Sjoerg     // Register the MC subtarget info.
4657330f729Sjoerg     TargetRegistry::RegisterMCSubtargetInfo(*T,
4667330f729Sjoerg                                             ARM_MC::createARMMCSubtargetInfo);
4677330f729Sjoerg 
4687330f729Sjoerg     TargetRegistry::RegisterELFStreamer(*T, createELFStreamer);
4697330f729Sjoerg     TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer);
4707330f729Sjoerg     TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer);
4717330f729Sjoerg 
4727330f729Sjoerg     // Register the obj target streamer.
4737330f729Sjoerg     TargetRegistry::RegisterObjectTargetStreamer(*T,
4747330f729Sjoerg                                                  createARMObjectTargetStreamer);
4757330f729Sjoerg 
4767330f729Sjoerg     // Register the asm streamer.
4777330f729Sjoerg     TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer);
4787330f729Sjoerg 
4797330f729Sjoerg     // Register the null TargetStreamer.
4807330f729Sjoerg     TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer);
4817330f729Sjoerg 
4827330f729Sjoerg     // Register the MCInstPrinter.
4837330f729Sjoerg     TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter);
4847330f729Sjoerg 
4857330f729Sjoerg     // Register the MC relocation info.
4867330f729Sjoerg     TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo);
4877330f729Sjoerg   }
4887330f729Sjoerg 
4897330f729Sjoerg   // Register the MC instruction analyzer.
490*82d56013Sjoerg   for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget(),
491*82d56013Sjoerg                     &getTheThumbLETarget(), &getTheThumbBETarget()})
4927330f729Sjoerg     TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis);
4937330f729Sjoerg 
4947330f729Sjoerg   for (Target *T : {&getTheARMLETarget(), &getTheThumbLETarget()}) {
4957330f729Sjoerg     TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter);
4967330f729Sjoerg     TargetRegistry::RegisterMCAsmBackend(*T, createARMLEAsmBackend);
4977330f729Sjoerg   }
4987330f729Sjoerg   for (Target *T : {&getTheARMBETarget(), &getTheThumbBETarget()}) {
4997330f729Sjoerg     TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter);
5007330f729Sjoerg     TargetRegistry::RegisterMCAsmBackend(*T, createARMBEAsmBackend);
5017330f729Sjoerg   }
5027330f729Sjoerg }
503