Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / lib / Target / ARM / MCTargetDesc / ARMMCTargetDesc.cpp
blob9f2672f912f86e5b581a506125d6ee37b4442774
1 //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides ARM specific target descriptions.
11 //===----------------------------------------------------------------------===//
13 #include "ARMMCTargetDesc.h"
14 #include "ARMBaseInfo.h"
15 #include "ARMMCAsmInfo.h"
16 #include "InstPrinter/ARMInstPrinter.h"
17 #include "llvm/ADT/Triple.h"
18 #include "llvm/MC/MCAsmBackend.h"
19 #include "llvm/MC/MCCodeEmitter.h"
20 #include "llvm/MC/MCELFStreamer.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/TargetParser.h"
29 #include "llvm/Support/TargetRegistry.h"
31 using namespace llvm;
33 #define GET_REGINFO_MC_DESC
34 #include "ARMGenRegisterInfo.inc"
36 static bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
37 std::string &Info) {
38 if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
39 (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
40 (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
41 // Checks for the deprecated CP15ISB encoding:
42 // mcr p15, #0, rX, c7, c5, #4
43 (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) {
44 if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
45 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
46 Info = "deprecated since v7, use 'isb'";
47 return true;
50 // Checks for the deprecated CP15DSB encoding:
51 // mcr p15, #0, rX, c7, c10, #4
52 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
53 Info = "deprecated since v7, use 'dsb'";
54 return true;
57 // Checks for the deprecated CP15DMB encoding:
58 // mcr p15, #0, rX, c7, c10, #5
59 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
60 (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
61 Info = "deprecated since v7, use 'dmb'";
62 return true;
65 return false;
68 static bool getITDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
69 std::string &Info) {
70 if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && MI.getOperand(1).isImm() &&
71 MI.getOperand(1).getImm() != 8) {
72 Info = "applying IT instruction to more than one subsequent instruction is "
73 "deprecated";
74 return true;
77 return false;
80 static bool getARMStoreDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
81 std::string &Info) {
82 assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
83 "cannot predicate thumb instructions");
85 assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
86 for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
87 assert(MI.getOperand(OI).isReg() && "expected register");
88 if (MI.getOperand(OI).getReg() == ARM::SP ||
89 MI.getOperand(OI).getReg() == ARM::PC) {
90 Info = "use of SP or PC in the list is deprecated";
91 return true;
94 return false;
97 static bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
98 std::string &Info) {
99 assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
100 "cannot predicate thumb instructions");
102 assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
103 bool ListContainsPC = false, ListContainsLR = false;
104 for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
105 assert(MI.getOperand(OI).isReg() && "expected register");
106 switch (MI.getOperand(OI).getReg()) {
107 default:
108 break;
109 case ARM::LR:
110 ListContainsLR = true;
111 break;
112 case ARM::PC:
113 ListContainsPC = true;
114 break;
115 case ARM::SP:
116 Info = "use of SP in the list is deprecated";
117 return true;
121 if (ListContainsPC && ListContainsLR) {
122 Info = "use of LR and PC simultaneously in the list is deprecated";
123 return true;
126 return false;
129 #define GET_INSTRINFO_MC_DESC
130 #include "ARMGenInstrInfo.inc"
132 #define GET_SUBTARGETINFO_MC_DESC
133 #include "ARMGenSubtargetInfo.inc"
135 std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
136 std::string ARMArchFeature;
138 ARM::ArchKind ArchID = ARM::parseArch(TT.getArchName());
139 if (ArchID != ARM::ArchKind::INVALID && (CPU.empty() || CPU == "generic"))
140 ARMArchFeature = (ARMArchFeature + "+" + ARM::getArchName(ArchID)).str();
142 if (TT.isThumb()) {
143 if (!ARMArchFeature.empty())
144 ARMArchFeature += ",";
145 ARMArchFeature += "+thumb-mode,+v4t";
148 if (TT.isOSNaCl()) {
149 if (!ARMArchFeature.empty())
150 ARMArchFeature += ",";
151 ARMArchFeature += "+nacl-trap";
154 if (TT.isOSWindows()) {
155 if (!ARMArchFeature.empty())
156 ARMArchFeature += ",";
157 ARMArchFeature += "+noarm";
160 return ARMArchFeature;
163 MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT,
164 StringRef CPU, StringRef FS) {
165 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
166 if (!FS.empty()) {
167 if (!ArchFS.empty())
168 ArchFS = (Twine(ArchFS) + "," + FS).str();
169 else
170 ArchFS = FS;
173 return createARMMCSubtargetInfoImpl(TT, CPU, ArchFS);
176 static MCInstrInfo *createARMMCInstrInfo() {
177 MCInstrInfo *X = new MCInstrInfo();
178 InitARMMCInstrInfo(X);
179 return X;
182 static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) {
183 MCRegisterInfo *X = new MCRegisterInfo();
184 InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
185 return X;
188 static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI,
189 const Triple &TheTriple) {
190 MCAsmInfo *MAI;
191 if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO())
192 MAI = new ARMMCAsmInfoDarwin(TheTriple);
193 else if (TheTriple.isWindowsMSVCEnvironment())
194 MAI = new ARMCOFFMCAsmInfoMicrosoft();
195 else if (TheTriple.isOSWindows())
196 MAI = new ARMCOFFMCAsmInfoGNU();
197 else
198 MAI = new ARMELFMCAsmInfo(TheTriple);
200 unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
201 MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0));
203 return MAI;
206 static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
207 std::unique_ptr<MCAsmBackend> &&MAB,
208 std::unique_ptr<MCObjectWriter> &&OW,
209 std::unique_ptr<MCCodeEmitter> &&Emitter,
210 bool RelaxAll) {
211 return createARMELFStreamer(
212 Ctx, std::move(MAB), std::move(OW), std::move(Emitter), false,
213 (T.getArch() == Triple::thumb || T.getArch() == Triple::thumbeb));
216 static MCStreamer *
217 createARMMachOStreamer(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&MAB,
218 std::unique_ptr<MCObjectWriter> &&OW,
219 std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
220 bool DWARFMustBeAtTheEnd) {
221 return createMachOStreamer(Ctx, std::move(MAB), std::move(OW),
222 std::move(Emitter), false, DWARFMustBeAtTheEnd);
225 static MCInstPrinter *createARMMCInstPrinter(const Triple &T,
226 unsigned SyntaxVariant,
227 const MCAsmInfo &MAI,
228 const MCInstrInfo &MII,
229 const MCRegisterInfo &MRI) {
230 if (SyntaxVariant == 0)
231 return new ARMInstPrinter(MAI, MII, MRI);
232 return nullptr;
235 static MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT,
236 MCContext &Ctx) {
237 if (TT.isOSBinFormatMachO())
238 return createARMMachORelocationInfo(Ctx);
239 // Default to the stock relocation info.
240 return llvm::createMCRelocationInfo(TT, Ctx);
243 namespace {
245 class ARMMCInstrAnalysis : public MCInstrAnalysis {
246 public:
247 ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
249 bool isUnconditionalBranch(const MCInst &Inst) const override {
250 // BCCs with the "always" predicate are unconditional branches.
251 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
252 return true;
253 return MCInstrAnalysis::isUnconditionalBranch(Inst);
256 bool isConditionalBranch(const MCInst &Inst) const override {
257 // BCCs with the "always" predicate are unconditional branches.
258 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
259 return false;
260 return MCInstrAnalysis::isConditionalBranch(Inst);
263 bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
264 uint64_t Size, uint64_t &Target) const override {
265 // We only handle PCRel branches for now.
266 if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL)
267 return false;
269 int64_t Imm = Inst.getOperand(0).getImm();
270 Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes.
271 return true;
275 class ThumbMCInstrAnalysis : public ARMMCInstrAnalysis {
276 public:
277 ThumbMCInstrAnalysis(const MCInstrInfo *Info) : ARMMCInstrAnalysis(Info) {}
279 bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
280 uint64_t Size, uint64_t &Target) const override {
281 // We only handle PCRel branches for now.
282 if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL)
283 return false;
285 int64_t Imm = Inst.getOperand(0).getImm();
286 Target = Addr+Imm+4; // In Thumb mode the PC is always off by 4 bytes.
287 return true;
293 static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) {
294 return new ARMMCInstrAnalysis(Info);
297 static MCInstrAnalysis *createThumbMCInstrAnalysis(const MCInstrInfo *Info) {
298 return new ThumbMCInstrAnalysis(Info);
301 // Force static initialization.
302 extern "C" void LLVMInitializeARMTargetMC() {
303 for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget(),
304 &getTheThumbLETarget(), &getTheThumbBETarget()}) {
305 // Register the MC asm info.
306 RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo);
308 // Register the MC instruction info.
309 TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo);
311 // Register the MC register info.
312 TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo);
314 // Register the MC subtarget info.
315 TargetRegistry::RegisterMCSubtargetInfo(*T,
316 ARM_MC::createARMMCSubtargetInfo);
318 TargetRegistry::RegisterELFStreamer(*T, createELFStreamer);
319 TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer);
320 TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer);
322 // Register the obj target streamer.
323 TargetRegistry::RegisterObjectTargetStreamer(*T,
324 createARMObjectTargetStreamer);
326 // Register the asm streamer.
327 TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer);
329 // Register the null TargetStreamer.
330 TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer);
332 // Register the MCInstPrinter.
333 TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter);
335 // Register the MC relocation info.
336 TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo);
339 // Register the MC instruction analyzer.
340 for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget()})
341 TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis);
342 for (Target *T : {&getTheThumbLETarget(), &getTheThumbBETarget()})
343 TargetRegistry::RegisterMCInstrAnalysis(*T, createThumbMCInstrAnalysis);
345 for (Target *T : {&getTheARMLETarget(), &getTheThumbLETarget()}) {
346 TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter);
347 TargetRegistry::RegisterMCAsmBackend(*T, createARMLEAsmBackend);
349 for (Target *T : {&getTheARMBETarget(), &getTheThumbBETarget()}) {
350 TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter);
351 TargetRegistry::RegisterMCAsmBackend(*T, createARMBEAsmBackend);