LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ARMMCTargetDesc.cpp
Go to the documentation of this file.
1 //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file provides ARM specific target descriptions.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARMBaseInfo.h"
15 #include "ARMMCAsmInfo.h"
16 #include "ARMMCTargetDesc.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/MC/MCCodeGenInfo.h"
20 #include "llvm/MC/MCELFStreamer.h"
22 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCRegisterInfo.h"
27 
28 using namespace llvm;
29 
30 #define GET_REGINFO_MC_DESC
31 #include "ARMGenRegisterInfo.inc"
32 
34  std::string &Info) {
35  if (STI.getFeatureBits() & llvm::ARM::HasV7Ops &&
36  (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
37  (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
38  // Checks for the deprecated CP15ISB encoding:
39  // mcr p15, #0, rX, c7, c5, #4
40  (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) {
41  if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
42  if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
43  Info = "deprecated since v7, use 'isb'";
44  return true;
45  }
46 
47  // Checks for the deprecated CP15DSB encoding:
48  // mcr p15, #0, rX, c7, c10, #4
49  if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
50  Info = "deprecated since v7, use 'dsb'";
51  return true;
52  }
53  }
54  // Checks for the deprecated CP15DMB encoding:
55  // mcr p15, #0, rX, c7, c10, #5
56  if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
57  (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
58  Info = "deprecated since v7, use 'dmb'";
59  return true;
60  }
61  }
62  return false;
63 }
64 
66  std::string &Info) {
67  if (STI.getFeatureBits() & llvm::ARM::HasV8Ops &&
68  MI.getOperand(1).isImm() && MI.getOperand(1).getImm() != 8) {
69  Info = "applying IT instruction to more than one subsequent instruction is deprecated";
70  return true;
71  }
72 
73  return false;
74 }
75 
76 #define GET_INSTRINFO_MC_DESC
77 #include "ARMGenInstrInfo.inc"
78 
79 #define GET_SUBTARGETINFO_MC_DESC
80 #include "ARMGenSubtargetInfo.inc"
81 
82 
84  Triple triple(TT);
85 
86  // Set the boolean corresponding to the current target triple, or the default
87  // if one cannot be determined, to true.
88  unsigned Len = TT.size();
89  unsigned Idx = 0;
90 
91  // FIXME: Enhance Triple helper class to extract ARM version.
92  bool isThumb = false;
93  if (Len >= 5 && TT.substr(0, 4) == "armv")
94  Idx = 4;
95  else if (Len >= 6 && TT.substr(0, 5) == "thumb") {
96  isThumb = true;
97  if (Len >= 7 && TT[5] == 'v')
98  Idx = 6;
99  }
100 
101  bool NoCPU = CPU == "generic" || CPU.empty();
102  std::string ARMArchFeature;
103  if (Idx) {
104  unsigned SubVer = TT[Idx];
105  if (SubVer == '8') {
106  if (NoCPU)
107  // v8a: FeatureDB, FeatureFPARMv8, FeatureNEON, FeatureDSPThumb2, FeatureMP,
108  // FeatureHWDiv, FeatureHWDivARM, FeatureTrustZone, FeatureT2XtPk, FeatureCrypto, FeatureCRC
109  ARMArchFeature = "+v8,+db,+fp-armv8,+neon,+t2dsp,+mp,+hwdiv,+hwdiv-arm,+trustzone,+t2xtpk,+crypto,+crc";
110  else
111  // Use CPU to figure out the exact features
112  ARMArchFeature = "+v8";
113  } else if (SubVer == '7') {
114  if (Len >= Idx+2 && TT[Idx+1] == 'm') {
115  isThumb = true;
116  if (NoCPU)
117  // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass
118  ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass";
119  else
120  // Use CPU to figure out the exact features.
121  ARMArchFeature = "+v7";
122  } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') {
123  if (NoCPU)
124  // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2,
125  // FeatureT2XtPk, FeatureMClass
126  ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass";
127  else
128  // Use CPU to figure out the exact features.
129  ARMArchFeature = "+v7";
130  } else if (Len >= Idx+2 && TT[Idx+1] == 's') {
131  if (NoCPU)
132  // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk
133  // Swift
134  ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+t2xtpk";
135  else
136  // Use CPU to figure out the exact features.
137  ARMArchFeature = "+v7";
138  } else {
139  // v7 CPUs have lots of different feature sets. If no CPU is specified,
140  // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return
141  // the "minimum" feature set and use CPU string to figure out the exact
142  // features.
143  if (NoCPU)
144  // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk
145  ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk";
146  else
147  // Use CPU to figure out the exact features.
148  ARMArchFeature = "+v7";
149  }
150  } else if (SubVer == '6') {
151  if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
152  ARMArchFeature = "+v6t2";
153  else if (Len >= Idx+2 && TT[Idx+1] == 'm') {
154  isThumb = true;
155  if (NoCPU)
156  // v6m: FeatureNoARM, FeatureMClass
157  ARMArchFeature = "+v6m,+noarm,+mclass";
158  else
159  ARMArchFeature = "+v6";
160  } else
161  ARMArchFeature = "+v6";
162  } else if (SubVer == '5') {
163  if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
164  ARMArchFeature = "+v5te";
165  else
166  ARMArchFeature = "+v5t";
167  } else if (SubVer == '4' && Len >= Idx+2 && TT[Idx+1] == 't')
168  ARMArchFeature = "+v4t";
169  }
170 
171  if (isThumb) {
172  if (ARMArchFeature.empty())
173  ARMArchFeature = "+thumb-mode";
174  else
175  ARMArchFeature += ",+thumb-mode";
176  }
177 
178  if (triple.isOSNaCl()) {
179  if (ARMArchFeature.empty())
180  ARMArchFeature = "+nacl-trap";
181  else
182  ARMArchFeature += ",+nacl-trap";
183  }
184 
185  return ARMArchFeature;
186 }
187 
189  StringRef FS) {
190  std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
191  if (!FS.empty()) {
192  if (!ArchFS.empty())
193  ArchFS = ArchFS + "," + FS.str();
194  else
195  ArchFS = FS;
196  }
197 
199  InitARMMCSubtargetInfo(X, TT, CPU, ArchFS);
200  return X;
201 }
202 
204  MCInstrInfo *X = new MCInstrInfo();
205  InitARMMCInstrInfo(X);
206  return X;
207 }
208 
211  InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
212  return X;
213 }
214 
216  Triple TheTriple(TT);
217 
218  if (TheTriple.isOSDarwin())
219  return new ARMMCAsmInfoDarwin();
220 
221  return new ARMELFMCAsmInfo();
222 }
223 
225  CodeModel::Model CM,
226  CodeGenOpt::Level OL) {
227  MCCodeGenInfo *X = new MCCodeGenInfo();
228  if (RM == Reloc::Default) {
229  Triple TheTriple(TT);
230  // Default relocation model on Darwin is PIC, not DynamicNoPIC.
231  RM = TheTriple.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC;
232  }
233  X->InitMCCodeGenInfo(RM, CM, OL);
234  return X;
235 }
236 
237 // This is duplicated code. Refactor this.
239  MCContext &Ctx, MCAsmBackend &MAB,
240  raw_ostream &OS,
241  MCCodeEmitter *Emitter,
242  bool RelaxAll,
243  bool NoExecStack) {
244  Triple TheTriple(TT);
245 
246  if (TheTriple.isOSDarwin())
247  return createMachOStreamer(Ctx, MAB, OS, Emitter, false);
248 
249  if (TheTriple.isOSWindows()) {
250  llvm_unreachable("ARM does not support Windows COFF format");
251  }
252 
253  return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack,
254  TheTriple.getArch() == Triple::thumb);
255 }
256 
258  unsigned SyntaxVariant,
259  const MCAsmInfo &MAI,
260  const MCInstrInfo &MII,
261  const MCRegisterInfo &MRI,
262  const MCSubtargetInfo &STI) {
263  if (SyntaxVariant == 0)
264  return new ARMInstPrinter(MAI, MII, MRI, STI);
265  return 0;
266 }
267 
269  MCContext &Ctx) {
270  Triple TheTriple(TT);
271  if (TheTriple.isEnvironmentMachO())
272  return createARMMachORelocationInfo(Ctx);
273  // Default to the stock relocation info.
274  return llvm::createMCRelocationInfo(TT, Ctx);
275 }
276 
277 namespace {
278 
279 class ARMMCInstrAnalysis : public MCInstrAnalysis {
280 public:
281  ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
282 
283  virtual bool isUnconditionalBranch(const MCInst &Inst) const {
284  // BCCs with the "always" predicate are unconditional branches.
285  if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
286  return true;
288  }
289 
290  virtual bool isConditionalBranch(const MCInst &Inst) const {
291  // BCCs with the "always" predicate are unconditional branches.
292  if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
293  return false;
295  }
296 
297  bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
298  uint64_t Size, uint64_t &Target) const {
299  // We only handle PCRel branches for now.
300  if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL)
301  return false;
302 
303  int64_t Imm = Inst.getOperand(0).getImm();
304  // FIXME: This is not right for thumb.
305  Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes.
306  return true;
307  }
308 };
309 
310 }
311 
313  return new ARMMCInstrAnalysis(Info);
314 }
315 
316 // Force static initialization.
317 extern "C" void LLVMInitializeARMTargetMC() {
318  // Register the MC asm info.
321 
322  // Register the MC codegen info.
325 
326  // Register the MC instruction info.
329 
330  // Register the MC register info.
333 
334  // Register the MC subtarget info.
339 
340  // Register the MC instruction analyzer.
345 
346  // Register the MC Code Emitter
349 
350  // Register the asm backend.
353 
354  // Register the object streamer.
357 
358  // Register the asm streamer.
361 
362  // Register the MCInstPrinter.
365 
366  // Register the MC relocation info.
371 }
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
MCStreamer * createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, bool useCFI, bool useDwarfDirectory, MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst)
static MCAsmInfo * createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT)
static void RegisterMCInstrAnalysis(Target &T, Target::MCInstrAnalysisCtorFnTy Fn)
static MCInstrInfo * createARMMCInstrInfo()
MCRelocationInfo * createARMMachORelocationInfo(MCContext &Ctx)
createARMMachORelocationInfo - Construct ARM Mach-O relocation info.
StringRef substr(size_t Start, size_t N=npos) const
Definition: StringRef.h:392
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:181
static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn)
void LLVMInitializeARMTargetMC()
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:328
MCCodeEmitter * createARMMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI, MCContext &Ctx)
MCStreamer * createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll=false)
#define llvm_unreachable(msg)
bool isEnvironmentMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:354
bool isOSNaCl() const
Tests whether the OS is NaCl (Native Client)
Definition: Triple.h:333
void InitMCCodeGenInfo(Reloc::Model RM=Reloc::Default, CodeModel::Model CM=CodeModel::Default, CodeGenOpt::Level OL=CodeGenOpt::Default)
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:172
static MCRelocationInfo * createARMMCRelocationInfo(StringRef TT, MCContext &Ctx)
virtual bool isUnconditionalBranch(const MCInst &Inst) const
bool isImm() const
Definition: MCInst.h:57
static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn)
static MCInstPrinter * createARMMCInstPrinter(const Target &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI)
Target TheThumbTarget
static void RegisterMCObjectStreamer(Target &T, Target::MCObjectStreamerCtorTy Fn)
const MCInstrInfo & MII
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:22
static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn)
static MCStreamer * createMCStreamer(const Target &T, StringRef TT, MCContext &Ctx, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *Emitter, bool RelaxAll, bool NoExecStack)
Create MCExprs from relocations found in an object file.
static void RegisterMCCodeGenInfo(Target &T, Target::MCCodeGenInfoCtorFnTy Fn)
static void RegisterMCSubtargetInfo(Target &T, Target::MCSubtargetInfoCtorFnTy Fn)
std::string ParseARMTriple(StringRef TT, StringRef CPU)
static bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, std::string &Info)
MCRelocationInfo * createMCRelocationInfo(StringRef TT, MCContext &Ctx)
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
Definition: Triple.h:313
static MCCodeGenInfo * createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL)
uint64_t getFeatureBits() const
virtual bool isConditionalBranch(const MCInst &Inst) const
MCSubtargetInfo * createARMMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS)
static void RegisterMCCodeEmitter(Target &T, Target::MCCodeEmitterCtorTy Fn)
Target TheARMTarget
static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn)
unsigned getOpcode() const
Definition: MCInst.h:158
int64_t getImm() const
Definition: MCInst.h:74
static bool getITDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, std::string &Info)
MCAsmBackend * createARMAsmBackend(const Target &T, const MCRegisterInfo &MRI, StringRef TT, StringRef CPU)
static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn)
static MCRegisterInfo * createARMMCRegisterInfo(StringRef Triple)
MCELFStreamer * createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, bool RelaxAll, bool NoExecStack, bool IsThumb)
static MCInstrAnalysis * createARMMCInstrAnalysis(const MCInstrInfo *Info)
MCAsmBackend - Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:34
cl::opt< bool > RelaxAll("mc-relax-all", cl::desc("When used with filetype=obj, ""relax all fixups in the emitted object file"))
static void RegisterMCRelocationInfo(Target &T, Target::MCRelocationInfoCtorTy Fn)
const MCRegisterInfo & MRI
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:163
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110