]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / AArch64 / MCTargetDesc / AArch64MCTargetDesc.cpp
1 //===-- AArch64MCTargetDesc.cpp - AArch64 Target Descriptions ---*- C++ -*-===//
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 "AArch64WinCOFFStreamer.h"
18 #include "InstPrinter/AArch64InstPrinter.h"
19 #include "llvm/MC/MCAsmBackend.h"
20 #include "llvm/MC/MCCodeEmitter.h"
21 #include "llvm/MC/MCInstrAnalysis.h"
22 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCObjectWriter.h"
24 #include "llvm/MC/MCRegisterInfo.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/TargetRegistry.h"
29
30 using namespace llvm;
31
32 #define GET_INSTRINFO_MC_DESC
33 #include "AArch64GenInstrInfo.inc"
34
35 #define GET_SUBTARGETINFO_MC_DESC
36 #include "AArch64GenSubtargetInfo.inc"
37
38 #define GET_REGINFO_MC_DESC
39 #include "AArch64GenRegisterInfo.inc"
40
41 static MCInstrInfo *createAArch64MCInstrInfo() {
42   MCInstrInfo *X = new MCInstrInfo();
43   InitAArch64MCInstrInfo(X);
44   return X;
45 }
46
47 static MCSubtargetInfo *
48 createAArch64MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
49   if (CPU.empty())
50     CPU = "generic";
51
52   return createAArch64MCSubtargetInfoImpl(TT, CPU, FS);
53 }
54
55 void AArch64_MC::initLLVMToCVRegMapping(MCRegisterInfo *MRI) {
56   for (unsigned Reg = AArch64::NoRegister + 1;
57        Reg < AArch64::NUM_TARGET_REGS; ++Reg) {
58     unsigned CV = MRI->getEncodingValue(Reg);
59     MRI->mapLLVMRegToCVReg(Reg, CV);
60   }
61 }
62
63 static MCRegisterInfo *createAArch64MCRegisterInfo(const Triple &Triple) {
64   MCRegisterInfo *X = new MCRegisterInfo();
65   InitAArch64MCRegisterInfo(X, AArch64::LR);
66   AArch64_MC::initLLVMToCVRegMapping(X);
67   return X;
68 }
69
70 static MCAsmInfo *createAArch64MCAsmInfo(const MCRegisterInfo &MRI,
71                                          const Triple &TheTriple) {
72   MCAsmInfo *MAI;
73   if (TheTriple.isOSBinFormatMachO())
74     MAI = new AArch64MCAsmInfoDarwin();
75   else if (TheTriple.isWindowsMSVCEnvironment())
76     MAI = new AArch64MCAsmInfoMicrosoftCOFF();
77   else if (TheTriple.isOSBinFormatCOFF())
78     MAI = new AArch64MCAsmInfoGNUCOFF();
79   else {
80     assert(TheTriple.isOSBinFormatELF() && "Invalid target");
81     MAI = new AArch64MCAsmInfoELF(TheTriple);
82   }
83
84   // Initial state of the frame pointer is SP.
85   unsigned Reg = MRI.getDwarfRegNum(AArch64::SP, true);
86   MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 0);
87   MAI->addInitialFrameState(Inst);
88
89   return MAI;
90 }
91
92 static MCInstPrinter *createAArch64MCInstPrinter(const Triple &T,
93                                                  unsigned SyntaxVariant,
94                                                  const MCAsmInfo &MAI,
95                                                  const MCInstrInfo &MII,
96                                                  const MCRegisterInfo &MRI) {
97   if (SyntaxVariant == 0)
98     return new AArch64InstPrinter(MAI, MII, MRI);
99   if (SyntaxVariant == 1)
100     return new AArch64AppleInstPrinter(MAI, MII, MRI);
101
102   return nullptr;
103 }
104
105 static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
106                                      std::unique_ptr<MCAsmBackend> &&TAB,
107                                      std::unique_ptr<MCObjectWriter> &&OW,
108                                      std::unique_ptr<MCCodeEmitter> &&Emitter,
109                                      bool RelaxAll) {
110   return createAArch64ELFStreamer(Ctx, std::move(TAB), std::move(OW),
111                                   std::move(Emitter), RelaxAll);
112 }
113
114 static MCStreamer *createMachOStreamer(MCContext &Ctx,
115                                        std::unique_ptr<MCAsmBackend> &&TAB,
116                                        std::unique_ptr<MCObjectWriter> &&OW,
117                                        std::unique_ptr<MCCodeEmitter> &&Emitter,
118                                        bool RelaxAll,
119                                        bool DWARFMustBeAtTheEnd) {
120   return createMachOStreamer(Ctx, std::move(TAB), std::move(OW),
121                              std::move(Emitter), RelaxAll, DWARFMustBeAtTheEnd,
122                              /*LabelSections*/ true);
123 }
124
125 static MCStreamer *
126 createWinCOFFStreamer(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB,
127                       std::unique_ptr<MCObjectWriter> &&OW,
128                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
129                       bool IncrementalLinkerCompatible) {
130   return createAArch64WinCOFFStreamer(Ctx, std::move(TAB), std::move(OW),
131                                       std::move(Emitter), RelaxAll,
132                                       IncrementalLinkerCompatible);
133 }
134
135 namespace {
136
137 class AArch64MCInstrAnalysis : public MCInstrAnalysis {
138 public:
139   AArch64MCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
140
141   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
142                       uint64_t &Target) const override {
143     // Search for a PC-relative argument.
144     // This will handle instructions like bcc (where the first argument is the
145     // condition code) and cbz (where it is a register).
146     const auto &Desc = Info->get(Inst.getOpcode());
147     for (unsigned i = 0, e = Inst.getNumOperands(); i != e; i++) {
148       if (Desc.OpInfo[i].OperandType == MCOI::OPERAND_PCREL) {
149         int64_t Imm = Inst.getOperand(i).getImm() * 4;
150         Target = Addr + Imm;
151         return true;
152       }
153     }
154     return false;
155   }
156 };
157
158 } // end anonymous namespace
159
160 static MCInstrAnalysis *createAArch64InstrAnalysis(const MCInstrInfo *Info) {
161   return new AArch64MCInstrAnalysis(Info);
162 }
163
164 // Force static initialization.
165 extern "C" void LLVMInitializeAArch64TargetMC() {
166   for (Target *T : {&getTheAArch64leTarget(), &getTheAArch64beTarget(),
167                     &getTheARM64Target()}) {
168     // Register the MC asm info.
169     RegisterMCAsmInfoFn X(*T, createAArch64MCAsmInfo);
170
171     // Register the MC instruction info.
172     TargetRegistry::RegisterMCInstrInfo(*T, createAArch64MCInstrInfo);
173
174     // Register the MC register info.
175     TargetRegistry::RegisterMCRegInfo(*T, createAArch64MCRegisterInfo);
176
177     // Register the MC subtarget info.
178     TargetRegistry::RegisterMCSubtargetInfo(*T, createAArch64MCSubtargetInfo);
179
180     // Register the MC instruction analyzer.
181     TargetRegistry::RegisterMCInstrAnalysis(*T, createAArch64InstrAnalysis);
182
183     // Register the MC Code Emitter
184     TargetRegistry::RegisterMCCodeEmitter(*T, createAArch64MCCodeEmitter);
185
186     // Register the obj streamers.
187     TargetRegistry::RegisterELFStreamer(*T, createELFStreamer);
188     TargetRegistry::RegisterMachOStreamer(*T, createMachOStreamer);
189     TargetRegistry::RegisterCOFFStreamer(*T, createWinCOFFStreamer);
190
191     // Register the obj target streamer.
192     TargetRegistry::RegisterObjectTargetStreamer(
193         *T, createAArch64ObjectTargetStreamer);
194
195     // Register the asm streamer.
196     TargetRegistry::RegisterAsmTargetStreamer(*T,
197                                               createAArch64AsmTargetStreamer);
198     // Register the MCInstPrinter.
199     TargetRegistry::RegisterMCInstPrinter(*T, createAArch64MCInstPrinter);
200   }
201
202   // Register the asm backend.
203   for (Target *T : {&getTheAArch64leTarget(), &getTheARM64Target()})
204     TargetRegistry::RegisterMCAsmBackend(*T, createAArch64leAsmBackend);
205   TargetRegistry::RegisterMCAsmBackend(getTheAArch64beTarget(),
206                                        createAArch64beAsmBackend);
207 }