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"
17 #include "llvm/ADT/Triple.h"
18 #include "llvm/MC/MCELFStreamer.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/MC/MCStreamer.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/TargetParser.h"
25 #include "llvm/Support/TargetRegistry.h"
26
27 using namespace llvm;
28
29 #define GET_REGINFO_MC_DESC
30 #include "ARMGenRegisterInfo.inc"
31
getMCRDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)32 static bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
33 std::string &Info) {
34 if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
35 (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
36 (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
37 // Checks for the deprecated CP15ISB encoding:
38 // mcr p15, #0, rX, c7, c5, #4
39 (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) {
40 if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
41 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
42 Info = "deprecated since v7, use 'isb'";
43 return true;
44 }
45
46 // Checks for the deprecated CP15DSB encoding:
47 // mcr p15, #0, rX, c7, c10, #4
48 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
49 Info = "deprecated since v7, use 'dsb'";
50 return true;
51 }
52 }
53 // Checks for the deprecated CP15DMB encoding:
54 // mcr p15, #0, rX, c7, c10, #5
55 if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
56 (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
57 Info = "deprecated since v7, use 'dmb'";
58 return true;
59 }
60 }
61 return false;
62 }
63
getITDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)64 static bool getITDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
65 std::string &Info) {
66 if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && MI.getOperand(1).isImm() &&
67 MI.getOperand(1).getImm() != 8) {
68 Info = "applying IT instruction to more than one subsequent instruction is "
69 "deprecated";
70 return true;
71 }
72
73 return false;
74 }
75
getARMStoreDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)76 static bool getARMStoreDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
77 std::string &Info) {
78 assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
79 "cannot predicate thumb instructions");
80
81 assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
82 for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
83 assert(MI.getOperand(OI).isReg() && "expected register");
84 if (MI.getOperand(OI).getReg() == ARM::SP ||
85 MI.getOperand(OI).getReg() == ARM::PC) {
86 Info = "use of SP or PC in the list is deprecated";
87 return true;
88 }
89 }
90 return false;
91 }
92
getARMLoadDeprecationInfo(MCInst & MI,const MCSubtargetInfo & STI,std::string & Info)93 static bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
94 std::string &Info) {
95 assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
96 "cannot predicate thumb instructions");
97
98 assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
99 bool ListContainsPC = false, ListContainsLR = false;
100 for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
101 assert(MI.getOperand(OI).isReg() && "expected register");
102 switch (MI.getOperand(OI).getReg()) {
103 default:
104 break;
105 case ARM::LR:
106 ListContainsLR = true;
107 break;
108 case ARM::PC:
109 ListContainsPC = true;
110 break;
111 case ARM::SP:
112 Info = "use of SP in the list is deprecated";
113 return true;
114 }
115 }
116
117 if (ListContainsPC && ListContainsLR) {
118 Info = "use of LR and PC simultaneously in the list is deprecated";
119 return true;
120 }
121
122 return false;
123 }
124
125 #define GET_INSTRINFO_MC_DESC
126 #include "ARMGenInstrInfo.inc"
127
128 #define GET_SUBTARGETINFO_MC_DESC
129 #include "ARMGenSubtargetInfo.inc"
130
ParseARMTriple(const Triple & TT,StringRef CPU)131 std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
132 bool isThumb =
133 TT.getArch() == Triple::thumb || TT.getArch() == Triple::thumbeb;
134
135 std::string ARMArchFeature;
136
137 unsigned ArchID = ARM::parseArch(TT.getArchName());
138 if (ArchID != ARM::AK_INVALID && (CPU.empty() || CPU == "generic"))
139 ARMArchFeature = (ARMArchFeature + "+" + ARM::getArchName(ArchID)).str();
140
141 if (isThumb) {
142 if (ARMArchFeature.empty())
143 ARMArchFeature = "+thumb-mode";
144 else
145 ARMArchFeature += ",+thumb-mode";
146 }
147
148 if (TT.isOSNaCl()) {
149 if (ARMArchFeature.empty())
150 ARMArchFeature = "+nacl-trap";
151 else
152 ARMArchFeature += ",+nacl-trap";
153 }
154
155 return ARMArchFeature;
156 }
157
createARMMCSubtargetInfo(const Triple & TT,StringRef CPU,StringRef FS)158 MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT,
159 StringRef CPU, StringRef FS) {
160 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
161 if (!FS.empty()) {
162 if (!ArchFS.empty())
163 ArchFS = (Twine(ArchFS) + "," + FS).str();
164 else
165 ArchFS = FS;
166 }
167
168 return createARMMCSubtargetInfoImpl(TT, CPU, ArchFS);
169 }
170
createARMMCInstrInfo()171 static MCInstrInfo *createARMMCInstrInfo() {
172 MCInstrInfo *X = new MCInstrInfo();
173 InitARMMCInstrInfo(X);
174 return X;
175 }
176
createARMMCRegisterInfo(const Triple & Triple)177 static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) {
178 MCRegisterInfo *X = new MCRegisterInfo();
179 InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
180 return X;
181 }
182
createARMMCAsmInfo(const MCRegisterInfo & MRI,const Triple & TheTriple)183 static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI,
184 const Triple &TheTriple) {
185 MCAsmInfo *MAI;
186 if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO())
187 MAI = new ARMMCAsmInfoDarwin(TheTriple);
188 else if (TheTriple.isWindowsMSVCEnvironment())
189 MAI = new ARMCOFFMCAsmInfoMicrosoft();
190 else if (TheTriple.isOSWindows())
191 MAI = new ARMCOFFMCAsmInfoGNU();
192 else
193 MAI = new ARMELFMCAsmInfo(TheTriple);
194
195 return MAI;
196 }
197
198 // Force static initialization.
LLVMInitializeARMTargetMC()199 extern "C" void LLVMInitializeARMTargetMC() {
200 for (Target *T : {&TheARMLETarget, &TheARMBETarget, &TheThumbLETarget,
201 &TheThumbBETarget}) {
202 // Register the MC asm info.
203 RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo);
204
205 // Register the MC instruction info.
206 TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo);
207
208 // Register the MC register info.
209 TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo);
210
211 // Register the MC subtarget info.
212 TargetRegistry::RegisterMCSubtargetInfo(*T,
213 ARM_MC::createARMMCSubtargetInfo);
214 }
215
216 // Register the MC Code Emitter
217 for (Target *T : {&TheARMLETarget, &TheThumbLETarget})
218 TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter);
219 for (Target *T : {&TheARMBETarget, &TheThumbBETarget})
220 TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter);
221
222 // Register the asm backend.
223 TargetRegistry::RegisterMCAsmBackend(TheARMLETarget, createARMLEAsmBackend);
224 TargetRegistry::RegisterMCAsmBackend(TheARMBETarget, createARMBEAsmBackend);
225 TargetRegistry::RegisterMCAsmBackend(TheThumbLETarget,
226 createThumbLEAsmBackend);
227 TargetRegistry::RegisterMCAsmBackend(TheThumbBETarget,
228 createThumbBEAsmBackend);
229 }
230