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