]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===-- X86Subtarget.cpp - X86 Subtarget Information ----------------------===// |
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 implements the X86 specific subclass of TargetSubtargetInfo. | |
11 | // | |
12 | //===----------------------------------------------------------------------===// | |
13 | ||
223e47cc LB |
14 | #include "X86Subtarget.h" |
15 | #include "X86InstrInfo.h" | |
1a4d82fc | 16 | #include "X86TargetMachine.h" |
970d7e83 LB |
17 | #include "llvm/IR/Attributes.h" |
18 | #include "llvm/IR/Function.h" | |
19 | #include "llvm/IR/GlobalValue.h" | |
1a4d82fc | 20 | #include "llvm/Support/CommandLine.h" |
223e47cc LB |
21 | #include "llvm/Support/Debug.h" |
22 | #include "llvm/Support/ErrorHandling.h" | |
223e47cc | 23 | #include "llvm/Support/Host.h" |
970d7e83 | 24 | #include "llvm/Support/raw_ostream.h" |
223e47cc LB |
25 | #include "llvm/Target/TargetMachine.h" |
26 | #include "llvm/Target/TargetOptions.h" | |
27 | ||
1a4d82fc JJ |
28 | #if defined(_MSC_VER) |
29 | #include <intrin.h> | |
30 | #endif | |
31 | ||
32 | using namespace llvm; | |
33 | ||
34 | #define DEBUG_TYPE "subtarget" | |
35 | ||
223e47cc LB |
36 | #define GET_SUBTARGETINFO_TARGET_DESC |
37 | #define GET_SUBTARGETINFO_CTOR | |
38 | #include "X86GenSubtargetInfo.inc" | |
39 | ||
1a4d82fc JJ |
40 | // Temporary option to control early if-conversion for x86 while adding machine |
41 | // models. | |
42 | static cl::opt<bool> | |
43 | X86EarlyIfConv("x86-early-ifcvt", cl::Hidden, | |
44 | cl::desc("Enable early if-conversion on X86")); | |
223e47cc | 45 | |
223e47cc LB |
46 | |
47 | /// ClassifyBlockAddressReference - Classify a blockaddress reference for the | |
48 | /// current subtarget according to how we should reference it in a non-pcrel | |
49 | /// context. | |
1a4d82fc | 50 | unsigned char X86Subtarget::ClassifyBlockAddressReference() const { |
223e47cc LB |
51 | if (isPICStyleGOT()) // 32-bit ELF targets. |
52 | return X86II::MO_GOTOFF; | |
53 | ||
54 | if (isPICStyleStubPIC()) // Darwin/32 in PIC mode. | |
55 | return X86II::MO_PIC_BASE_OFFSET; | |
56 | ||
57 | // Direct static reference to label. | |
58 | return X86II::MO_NO_FLAG; | |
59 | } | |
60 | ||
61 | /// ClassifyGlobalReference - Classify a global variable reference for the | |
62 | /// current subtarget according to how we should reference it in a non-pcrel | |
63 | /// context. | |
64 | unsigned char X86Subtarget:: | |
65 | ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const { | |
66 | // DLLImport only exists on windows, it is implemented as a load from a | |
67 | // DLLIMPORT stub. | |
1a4d82fc | 68 | if (GV->hasDLLImportStorageClass()) |
223e47cc LB |
69 | return X86II::MO_DLLIMPORT; |
70 | ||
85aaf69f | 71 | bool isDecl = GV->isDeclarationForLinker(); |
223e47cc LB |
72 | |
73 | // X86-64 in PIC mode. | |
74 | if (isPICStyleRIPRel()) { | |
75 | // Large model never uses stubs. | |
76 | if (TM.getCodeModel() == CodeModel::Large) | |
77 | return X86II::MO_NO_FLAG; | |
78 | ||
79 | if (isTargetDarwin()) { | |
80 | // If symbol visibility is hidden, the extra load is not needed if | |
81 | // target is x86-64 or the symbol is definitely defined in the current | |
82 | // translation unit. | |
83 | if (GV->hasDefaultVisibility() && | |
84 | (isDecl || GV->isWeakForLinker())) | |
85 | return X86II::MO_GOTPCREL; | |
86 | } else if (!isTargetWin64()) { | |
87 | assert(isTargetELF() && "Unknown rip-relative target"); | |
88 | ||
89 | // Extra load is needed for all externally visible. | |
90 | if (!GV->hasLocalLinkage() && GV->hasDefaultVisibility()) | |
91 | return X86II::MO_GOTPCREL; | |
92 | } | |
93 | ||
94 | return X86II::MO_NO_FLAG; | |
95 | } | |
96 | ||
97 | if (isPICStyleGOT()) { // 32-bit ELF targets. | |
98 | // Extra load is needed for all externally visible. | |
99 | if (GV->hasLocalLinkage() || GV->hasHiddenVisibility()) | |
100 | return X86II::MO_GOTOFF; | |
101 | return X86II::MO_GOT; | |
102 | } | |
103 | ||
104 | if (isPICStyleStubPIC()) { // Darwin/32 in PIC mode. | |
105 | // Determine whether we have a stub reference and/or whether the reference | |
106 | // is relative to the PIC base or not. | |
107 | ||
108 | // If this is a strong reference to a definition, it is definitely not | |
109 | // through a stub. | |
110 | if (!isDecl && !GV->isWeakForLinker()) | |
111 | return X86II::MO_PIC_BASE_OFFSET; | |
112 | ||
113 | // Unless we have a symbol with hidden visibility, we have to go through a | |
114 | // normal $non_lazy_ptr stub because this symbol might be resolved late. | |
115 | if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference. | |
116 | return X86II::MO_DARWIN_NONLAZY_PIC_BASE; | |
117 | ||
118 | // If symbol visibility is hidden, we have a stub for common symbol | |
119 | // references and external declarations. | |
120 | if (isDecl || GV->hasCommonLinkage()) { | |
121 | // Hidden $non_lazy_ptr reference. | |
122 | return X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE; | |
123 | } | |
124 | ||
125 | // Otherwise, no stub. | |
126 | return X86II::MO_PIC_BASE_OFFSET; | |
127 | } | |
128 | ||
129 | if (isPICStyleStubNoDynamic()) { // Darwin/32 in -mdynamic-no-pic mode. | |
130 | // Determine whether we have a stub reference. | |
131 | ||
132 | // If this is a strong reference to a definition, it is definitely not | |
133 | // through a stub. | |
134 | if (!isDecl && !GV->isWeakForLinker()) | |
135 | return X86II::MO_NO_FLAG; | |
136 | ||
137 | // Unless we have a symbol with hidden visibility, we have to go through a | |
138 | // normal $non_lazy_ptr stub because this symbol might be resolved late. | |
139 | if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference. | |
140 | return X86II::MO_DARWIN_NONLAZY; | |
141 | ||
142 | // Otherwise, no stub. | |
143 | return X86II::MO_NO_FLAG; | |
144 | } | |
145 | ||
146 | // Direct static reference to global. | |
147 | return X86II::MO_NO_FLAG; | |
148 | } | |
149 | ||
150 | ||
151 | /// getBZeroEntry - This function returns the name of a function which has an | |
152 | /// interface like the non-standard bzero function, if such a function exists on | |
153 | /// the current subtarget and it is considered prefereable over memset with zero | |
154 | /// passed as the second argument. Otherwise it returns null. | |
155 | const char *X86Subtarget::getBZeroEntry() const { | |
156 | // Darwin 10 has a __bzero entry point for this purpose. | |
157 | if (getTargetTriple().isMacOSX() && | |
158 | !getTargetTriple().isMacOSXVersionLT(10, 6)) | |
159 | return "__bzero"; | |
160 | ||
1a4d82fc | 161 | return nullptr; |
223e47cc LB |
162 | } |
163 | ||
970d7e83 LB |
164 | bool X86Subtarget::hasSinCos() const { |
165 | return getTargetTriple().isMacOSX() && | |
166 | !getTargetTriple().isMacOSXVersionLT(10, 9) && | |
167 | is64Bit(); | |
168 | } | |
169 | ||
223e47cc LB |
170 | /// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls |
171 | /// to immediate address. | |
172 | bool X86Subtarget::IsLegalToCallImmediateAddr(const TargetMachine &TM) const { | |
1a4d82fc JJ |
173 | // FIXME: I386 PE/COFF supports PC relative calls using IMAGE_REL_I386_REL32 |
174 | // but WinCOFFObjectWriter::RecordRelocation cannot emit them. Once it does, | |
175 | // the following check for Win32 should be removed. | |
176 | if (In64BitMode || isTargetWin32()) | |
223e47cc LB |
177 | return false; |
178 | return isTargetELF() || TM.getRelocationModel() == Reloc::Static; | |
179 | } | |
180 | ||
1a4d82fc | 181 | void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { |
223e47cc | 182 | std::string CPUName = CPU; |
1a4d82fc JJ |
183 | if (CPUName.empty()) |
184 | CPUName = "generic"; | |
185 | ||
186 | // Make sure 64-bit features are available in 64-bit mode. (But make sure | |
187 | // SSE2 can be turned off explicitly.) | |
188 | std::string FullFS = FS; | |
189 | if (In64BitMode) { | |
190 | if (!FullFS.empty()) | |
191 | FullFS = "+64bit,+sse2," + FullFS; | |
192 | else | |
193 | FullFS = "+64bit,+sse2"; | |
223e47cc LB |
194 | } |
195 | ||
1a4d82fc JJ |
196 | // If feature string is not empty, parse features string. |
197 | ParseSubtargetFeatures(CPUName, FullFS); | |
970d7e83 | 198 | |
1a4d82fc JJ |
199 | // Make sure the right MCSchedModel is used. |
200 | InitCPUSchedModel(CPUName); | |
223e47cc LB |
201 | |
202 | InstrItins = getInstrItineraryForCPU(CPUName); | |
203 | ||
204 | // It's important to keep the MCSubtargetInfo feature bits in sync with | |
205 | // target data structure which is shared with MC code emitter, etc. | |
206 | if (In64BitMode) | |
207 | ToggleFeature(X86::Mode64Bit); | |
1a4d82fc JJ |
208 | else if (In32BitMode) |
209 | ToggleFeature(X86::Mode32Bit); | |
210 | else if (In16BitMode) | |
211 | ToggleFeature(X86::Mode16Bit); | |
212 | else | |
213 | llvm_unreachable("Not 16-bit, 32-bit or 64-bit mode!"); | |
223e47cc LB |
214 | |
215 | DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel | |
216 | << ", 3DNowLevel " << X863DNowLevel | |
217 | << ", 64bit " << HasX86_64 << "\n"); | |
218 | assert((!In64BitMode || HasX86_64) && | |
219 | "64-bit code requested on a subtarget that doesn't support it!"); | |
220 | ||
970d7e83 | 221 | // Stack alignment is 16 bytes on Darwin, Linux and Solaris (both |
223e47cc LB |
222 | // 32 and 64 bit) and for all 64-bit targets. |
223 | if (StackAlignOverride) | |
224 | stackAlignment = StackAlignOverride; | |
970d7e83 LB |
225 | else if (isTargetDarwin() || isTargetLinux() || isTargetSolaris() || |
226 | In64BitMode) | |
223e47cc LB |
227 | stackAlignment = 16; |
228 | } | |
229 | ||
970d7e83 LB |
230 | void X86Subtarget::initializeEnvironment() { |
231 | X86SSELevel = NoMMXSSE; | |
232 | X863DNowLevel = NoThreeDNow; | |
233 | HasCMov = false; | |
234 | HasX86_64 = false; | |
235 | HasPOPCNT = false; | |
236 | HasSSE4A = false; | |
237 | HasAES = false; | |
238 | HasPCLMUL = false; | |
239 | HasFMA = false; | |
240 | HasFMA4 = false; | |
241 | HasXOP = false; | |
1a4d82fc | 242 | HasTBM = false; |
970d7e83 LB |
243 | HasMOVBE = false; |
244 | HasRDRAND = false; | |
245 | HasF16C = false; | |
246 | HasFSGSBase = false; | |
247 | HasLZCNT = false; | |
248 | HasBMI = false; | |
249 | HasBMI2 = false; | |
250 | HasRTM = false; | |
1a4d82fc JJ |
251 | HasHLE = false; |
252 | HasERI = false; | |
253 | HasCDI = false; | |
254 | HasPFI = false; | |
255 | HasDQI = false; | |
256 | HasBWI = false; | |
257 | HasVLX = false; | |
970d7e83 | 258 | HasADX = false; |
1a4d82fc JJ |
259 | HasSHA = false; |
260 | HasSGX = false; | |
261 | HasPRFCHW = false; | |
262 | HasRDSEED = false; | |
263 | HasSMAP = false; | |
970d7e83 | 264 | IsBTMemSlow = false; |
1a4d82fc | 265 | IsSHLDSlow = false; |
970d7e83 | 266 | IsUAMemFast = false; |
85aaf69f SL |
267 | IsUAMem32Slow = false; |
268 | HasSSEUnalignedMem = false; | |
970d7e83 LB |
269 | HasCmpxchg16b = false; |
270 | UseLeaForSP = false; | |
85aaf69f SL |
271 | HasSlowDivide32 = false; |
272 | HasSlowDivide64 = false; | |
970d7e83 | 273 | PadShortFunctions = false; |
1a4d82fc JJ |
274 | CallRegIndirect = false; |
275 | LEAUsesAG = false; | |
276 | SlowLEA = false; | |
277 | SlowIncDec = false; | |
85aaf69f SL |
278 | UseSqrtEst = false; |
279 | UseReciprocalEst = false; | |
970d7e83 LB |
280 | stackAlignment = 4; |
281 | // FIXME: this is a known good value for Yonah. How about others? | |
282 | MaxInlineSizeThreshold = 128; | |
283 | } | |
284 | ||
1a4d82fc JJ |
285 | static std::string computeDataLayout(const Triple &TT) { |
286 | // X86 is little endian | |
287 | std::string Ret = "e"; | |
288 | ||
289 | Ret += DataLayout::getManglingComponent(TT); | |
290 | // X86 and x32 have 32 bit pointers. | |
291 | if ((TT.isArch64Bit() && | |
292 | (TT.getEnvironment() == Triple::GNUX32 || TT.isOSNaCl())) || | |
293 | !TT.isArch64Bit()) | |
294 | Ret += "-p:32:32"; | |
295 | ||
296 | // Some ABIs align 64 bit integers and doubles to 64 bits, others to 32. | |
297 | if (TT.isArch64Bit() || TT.isOSWindows() || TT.isOSNaCl()) | |
298 | Ret += "-i64:64"; | |
299 | else | |
300 | Ret += "-f64:32:64"; | |
301 | ||
302 | // Some ABIs align long double to 128 bits, others to 32. | |
303 | if (TT.isOSNaCl()) | |
304 | ; // No f80 | |
305 | else if (TT.isArch64Bit() || TT.isOSDarwin()) | |
306 | Ret += "-f80:128"; | |
307 | else | |
308 | Ret += "-f80:32"; | |
309 | ||
310 | // The registers can hold 8, 16, 32 or, in x86-64, 64 bits. | |
311 | if (TT.isArch64Bit()) | |
312 | Ret += "-n8:16:32:64"; | |
313 | else | |
314 | Ret += "-n8:16:32"; | |
315 | ||
316 | // The stack is aligned to 32 bits on some ABIs and 128 bits on others. | |
317 | if (!TT.isArch64Bit() && TT.isOSWindows()) | |
318 | Ret += "-S32"; | |
319 | else | |
320 | Ret += "-S128"; | |
321 | ||
322 | return Ret; | |
323 | } | |
324 | ||
325 | X86Subtarget &X86Subtarget::initializeSubtargetDependencies(StringRef CPU, | |
326 | StringRef FS) { | |
970d7e83 | 327 | initializeEnvironment(); |
1a4d82fc JJ |
328 | initSubtargetFeatures(CPU, FS); |
329 | return *this; | |
970d7e83 LB |
330 | } |
331 | ||
1a4d82fc | 332 | X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU, |
85aaf69f | 333 | const std::string &FS, const X86TargetMachine &TM, |
1a4d82fc JJ |
334 | unsigned StackAlignOverride) |
335 | : X86GenSubtargetInfo(TT, CPU, FS), X86ProcFamily(Others), | |
336 | PICStyle(PICStyles::None), TargetTriple(TT), | |
337 | DL(computeDataLayout(TargetTriple)), | |
338 | StackAlignOverride(StackAlignOverride), | |
339 | In64BitMode(TargetTriple.getArch() == Triple::x86_64), | |
340 | In32BitMode(TargetTriple.getArch() == Triple::x86 && | |
341 | TargetTriple.getEnvironment() != Triple::CODE16), | |
342 | In16BitMode(TargetTriple.getArch() == Triple::x86 && | |
343 | TargetTriple.getEnvironment() == Triple::CODE16), | |
344 | TSInfo(DL), InstrInfo(initializeSubtargetDependencies(CPU, FS)), | |
345 | TLInfo(TM), FrameLowering(TargetFrameLowering::StackGrowsDown, | |
346 | getStackAlignment(), is64Bit() ? -8 : -4) { | |
347 | // Determine the PICStyle based on the target selected. | |
348 | if (TM.getRelocationModel() == Reloc::Static) { | |
349 | // Unless we're in PIC or DynamicNoPIC mode, set the PIC style to None. | |
350 | setPICStyle(PICStyles::None); | |
351 | } else if (is64Bit()) { | |
352 | // PIC in 64 bit mode is always rip-rel. | |
353 | setPICStyle(PICStyles::RIPRel); | |
354 | } else if (isTargetCOFF()) { | |
355 | setPICStyle(PICStyles::None); | |
356 | } else if (isTargetDarwin()) { | |
357 | if (TM.getRelocationModel() == Reloc::PIC_) | |
358 | setPICStyle(PICStyles::StubPIC); | |
359 | else { | |
360 | assert(TM.getRelocationModel() == Reloc::DynamicNoPIC); | |
361 | setPICStyle(PICStyles::StubDynamicNoPIC); | |
362 | } | |
363 | } else if (isTargetELF()) { | |
364 | setPICStyle(PICStyles::GOT); | |
365 | } | |
223e47cc | 366 | } |
1a4d82fc JJ |
367 | |
368 | bool X86Subtarget::enableEarlyIfConversion() const { | |
369 | return hasCMov() && X86EarlyIfConv; | |
370 | } | |
371 |