AArch64MCTargetDesc.cpp revision 263508
1//===-- AArch64MCTargetDesc.cpp - AArch64 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 AArch64 specific target descriptions.
11//
12//===----------------------------------------------------------------------===//
13
14#include "AArch64MCTargetDesc.h"
15#include "AArch64ELFStreamer.h"
16#include "AArch64MCAsmInfo.h"
17#include "InstPrinter/AArch64InstPrinter.h"
18#include "llvm/ADT/APInt.h"
19#include "llvm/MC/MCCodeGenInfo.h"
20#include "llvm/MC/MCInstrAnalysis.h"
21#include "llvm/MC/MCInstrInfo.h"
22#include "llvm/MC/MCRegisterInfo.h"
23#include "llvm/MC/MCStreamer.h"
24#include "llvm/MC/MCSubtargetInfo.h"
25#include "llvm/Support/TargetRegistry.h"
26#include "llvm/Support/ErrorHandling.h"
27
28#define GET_REGINFO_MC_DESC
29#include "AArch64GenRegisterInfo.inc"
30
31#define GET_INSTRINFO_MC_DESC
32#include "AArch64GenInstrInfo.inc"
33
34#define GET_SUBTARGETINFO_MC_DESC
35#include "AArch64GenSubtargetInfo.inc"
36
37using namespace llvm;
38
39MCSubtargetInfo *AArch64_MC::createAArch64MCSubtargetInfo(StringRef TT,
40                                                          StringRef CPU,
41                                                          StringRef FS) {
42  MCSubtargetInfo *X = new MCSubtargetInfo();
43  InitAArch64MCSubtargetInfo(X, TT, CPU, FS);
44  return X;
45}
46
47
48static MCInstrInfo *createAArch64MCInstrInfo() {
49  MCInstrInfo *X = new MCInstrInfo();
50  InitAArch64MCInstrInfo(X);
51  return X;
52}
53
54static MCRegisterInfo *createAArch64MCRegisterInfo(StringRef Triple) {
55  MCRegisterInfo *X = new MCRegisterInfo();
56  InitAArch64MCRegisterInfo(X, AArch64::X30);
57  return X;
58}
59
60static MCAsmInfo *createAArch64MCAsmInfo(const MCRegisterInfo &MRI,
61                                         StringRef TT) {
62  Triple TheTriple(TT);
63
64  MCAsmInfo *MAI = new AArch64ELFMCAsmInfo();
65  unsigned Reg = MRI.getDwarfRegNum(AArch64::XSP, true);
66  MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, Reg, 0);
67  MAI->addInitialFrameState(Inst);
68
69  return MAI;
70}
71
72static MCCodeGenInfo *createAArch64MCCodeGenInfo(StringRef TT, Reloc::Model RM,
73                                                 CodeModel::Model CM,
74                                                 CodeGenOpt::Level OL) {
75  MCCodeGenInfo *X = new MCCodeGenInfo();
76  if (RM == Reloc::Default || RM == Reloc::DynamicNoPIC) {
77    // On ELF platforms the default static relocation model has a smart enough
78    // linker to cope with referencing external symbols defined in a shared
79    // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
80    RM = Reloc::Static;
81  }
82
83  if (CM == CodeModel::Default)
84    CM = CodeModel::Small;
85  else if (CM == CodeModel::JITDefault) {
86    // The default MCJIT memory managers make no guarantees about where they can
87    // find an executable page; JITed code needs to be able to refer to globals
88    // no matter how far away they are.
89    CM = CodeModel::Large;
90  }
91
92  X->InitMCCodeGenInfo(RM, CM, OL);
93  return X;
94}
95
96static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
97                                    MCContext &Ctx, MCAsmBackend &MAB,
98                                    raw_ostream &OS,
99                                    MCCodeEmitter *Emitter,
100                                    bool RelaxAll,
101                                    bool NoExecStack) {
102  Triple TheTriple(TT);
103
104  return createAArch64ELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack);
105}
106
107
108static MCInstPrinter *createAArch64MCInstPrinter(const Target &T,
109                                                 unsigned SyntaxVariant,
110                                                 const MCAsmInfo &MAI,
111                                                 const MCInstrInfo &MII,
112                                                 const MCRegisterInfo &MRI,
113                                                 const MCSubtargetInfo &STI) {
114  if (SyntaxVariant == 0)
115    return new AArch64InstPrinter(MAI, MII, MRI, STI);
116  return 0;
117}
118
119namespace {
120
121class AArch64MCInstrAnalysis : public MCInstrAnalysis {
122public:
123  AArch64MCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
124
125  virtual bool isUnconditionalBranch(const MCInst &Inst) const {
126    if (Inst.getOpcode() == AArch64::Bcc
127        && Inst.getOperand(0).getImm() == A64CC::AL)
128      return true;
129    return MCInstrAnalysis::isUnconditionalBranch(Inst);
130  }
131
132  virtual bool isConditionalBranch(const MCInst &Inst) const {
133    if (Inst.getOpcode() == AArch64::Bcc
134        && Inst.getOperand(0).getImm() == A64CC::AL)
135      return false;
136    return MCInstrAnalysis::isConditionalBranch(Inst);
137  }
138
139  bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
140                      uint64_t Size, uint64_t &Target) const {
141    unsigned LblOperand = Inst.getOpcode() == AArch64::Bcc ? 1 : 0;
142    // FIXME: We only handle PCRel branches for now.
143    if (Info->get(Inst.getOpcode()).OpInfo[LblOperand].OperandType
144        != MCOI::OPERAND_PCREL)
145      return false;
146
147    int64_t Imm = Inst.getOperand(LblOperand).getImm();
148    Target = Addr + Imm;
149    return true;
150  }
151};
152
153}
154
155static MCInstrAnalysis *createAArch64MCInstrAnalysis(const MCInstrInfo *Info) {
156  return new AArch64MCInstrAnalysis(Info);
157}
158
159
160
161extern "C" void LLVMInitializeAArch64TargetMC() {
162  // Register the MC asm info.
163  RegisterMCAsmInfoFn A(TheAArch64Target, createAArch64MCAsmInfo);
164
165  // Register the MC codegen info.
166  TargetRegistry::RegisterMCCodeGenInfo(TheAArch64Target,
167                                        createAArch64MCCodeGenInfo);
168
169  // Register the MC instruction info.
170  TargetRegistry::RegisterMCInstrInfo(TheAArch64Target,
171                                      createAArch64MCInstrInfo);
172
173  // Register the MC register info.
174  TargetRegistry::RegisterMCRegInfo(TheAArch64Target,
175                                    createAArch64MCRegisterInfo);
176
177  // Register the MC subtarget info.
178  using AArch64_MC::createAArch64MCSubtargetInfo;
179  TargetRegistry::RegisterMCSubtargetInfo(TheAArch64Target,
180                                          createAArch64MCSubtargetInfo);
181
182  // Register the MC instruction analyzer.
183  TargetRegistry::RegisterMCInstrAnalysis(TheAArch64Target,
184                                          createAArch64MCInstrAnalysis);
185
186  // Register the MC Code Emitter
187  TargetRegistry::RegisterMCCodeEmitter(TheAArch64Target,
188                                        createAArch64MCCodeEmitter);
189
190  // Register the asm backend.
191  TargetRegistry::RegisterMCAsmBackend(TheAArch64Target,
192                                       createAArch64AsmBackend);
193
194  // Register the object streamer.
195  TargetRegistry::RegisterMCObjectStreamer(TheAArch64Target,
196                                           createMCStreamer);
197
198  // Register the MCInstPrinter.
199  TargetRegistry::RegisterMCInstPrinter(TheAArch64Target,
200                                        createAArch64MCInstPrinter);
201}
202