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