xref: /aosp_15_r20/external/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file provides ARM specific target descriptions.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "ARMBaseInfo.h"
15*9880d681SAndroid Build Coastguard Worker #include "ARMMCAsmInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "ARMMCTargetDesc.h"
17*9880d681SAndroid Build Coastguard Worker #include "InstPrinter/ARMInstPrinter.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCELFStreamer.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrAnalysis.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetParser.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker using namespace llvm;
30*9880d681SAndroid Build Coastguard Worker 
31*9880d681SAndroid Build Coastguard Worker #define GET_REGINFO_MC_DESC
32*9880d681SAndroid Build Coastguard Worker #include "ARMGenRegisterInfo.inc"
33*9880d681SAndroid Build Coastguard Worker 
getMCRDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)34*9880d681SAndroid Build Coastguard Worker static bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
35*9880d681SAndroid Build Coastguard Worker                                   std::string &Info) {
36*9880d681SAndroid Build Coastguard Worker   if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
37*9880d681SAndroid Build Coastguard Worker       (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
38*9880d681SAndroid Build Coastguard Worker       (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
39*9880d681SAndroid Build Coastguard Worker       // Checks for the deprecated CP15ISB encoding:
40*9880d681SAndroid Build Coastguard Worker       // mcr p15, #0, rX, c7, c5, #4
41*9880d681SAndroid Build Coastguard Worker       (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) {
42*9880d681SAndroid Build Coastguard Worker     if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
43*9880d681SAndroid Build Coastguard Worker       if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
44*9880d681SAndroid Build Coastguard Worker         Info = "deprecated since v7, use 'isb'";
45*9880d681SAndroid Build Coastguard Worker         return true;
46*9880d681SAndroid Build Coastguard Worker       }
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker       // Checks for the deprecated CP15DSB encoding:
49*9880d681SAndroid Build Coastguard Worker       // mcr p15, #0, rX, c7, c10, #4
50*9880d681SAndroid Build Coastguard Worker       if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
51*9880d681SAndroid Build Coastguard Worker         Info = "deprecated since v7, use 'dsb'";
52*9880d681SAndroid Build Coastguard Worker         return true;
53*9880d681SAndroid Build Coastguard Worker       }
54*9880d681SAndroid Build Coastguard Worker     }
55*9880d681SAndroid Build Coastguard Worker     // Checks for the deprecated CP15DMB encoding:
56*9880d681SAndroid Build Coastguard Worker     // mcr p15, #0, rX, c7, c10, #5
57*9880d681SAndroid Build Coastguard Worker     if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
58*9880d681SAndroid Build Coastguard Worker         (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
59*9880d681SAndroid Build Coastguard Worker       Info = "deprecated since v7, use 'dmb'";
60*9880d681SAndroid Build Coastguard Worker       return true;
61*9880d681SAndroid Build Coastguard Worker     }
62*9880d681SAndroid Build Coastguard Worker   }
63*9880d681SAndroid Build Coastguard Worker   return false;
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker 
getITDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)66*9880d681SAndroid Build Coastguard Worker static bool getITDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
67*9880d681SAndroid Build Coastguard Worker                                  std::string &Info) {
68*9880d681SAndroid Build Coastguard Worker   if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && MI.getOperand(1).isImm() &&
69*9880d681SAndroid Build Coastguard Worker       MI.getOperand(1).getImm() != 8) {
70*9880d681SAndroid Build Coastguard Worker     Info = "applying IT instruction to more than one subsequent instruction is "
71*9880d681SAndroid Build Coastguard Worker            "deprecated";
72*9880d681SAndroid Build Coastguard Worker     return true;
73*9880d681SAndroid Build Coastguard Worker   }
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker   return false;
76*9880d681SAndroid Build Coastguard Worker }
77*9880d681SAndroid Build Coastguard Worker 
getARMStoreDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)78*9880d681SAndroid Build Coastguard Worker static bool getARMStoreDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
79*9880d681SAndroid Build Coastguard Worker                                        std::string &Info) {
80*9880d681SAndroid Build Coastguard Worker   assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
81*9880d681SAndroid Build Coastguard Worker          "cannot predicate thumb instructions");
82*9880d681SAndroid Build Coastguard Worker 
83*9880d681SAndroid Build Coastguard Worker   assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
84*9880d681SAndroid Build Coastguard Worker   for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
85*9880d681SAndroid Build Coastguard Worker     assert(MI.getOperand(OI).isReg() && "expected register");
86*9880d681SAndroid Build Coastguard Worker     if (MI.getOperand(OI).getReg() == ARM::SP ||
87*9880d681SAndroid Build Coastguard Worker         MI.getOperand(OI).getReg() == ARM::PC) {
88*9880d681SAndroid Build Coastguard Worker       Info = "use of SP or PC in the list is deprecated";
89*9880d681SAndroid Build Coastguard Worker       return true;
90*9880d681SAndroid Build Coastguard Worker     }
91*9880d681SAndroid Build Coastguard Worker   }
92*9880d681SAndroid Build Coastguard Worker   return false;
93*9880d681SAndroid Build Coastguard Worker }
94*9880d681SAndroid Build Coastguard Worker 
getARMLoadDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)95*9880d681SAndroid Build Coastguard Worker static bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
96*9880d681SAndroid Build Coastguard Worker                                       std::string &Info) {
97*9880d681SAndroid Build Coastguard Worker   assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
98*9880d681SAndroid Build Coastguard Worker          "cannot predicate thumb instructions");
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker   assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
101*9880d681SAndroid Build Coastguard Worker   bool ListContainsPC = false, ListContainsLR = false;
102*9880d681SAndroid Build Coastguard Worker   for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
103*9880d681SAndroid Build Coastguard Worker     assert(MI.getOperand(OI).isReg() && "expected register");
104*9880d681SAndroid Build Coastguard Worker     switch (MI.getOperand(OI).getReg()) {
105*9880d681SAndroid Build Coastguard Worker     default:
106*9880d681SAndroid Build Coastguard Worker       break;
107*9880d681SAndroid Build Coastguard Worker     case ARM::LR:
108*9880d681SAndroid Build Coastguard Worker       ListContainsLR = true;
109*9880d681SAndroid Build Coastguard Worker       break;
110*9880d681SAndroid Build Coastguard Worker     case ARM::PC:
111*9880d681SAndroid Build Coastguard Worker       ListContainsPC = true;
112*9880d681SAndroid Build Coastguard Worker       break;
113*9880d681SAndroid Build Coastguard Worker     case ARM::SP:
114*9880d681SAndroid Build Coastguard Worker       Info = "use of SP in the list is deprecated";
115*9880d681SAndroid Build Coastguard Worker       return true;
116*9880d681SAndroid Build Coastguard Worker     }
117*9880d681SAndroid Build Coastguard Worker   }
118*9880d681SAndroid Build Coastguard Worker 
119*9880d681SAndroid Build Coastguard Worker   if (ListContainsPC && ListContainsLR) {
120*9880d681SAndroid Build Coastguard Worker     Info = "use of LR and PC simultaneously in the list is deprecated";
121*9880d681SAndroid Build Coastguard Worker     return true;
122*9880d681SAndroid Build Coastguard Worker   }
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker   return false;
125*9880d681SAndroid Build Coastguard Worker }
126*9880d681SAndroid Build Coastguard Worker 
127*9880d681SAndroid Build Coastguard Worker #define GET_INSTRINFO_MC_DESC
128*9880d681SAndroid Build Coastguard Worker #include "ARMGenInstrInfo.inc"
129*9880d681SAndroid Build Coastguard Worker 
130*9880d681SAndroid Build Coastguard Worker #define GET_SUBTARGETINFO_MC_DESC
131*9880d681SAndroid Build Coastguard Worker #include "ARMGenSubtargetInfo.inc"
132*9880d681SAndroid Build Coastguard Worker 
ParseARMTriple(const Triple & TT,StringRef CPU)133*9880d681SAndroid Build Coastguard Worker std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
134*9880d681SAndroid Build Coastguard Worker   bool isThumb =
135*9880d681SAndroid Build Coastguard Worker       TT.getArch() == Triple::thumb || TT.getArch() == Triple::thumbeb;
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker   std::string ARMArchFeature;
138*9880d681SAndroid Build Coastguard Worker 
139*9880d681SAndroid Build Coastguard Worker   unsigned ArchID = ARM::parseArch(TT.getArchName());
140*9880d681SAndroid Build Coastguard Worker   if (ArchID != ARM::AK_INVALID &&  (CPU.empty() || CPU == "generic"))
141*9880d681SAndroid Build Coastguard Worker     ARMArchFeature = (ARMArchFeature + "+" + ARM::getArchName(ArchID)).str();
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker   if (isThumb) {
144*9880d681SAndroid Build Coastguard Worker     if (ARMArchFeature.empty())
145*9880d681SAndroid Build Coastguard Worker       ARMArchFeature = "+thumb-mode";
146*9880d681SAndroid Build Coastguard Worker     else
147*9880d681SAndroid Build Coastguard Worker       ARMArchFeature += ",+thumb-mode";
148*9880d681SAndroid Build Coastguard Worker   }
149*9880d681SAndroid Build Coastguard Worker 
150*9880d681SAndroid Build Coastguard Worker   if (TT.isOSNaCl()) {
151*9880d681SAndroid Build Coastguard Worker     if (ARMArchFeature.empty())
152*9880d681SAndroid Build Coastguard Worker       ARMArchFeature = "+nacl-trap";
153*9880d681SAndroid Build Coastguard Worker     else
154*9880d681SAndroid Build Coastguard Worker       ARMArchFeature += ",+nacl-trap";
155*9880d681SAndroid Build Coastguard Worker   }
156*9880d681SAndroid Build Coastguard Worker 
157*9880d681SAndroid Build Coastguard Worker   return ARMArchFeature;
158*9880d681SAndroid Build Coastguard Worker }
159*9880d681SAndroid Build Coastguard Worker 
createARMMCSubtargetInfo(const Triple & TT,StringRef CPU,StringRef FS)160*9880d681SAndroid Build Coastguard Worker MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT,
161*9880d681SAndroid Build Coastguard Worker                                                   StringRef CPU, StringRef FS) {
162*9880d681SAndroid Build Coastguard Worker   std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
163*9880d681SAndroid Build Coastguard Worker   if (!FS.empty()) {
164*9880d681SAndroid Build Coastguard Worker     if (!ArchFS.empty())
165*9880d681SAndroid Build Coastguard Worker       ArchFS = (Twine(ArchFS) + "," + FS).str();
166*9880d681SAndroid Build Coastguard Worker     else
167*9880d681SAndroid Build Coastguard Worker       ArchFS = FS;
168*9880d681SAndroid Build Coastguard Worker   }
169*9880d681SAndroid Build Coastguard Worker 
170*9880d681SAndroid Build Coastguard Worker   return createARMMCSubtargetInfoImpl(TT, CPU, ArchFS);
171*9880d681SAndroid Build Coastguard Worker }
172*9880d681SAndroid Build Coastguard Worker 
createARMMCInstrInfo()173*9880d681SAndroid Build Coastguard Worker static MCInstrInfo *createARMMCInstrInfo() {
174*9880d681SAndroid Build Coastguard Worker   MCInstrInfo *X = new MCInstrInfo();
175*9880d681SAndroid Build Coastguard Worker   InitARMMCInstrInfo(X);
176*9880d681SAndroid Build Coastguard Worker   return X;
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker 
createARMMCRegisterInfo(const Triple & Triple)179*9880d681SAndroid Build Coastguard Worker static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) {
180*9880d681SAndroid Build Coastguard Worker   MCRegisterInfo *X = new MCRegisterInfo();
181*9880d681SAndroid Build Coastguard Worker   InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
182*9880d681SAndroid Build Coastguard Worker   return X;
183*9880d681SAndroid Build Coastguard Worker }
184*9880d681SAndroid Build Coastguard Worker 
createARMMCAsmInfo(const MCRegisterInfo & MRI,const Triple & TheTriple)185*9880d681SAndroid Build Coastguard Worker static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI,
186*9880d681SAndroid Build Coastguard Worker                                      const Triple &TheTriple) {
187*9880d681SAndroid Build Coastguard Worker   MCAsmInfo *MAI;
188*9880d681SAndroid Build Coastguard Worker   if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO())
189*9880d681SAndroid Build Coastguard Worker     MAI = new ARMMCAsmInfoDarwin(TheTriple);
190*9880d681SAndroid Build Coastguard Worker   else if (TheTriple.isWindowsMSVCEnvironment())
191*9880d681SAndroid Build Coastguard Worker     MAI = new ARMCOFFMCAsmInfoMicrosoft();
192*9880d681SAndroid Build Coastguard Worker   else if (TheTriple.isOSWindows())
193*9880d681SAndroid Build Coastguard Worker     MAI = new ARMCOFFMCAsmInfoGNU();
194*9880d681SAndroid Build Coastguard Worker   else
195*9880d681SAndroid Build Coastguard Worker     MAI = new ARMELFMCAsmInfo(TheTriple);
196*9880d681SAndroid Build Coastguard Worker 
197*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
198*9880d681SAndroid Build Coastguard Worker   MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0));
199*9880d681SAndroid Build Coastguard Worker 
200*9880d681SAndroid Build Coastguard Worker   return MAI;
201*9880d681SAndroid Build Coastguard Worker }
202*9880d681SAndroid Build Coastguard Worker 
createELFStreamer(const Triple & T,MCContext & Ctx,MCAsmBackend & MAB,raw_pwrite_stream & OS,MCCodeEmitter * Emitter,bool RelaxAll)203*9880d681SAndroid Build Coastguard Worker static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
204*9880d681SAndroid Build Coastguard Worker                                      MCAsmBackend &MAB, raw_pwrite_stream &OS,
205*9880d681SAndroid Build Coastguard Worker                                      MCCodeEmitter *Emitter, bool RelaxAll) {
206*9880d681SAndroid Build Coastguard Worker   return createARMELFStreamer(Ctx, MAB, OS, Emitter, false,
207*9880d681SAndroid Build Coastguard Worker                               T.getArch() == Triple::thumb);
208*9880d681SAndroid Build Coastguard Worker }
209*9880d681SAndroid Build Coastguard Worker 
createARMMachOStreamer(MCContext & Ctx,MCAsmBackend & MAB,raw_pwrite_stream & OS,MCCodeEmitter * Emitter,bool RelaxAll,bool DWARFMustBeAtTheEnd)210*9880d681SAndroid Build Coastguard Worker static MCStreamer *createARMMachOStreamer(MCContext &Ctx, MCAsmBackend &MAB,
211*9880d681SAndroid Build Coastguard Worker                                           raw_pwrite_stream &OS,
212*9880d681SAndroid Build Coastguard Worker                                           MCCodeEmitter *Emitter, bool RelaxAll,
213*9880d681SAndroid Build Coastguard Worker                                           bool DWARFMustBeAtTheEnd) {
214*9880d681SAndroid Build Coastguard Worker   return createMachOStreamer(Ctx, MAB, OS, Emitter, false, DWARFMustBeAtTheEnd);
215*9880d681SAndroid Build Coastguard Worker }
216*9880d681SAndroid Build Coastguard Worker 
createARMMCInstPrinter(const Triple & T,unsigned SyntaxVariant,const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)217*9880d681SAndroid Build Coastguard Worker static MCInstPrinter *createARMMCInstPrinter(const Triple &T,
218*9880d681SAndroid Build Coastguard Worker                                              unsigned SyntaxVariant,
219*9880d681SAndroid Build Coastguard Worker                                              const MCAsmInfo &MAI,
220*9880d681SAndroid Build Coastguard Worker                                              const MCInstrInfo &MII,
221*9880d681SAndroid Build Coastguard Worker                                              const MCRegisterInfo &MRI) {
222*9880d681SAndroid Build Coastguard Worker   if (SyntaxVariant == 0)
223*9880d681SAndroid Build Coastguard Worker     return new ARMInstPrinter(MAI, MII, MRI);
224*9880d681SAndroid Build Coastguard Worker   return nullptr;
225*9880d681SAndroid Build Coastguard Worker }
226*9880d681SAndroid Build Coastguard Worker 
createARMMCRelocationInfo(const Triple & TT,MCContext & Ctx)227*9880d681SAndroid Build Coastguard Worker static MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT,
228*9880d681SAndroid Build Coastguard Worker                                                    MCContext &Ctx) {
229*9880d681SAndroid Build Coastguard Worker   if (TT.isOSBinFormatMachO())
230*9880d681SAndroid Build Coastguard Worker     return createARMMachORelocationInfo(Ctx);
231*9880d681SAndroid Build Coastguard Worker   // Default to the stock relocation info.
232*9880d681SAndroid Build Coastguard Worker   return llvm::createMCRelocationInfo(TT, Ctx);
233*9880d681SAndroid Build Coastguard Worker }
234*9880d681SAndroid Build Coastguard Worker 
235*9880d681SAndroid Build Coastguard Worker namespace {
236*9880d681SAndroid Build Coastguard Worker 
237*9880d681SAndroid Build Coastguard Worker class ARMMCInstrAnalysis : public MCInstrAnalysis {
238*9880d681SAndroid Build Coastguard Worker public:
ARMMCInstrAnalysis(const MCInstrInfo * Info)239*9880d681SAndroid Build Coastguard Worker   ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
240*9880d681SAndroid Build Coastguard Worker 
isUnconditionalBranch(const MCInst & Inst) const241*9880d681SAndroid Build Coastguard Worker   bool isUnconditionalBranch(const MCInst &Inst) const override {
242*9880d681SAndroid Build Coastguard Worker     // BCCs with the "always" predicate are unconditional branches.
243*9880d681SAndroid Build Coastguard Worker     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
244*9880d681SAndroid Build Coastguard Worker       return true;
245*9880d681SAndroid Build Coastguard Worker     return MCInstrAnalysis::isUnconditionalBranch(Inst);
246*9880d681SAndroid Build Coastguard Worker   }
247*9880d681SAndroid Build Coastguard Worker 
isConditionalBranch(const MCInst & Inst) const248*9880d681SAndroid Build Coastguard Worker   bool isConditionalBranch(const MCInst &Inst) const override {
249*9880d681SAndroid Build Coastguard Worker     // BCCs with the "always" predicate are unconditional branches.
250*9880d681SAndroid Build Coastguard Worker     if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
251*9880d681SAndroid Build Coastguard Worker       return false;
252*9880d681SAndroid Build Coastguard Worker     return MCInstrAnalysis::isConditionalBranch(Inst);
253*9880d681SAndroid Build Coastguard Worker   }
254*9880d681SAndroid Build Coastguard Worker 
evaluateBranch(const MCInst & Inst,uint64_t Addr,uint64_t Size,uint64_t & Target) const255*9880d681SAndroid Build Coastguard Worker   bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
256*9880d681SAndroid Build Coastguard Worker                       uint64_t Size, uint64_t &Target) const override {
257*9880d681SAndroid Build Coastguard Worker     // We only handle PCRel branches for now.
258*9880d681SAndroid Build Coastguard Worker     if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL)
259*9880d681SAndroid Build Coastguard Worker       return false;
260*9880d681SAndroid Build Coastguard Worker 
261*9880d681SAndroid Build Coastguard Worker     int64_t Imm = Inst.getOperand(0).getImm();
262*9880d681SAndroid Build Coastguard Worker     // FIXME: This is not right for thumb.
263*9880d681SAndroid Build Coastguard Worker     Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes.
264*9880d681SAndroid Build Coastguard Worker     return true;
265*9880d681SAndroid Build Coastguard Worker   }
266*9880d681SAndroid Build Coastguard Worker };
267*9880d681SAndroid Build Coastguard Worker 
268*9880d681SAndroid Build Coastguard Worker }
269*9880d681SAndroid Build Coastguard Worker 
createARMMCInstrAnalysis(const MCInstrInfo * Info)270*9880d681SAndroid Build Coastguard Worker static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) {
271*9880d681SAndroid Build Coastguard Worker   return new ARMMCInstrAnalysis(Info);
272*9880d681SAndroid Build Coastguard Worker }
273*9880d681SAndroid Build Coastguard Worker 
274*9880d681SAndroid Build Coastguard Worker // Force static initialization.
LLVMInitializeARMTargetMC()275*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializeARMTargetMC() {
276*9880d681SAndroid Build Coastguard Worker   for (Target *T : {&TheARMLETarget, &TheARMBETarget, &TheThumbLETarget,
277*9880d681SAndroid Build Coastguard Worker                     &TheThumbBETarget}) {
278*9880d681SAndroid Build Coastguard Worker     // Register the MC asm info.
279*9880d681SAndroid Build Coastguard Worker     RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo);
280*9880d681SAndroid Build Coastguard Worker 
281*9880d681SAndroid Build Coastguard Worker     // Register the MC instruction info.
282*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo);
283*9880d681SAndroid Build Coastguard Worker 
284*9880d681SAndroid Build Coastguard Worker     // Register the MC register info.
285*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo);
286*9880d681SAndroid Build Coastguard Worker 
287*9880d681SAndroid Build Coastguard Worker     // Register the MC subtarget info.
288*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterMCSubtargetInfo(*T,
289*9880d681SAndroid Build Coastguard Worker                                             ARM_MC::createARMMCSubtargetInfo);
290*9880d681SAndroid Build Coastguard Worker 
291*9880d681SAndroid Build Coastguard Worker     // Register the MC instruction analyzer.
292*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis);
293*9880d681SAndroid Build Coastguard Worker 
294*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterELFStreamer(*T, createELFStreamer);
295*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer);
296*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer);
297*9880d681SAndroid Build Coastguard Worker 
298*9880d681SAndroid Build Coastguard Worker     // Register the obj target streamer.
299*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterObjectTargetStreamer(*T,
300*9880d681SAndroid Build Coastguard Worker                                                  createARMObjectTargetStreamer);
301*9880d681SAndroid Build Coastguard Worker 
302*9880d681SAndroid Build Coastguard Worker     // Register the asm streamer.
303*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer);
304*9880d681SAndroid Build Coastguard Worker 
305*9880d681SAndroid Build Coastguard Worker     // Register the null TargetStreamer.
306*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer);
307*9880d681SAndroid Build Coastguard Worker 
308*9880d681SAndroid Build Coastguard Worker     // Register the MCInstPrinter.
309*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter);
310*9880d681SAndroid Build Coastguard Worker 
311*9880d681SAndroid Build Coastguard Worker     // Register the MC relocation info.
312*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo);
313*9880d681SAndroid Build Coastguard Worker   }
314*9880d681SAndroid Build Coastguard Worker 
315*9880d681SAndroid Build Coastguard Worker   // Register the MC Code Emitter
316*9880d681SAndroid Build Coastguard Worker   for (Target *T : {&TheARMLETarget, &TheThumbLETarget})
317*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter);
318*9880d681SAndroid Build Coastguard Worker   for (Target *T : {&TheARMBETarget, &TheThumbBETarget})
319*9880d681SAndroid Build Coastguard Worker     TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter);
320*9880d681SAndroid Build Coastguard Worker 
321*9880d681SAndroid Build Coastguard Worker   // Register the asm backend.
322*9880d681SAndroid Build Coastguard Worker   TargetRegistry::RegisterMCAsmBackend(TheARMLETarget, createARMLEAsmBackend);
323*9880d681SAndroid Build Coastguard Worker   TargetRegistry::RegisterMCAsmBackend(TheARMBETarget, createARMBEAsmBackend);
324*9880d681SAndroid Build Coastguard Worker   TargetRegistry::RegisterMCAsmBackend(TheThumbLETarget,
325*9880d681SAndroid Build Coastguard Worker                                        createThumbLEAsmBackend);
326*9880d681SAndroid Build Coastguard Worker   TargetRegistry::RegisterMCAsmBackend(TheThumbBETarget,
327*9880d681SAndroid Build Coastguard Worker                                        createThumbBEAsmBackend);
328*9880d681SAndroid Build Coastguard Worker }
329