1 | //===--- TargetInfo.cpp - Information about Target machine ----------------===// |
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 implements the TargetInfo interface. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "clang/Basic/TargetInfo.h" |
14 | #include "clang/Basic/AddressSpaces.h" |
15 | #include "clang/Basic/CharInfo.h" |
16 | #include "clang/Basic/Diagnostic.h" |
17 | #include "clang/Basic/DiagnosticFrontend.h" |
18 | #include "clang/Basic/LangOptions.h" |
19 | #include "llvm/ADT/APFloat.h" |
20 | #include "llvm/ADT/STLExtras.h" |
21 | #include "llvm/Support/ErrorHandling.h" |
22 | #include "llvm/TargetParser/TargetParser.h" |
23 | #include <cstdlib> |
24 | using namespace clang; |
25 | |
26 | static const LangASMap DefaultAddrSpaceMap = {0}; |
27 | // The fake address space map must have a distinct entry for each |
28 | // language-specific address space. |
29 | static const LangASMap FakeAddrSpaceMap = { |
30 | 0, // Default |
31 | 1, // opencl_global |
32 | 3, // opencl_local |
33 | 2, // opencl_constant |
34 | 0, // opencl_private |
35 | 4, // opencl_generic |
36 | 5, // opencl_global_device |
37 | 6, // opencl_global_host |
38 | 7, // cuda_device |
39 | 8, // cuda_constant |
40 | 9, // cuda_shared |
41 | 1, // sycl_global |
42 | 5, // sycl_global_device |
43 | 6, // sycl_global_host |
44 | 3, // sycl_local |
45 | 0, // sycl_private |
46 | 10, // ptr32_sptr |
47 | 11, // ptr32_uptr |
48 | 12, // ptr64 |
49 | 13, // hlsl_groupshared |
50 | 20, // wasm_funcref |
51 | }; |
52 | |
53 | // TargetInfo Constructor. |
54 | TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { |
55 | // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or |
56 | // SPARC. These should be overridden by concrete targets as needed. |
57 | BigEndian = !T.isLittleEndian(); |
58 | TLSSupported = true; |
59 | VLASupported = true; |
60 | NoAsmVariants = false; |
61 | HasLegalHalfType = false; |
62 | HalfArgsAndReturns = false; |
63 | HasFloat128 = false; |
64 | HasIbm128 = false; |
65 | HasFloat16 = false; |
66 | HasBFloat16 = false; |
67 | HasFullBFloat16 = false; |
68 | HasLongDouble = true; |
69 | HasFPReturn = true; |
70 | HasStrictFP = false; |
71 | PointerWidth = PointerAlign = 32; |
72 | BoolWidth = BoolAlign = 8; |
73 | IntWidth = IntAlign = 32; |
74 | LongWidth = LongAlign = 32; |
75 | LongLongWidth = LongLongAlign = 64; |
76 | Int128Align = 128; |
77 | |
78 | // Fixed point default bit widths |
79 | ShortAccumWidth = ShortAccumAlign = 16; |
80 | AccumWidth = AccumAlign = 32; |
81 | LongAccumWidth = LongAccumAlign = 64; |
82 | ShortFractWidth = ShortFractAlign = 8; |
83 | FractWidth = FractAlign = 16; |
84 | LongFractWidth = LongFractAlign = 32; |
85 | |
86 | // Fixed point default integral and fractional bit sizes |
87 | // We give the _Accum 1 fewer fractional bits than their corresponding _Fract |
88 | // types by default to have the same number of fractional bits between _Accum |
89 | // and _Fract types. |
90 | PaddingOnUnsignedFixedPoint = false; |
91 | ShortAccumScale = 7; |
92 | AccumScale = 15; |
93 | LongAccumScale = 31; |
94 | |
95 | SuitableAlign = 64; |
96 | DefaultAlignForAttributeAligned = 128; |
97 | MinGlobalAlign = 0; |
98 | // From the glibc documentation, on GNU systems, malloc guarantees 16-byte |
99 | // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See |
100 | // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html. |
101 | // This alignment guarantee also applies to Windows and Android. On Darwin |
102 | // and OpenBSD, the alignment is 16 bytes on both 64-bit and 32-bit systems. |
103 | if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid() || |
104 | T.isOHOSFamily()) |
105 | NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0; |
106 | else if (T.isOSDarwin() || T.isOSOpenBSD()) |
107 | NewAlign = 128; |
108 | else |
109 | NewAlign = 0; // Infer from basic type alignment. |
110 | HalfWidth = 16; |
111 | HalfAlign = 16; |
112 | FloatWidth = 32; |
113 | FloatAlign = 32; |
114 | DoubleWidth = 64; |
115 | DoubleAlign = 64; |
116 | LongDoubleWidth = 64; |
117 | LongDoubleAlign = 64; |
118 | Float128Align = 128; |
119 | Ibm128Align = 128; |
120 | LargeArrayMinWidth = 0; |
121 | LargeArrayAlign = 0; |
122 | MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; |
123 | MaxVectorAlign = 0; |
124 | MaxTLSAlign = 0; |
125 | SizeType = UnsignedLong; |
126 | PtrDiffType = SignedLong; |
127 | IntMaxType = SignedLongLong; |
128 | IntPtrType = SignedLong; |
129 | WCharType = SignedInt; |
130 | WIntType = SignedInt; |
131 | Char16Type = UnsignedShort; |
132 | Char32Type = UnsignedInt; |
133 | Int64Type = SignedLongLong; |
134 | Int16Type = SignedShort; |
135 | SigAtomicType = SignedInt; |
136 | ProcessIDType = SignedInt; |
137 | UseSignedCharForObjCBool = true; |
138 | UseBitFieldTypeAlignment = true; |
139 | UseZeroLengthBitfieldAlignment = false; |
140 | UseLeadingZeroLengthBitfield = true; |
141 | UseExplicitBitFieldAlignment = true; |
142 | ZeroLengthBitfieldBoundary = 0; |
143 | MaxAlignedAttribute = 0; |
144 | HalfFormat = &llvm::APFloat::IEEEhalf(); |
145 | FloatFormat = &llvm::APFloat::IEEEsingle(); |
146 | DoubleFormat = &llvm::APFloat::IEEEdouble(); |
147 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
148 | Float128Format = &llvm::APFloat::IEEEquad(); |
149 | Ibm128Format = &llvm::APFloat::PPCDoubleDouble(); |
150 | MCountName = "mcount" ; |
151 | UserLabelPrefix = "_" ; |
152 | RegParmMax = 0; |
153 | SSERegParmMax = 0; |
154 | HasAlignMac68kSupport = false; |
155 | HasBuiltinMSVaList = false; |
156 | IsRenderScriptTarget = false; |
157 | HasAArch64SVETypes = false; |
158 | HasRISCVVTypes = false; |
159 | AllowAMDGPUUnsafeFPAtomics = false; |
160 | HasUnalignedAccess = false; |
161 | ARMCDECoprocMask = 0; |
162 | |
163 | // Default to no types using fpret. |
164 | RealTypeUsesObjCFPRetMask = 0; |
165 | |
166 | // Default to not using fp2ret for __Complex long double |
167 | ComplexLongDoubleUsesFP2Ret = false; |
168 | |
169 | // Set the C++ ABI based on the triple. |
170 | TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment() |
171 | ? TargetCXXABI::Microsoft |
172 | : TargetCXXABI::GenericItanium); |
173 | |
174 | // Default to an empty address space map. |
175 | AddrSpaceMap = &DefaultAddrSpaceMap; |
176 | UseAddrSpaceMapMangling = false; |
177 | |
178 | // Default to an unknown platform name. |
179 | PlatformName = "unknown" ; |
180 | PlatformMinVersion = VersionTuple(); |
181 | |
182 | MaxOpenCLWorkGroupSize = 1024; |
183 | |
184 | MaxBitIntWidth.reset(); |
185 | } |
186 | |
187 | // Out of line virtual dtor for TargetInfo. |
188 | TargetInfo::~TargetInfo() {} |
189 | |
190 | void TargetInfo::resetDataLayout(StringRef DL, const char *ULP) { |
191 | DataLayoutString = DL.str(); |
192 | UserLabelPrefix = ULP; |
193 | } |
194 | |
195 | bool |
196 | TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const { |
197 | Diags.Report(DiagID: diag::err_opt_not_valid_on_target) << "cf-protection=branch" ; |
198 | return false; |
199 | } |
200 | |
201 | bool |
202 | TargetInfo::checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const { |
203 | Diags.Report(DiagID: diag::err_opt_not_valid_on_target) << "cf-protection=return" ; |
204 | return false; |
205 | } |
206 | |
207 | /// getTypeName - Return the user string for the specified integer type enum. |
208 | /// For example, SignedShort -> "short". |
209 | const char *TargetInfo::getTypeName(IntType T) { |
210 | switch (T) { |
211 | default: llvm_unreachable("not an integer!" ); |
212 | case SignedChar: return "signed char" ; |
213 | case UnsignedChar: return "unsigned char" ; |
214 | case SignedShort: return "short" ; |
215 | case UnsignedShort: return "unsigned short" ; |
216 | case SignedInt: return "int" ; |
217 | case UnsignedInt: return "unsigned int" ; |
218 | case SignedLong: return "long int" ; |
219 | case UnsignedLong: return "long unsigned int" ; |
220 | case SignedLongLong: return "long long int" ; |
221 | case UnsignedLongLong: return "long long unsigned int" ; |
222 | } |
223 | } |
224 | |
225 | /// getTypeConstantSuffix - Return the constant suffix for the specified |
226 | /// integer type enum. For example, SignedLong -> "L". |
227 | const char *TargetInfo::getTypeConstantSuffix(IntType T) const { |
228 | switch (T) { |
229 | default: llvm_unreachable("not an integer!" ); |
230 | case SignedChar: |
231 | case SignedShort: |
232 | case SignedInt: return "" ; |
233 | case SignedLong: return "L" ; |
234 | case SignedLongLong: return "LL" ; |
235 | case UnsignedChar: |
236 | if (getCharWidth() < getIntWidth()) |
237 | return "" ; |
238 | [[fallthrough]]; |
239 | case UnsignedShort: |
240 | if (getShortWidth() < getIntWidth()) |
241 | return "" ; |
242 | [[fallthrough]]; |
243 | case UnsignedInt: return "U" ; |
244 | case UnsignedLong: return "UL" ; |
245 | case UnsignedLongLong: return "ULL" ; |
246 | } |
247 | } |
248 | |
249 | /// getTypeFormatModifier - Return the printf format modifier for the |
250 | /// specified integer type enum. For example, SignedLong -> "l". |
251 | |
252 | const char *TargetInfo::getTypeFormatModifier(IntType T) { |
253 | switch (T) { |
254 | default: llvm_unreachable("not an integer!" ); |
255 | case SignedChar: |
256 | case UnsignedChar: return "hh" ; |
257 | case SignedShort: |
258 | case UnsignedShort: return "h" ; |
259 | case SignedInt: |
260 | case UnsignedInt: return "" ; |
261 | case SignedLong: |
262 | case UnsignedLong: return "l" ; |
263 | case SignedLongLong: |
264 | case UnsignedLongLong: return "ll" ; |
265 | } |
266 | } |
267 | |
268 | /// getTypeWidth - Return the width (in bits) of the specified integer type |
269 | /// enum. For example, SignedInt -> getIntWidth(). |
270 | unsigned TargetInfo::getTypeWidth(IntType T) const { |
271 | switch (T) { |
272 | default: llvm_unreachable("not an integer!" ); |
273 | case SignedChar: |
274 | case UnsignedChar: return getCharWidth(); |
275 | case SignedShort: |
276 | case UnsignedShort: return getShortWidth(); |
277 | case SignedInt: |
278 | case UnsignedInt: return getIntWidth(); |
279 | case SignedLong: |
280 | case UnsignedLong: return getLongWidth(); |
281 | case SignedLongLong: |
282 | case UnsignedLongLong: return getLongLongWidth(); |
283 | }; |
284 | } |
285 | |
286 | TargetInfo::IntType TargetInfo::getIntTypeByWidth( |
287 | unsigned BitWidth, bool IsSigned) const { |
288 | if (getCharWidth() == BitWidth) |
289 | return IsSigned ? SignedChar : UnsignedChar; |
290 | if (getShortWidth() == BitWidth) |
291 | return IsSigned ? SignedShort : UnsignedShort; |
292 | if (getIntWidth() == BitWidth) |
293 | return IsSigned ? SignedInt : UnsignedInt; |
294 | if (getLongWidth() == BitWidth) |
295 | return IsSigned ? SignedLong : UnsignedLong; |
296 | if (getLongLongWidth() == BitWidth) |
297 | return IsSigned ? SignedLongLong : UnsignedLongLong; |
298 | return NoInt; |
299 | } |
300 | |
301 | TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth, |
302 | bool IsSigned) const { |
303 | if (getCharWidth() >= BitWidth) |
304 | return IsSigned ? SignedChar : UnsignedChar; |
305 | if (getShortWidth() >= BitWidth) |
306 | return IsSigned ? SignedShort : UnsignedShort; |
307 | if (getIntWidth() >= BitWidth) |
308 | return IsSigned ? SignedInt : UnsignedInt; |
309 | if (getLongWidth() >= BitWidth) |
310 | return IsSigned ? SignedLong : UnsignedLong; |
311 | if (getLongLongWidth() >= BitWidth) |
312 | return IsSigned ? SignedLongLong : UnsignedLongLong; |
313 | return NoInt; |
314 | } |
315 | |
316 | FloatModeKind TargetInfo::getRealTypeByWidth(unsigned BitWidth, |
317 | FloatModeKind ExplicitType) const { |
318 | if (getHalfWidth() == BitWidth) |
319 | return FloatModeKind::Half; |
320 | if (getFloatWidth() == BitWidth) |
321 | return FloatModeKind::Float; |
322 | if (getDoubleWidth() == BitWidth) |
323 | return FloatModeKind::Double; |
324 | |
325 | switch (BitWidth) { |
326 | case 96: |
327 | if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended()) |
328 | return FloatModeKind::LongDouble; |
329 | break; |
330 | case 128: |
331 | // The caller explicitly asked for an IEEE compliant type but we still |
332 | // have to check if the target supports it. |
333 | if (ExplicitType == FloatModeKind::Float128) |
334 | return hasFloat128Type() ? FloatModeKind::Float128 |
335 | : FloatModeKind::NoFloat; |
336 | if (ExplicitType == FloatModeKind::Ibm128) |
337 | return hasIbm128Type() ? FloatModeKind::Ibm128 |
338 | : FloatModeKind::NoFloat; |
339 | if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() || |
340 | &getLongDoubleFormat() == &llvm::APFloat::IEEEquad()) |
341 | return FloatModeKind::LongDouble; |
342 | if (hasFloat128Type()) |
343 | return FloatModeKind::Float128; |
344 | break; |
345 | } |
346 | |
347 | return FloatModeKind::NoFloat; |
348 | } |
349 | |
350 | /// getTypeAlign - Return the alignment (in bits) of the specified integer type |
351 | /// enum. For example, SignedInt -> getIntAlign(). |
352 | unsigned TargetInfo::getTypeAlign(IntType T) const { |
353 | switch (T) { |
354 | default: llvm_unreachable("not an integer!" ); |
355 | case SignedChar: |
356 | case UnsignedChar: return getCharAlign(); |
357 | case SignedShort: |
358 | case UnsignedShort: return getShortAlign(); |
359 | case SignedInt: |
360 | case UnsignedInt: return getIntAlign(); |
361 | case SignedLong: |
362 | case UnsignedLong: return getLongAlign(); |
363 | case SignedLongLong: |
364 | case UnsignedLongLong: return getLongLongAlign(); |
365 | }; |
366 | } |
367 | |
368 | /// isTypeSigned - Return whether an integer types is signed. Returns true if |
369 | /// the type is signed; false otherwise. |
370 | bool TargetInfo::isTypeSigned(IntType T) { |
371 | switch (T) { |
372 | default: llvm_unreachable("not an integer!" ); |
373 | case SignedChar: |
374 | case SignedShort: |
375 | case SignedInt: |
376 | case SignedLong: |
377 | case SignedLongLong: |
378 | return true; |
379 | case UnsignedChar: |
380 | case UnsignedShort: |
381 | case UnsignedInt: |
382 | case UnsignedLong: |
383 | case UnsignedLongLong: |
384 | return false; |
385 | }; |
386 | } |
387 | |
388 | /// adjust - Set forced language options. |
389 | /// Apply changes to the target information with respect to certain |
390 | /// language options which change the target configuration and adjust |
391 | /// the language based on the target options where applicable. |
392 | void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { |
393 | if (Opts.NoBitFieldTypeAlign) |
394 | UseBitFieldTypeAlignment = false; |
395 | |
396 | switch (Opts.WCharSize) { |
397 | default: llvm_unreachable("invalid wchar_t width" ); |
398 | case 0: break; |
399 | case 1: WCharType = Opts.WCharIsSigned ? SignedChar : UnsignedChar; break; |
400 | case 2: WCharType = Opts.WCharIsSigned ? SignedShort : UnsignedShort; break; |
401 | case 4: WCharType = Opts.WCharIsSigned ? SignedInt : UnsignedInt; break; |
402 | } |
403 | |
404 | if (Opts.AlignDouble) { |
405 | DoubleAlign = LongLongAlign = 64; |
406 | LongDoubleAlign = 64; |
407 | } |
408 | |
409 | // HLSL explicitly defines the sizes and formats of some data types, and we |
410 | // need to conform to those regardless of what architecture you are targeting. |
411 | if (Opts.HLSL) { |
412 | LongWidth = LongAlign = 64; |
413 | if (!Opts.NativeHalfType) { |
414 | HalfFormat = &llvm::APFloat::IEEEsingle(); |
415 | HalfWidth = HalfAlign = 32; |
416 | } |
417 | } |
418 | |
419 | if (Opts.OpenCL) { |
420 | // OpenCL C requires specific widths for types, irrespective of |
421 | // what these normally are for the target. |
422 | // We also define long long and long double here, although the |
423 | // OpenCL standard only mentions these as "reserved". |
424 | IntWidth = IntAlign = 32; |
425 | LongWidth = LongAlign = 64; |
426 | LongLongWidth = LongLongAlign = 128; |
427 | HalfWidth = HalfAlign = 16; |
428 | FloatWidth = FloatAlign = 32; |
429 | |
430 | // Embedded 32-bit targets (OpenCL EP) might have double C type |
431 | // defined as float. Let's not override this as it might lead |
432 | // to generating illegal code that uses 64bit doubles. |
433 | if (DoubleWidth != FloatWidth) { |
434 | DoubleWidth = DoubleAlign = 64; |
435 | DoubleFormat = &llvm::APFloat::IEEEdouble(); |
436 | } |
437 | LongDoubleWidth = LongDoubleAlign = 128; |
438 | |
439 | unsigned MaxPointerWidth = getMaxPointerWidth(); |
440 | assert(MaxPointerWidth == 32 || MaxPointerWidth == 64); |
441 | bool Is32BitArch = MaxPointerWidth == 32; |
442 | SizeType = Is32BitArch ? UnsignedInt : UnsignedLong; |
443 | PtrDiffType = Is32BitArch ? SignedInt : SignedLong; |
444 | IntPtrType = Is32BitArch ? SignedInt : SignedLong; |
445 | |
446 | IntMaxType = SignedLongLong; |
447 | Int64Type = SignedLong; |
448 | |
449 | HalfFormat = &llvm::APFloat::IEEEhalf(); |
450 | FloatFormat = &llvm::APFloat::IEEEsingle(); |
451 | LongDoubleFormat = &llvm::APFloat::IEEEquad(); |
452 | |
453 | // OpenCL C v3.0 s6.7.5 - The generic address space requires support for |
454 | // OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space |
455 | // feature |
456 | // OpenCL C v3.0 s6.2.1 - OpenCL pipes require support of OpenCL C 2.0 |
457 | // or later and __opencl_c_pipes feature |
458 | // FIXME: These language options are also defined in setLangDefaults() |
459 | // for OpenCL C 2.0 but with no access to target capabilities. Target |
460 | // should be immutable once created and thus these language options need |
461 | // to be defined only once. |
462 | if (Opts.getOpenCLCompatibleVersion() == 300) { |
463 | const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts(); |
464 | Opts.OpenCLGenericAddressSpace = hasFeatureEnabled( |
465 | Features: OpenCLFeaturesMap, Name: "__opencl_c_generic_address_space" ); |
466 | Opts.OpenCLPipes = |
467 | hasFeatureEnabled(Features: OpenCLFeaturesMap, Name: "__opencl_c_pipes" ); |
468 | Opts.Blocks = |
469 | hasFeatureEnabled(Features: OpenCLFeaturesMap, Name: "__opencl_c_device_enqueue" ); |
470 | } |
471 | } |
472 | |
473 | if (Opts.DoubleSize) { |
474 | if (Opts.DoubleSize == 32) { |
475 | DoubleWidth = 32; |
476 | LongDoubleWidth = 32; |
477 | DoubleFormat = &llvm::APFloat::IEEEsingle(); |
478 | LongDoubleFormat = &llvm::APFloat::IEEEsingle(); |
479 | } else if (Opts.DoubleSize == 64) { |
480 | DoubleWidth = 64; |
481 | LongDoubleWidth = 64; |
482 | DoubleFormat = &llvm::APFloat::IEEEdouble(); |
483 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
484 | } |
485 | } |
486 | |
487 | if (Opts.LongDoubleSize) { |
488 | if (Opts.LongDoubleSize == DoubleWidth) { |
489 | LongDoubleWidth = DoubleWidth; |
490 | LongDoubleAlign = DoubleAlign; |
491 | LongDoubleFormat = DoubleFormat; |
492 | } else if (Opts.LongDoubleSize == 128) { |
493 | LongDoubleWidth = LongDoubleAlign = 128; |
494 | LongDoubleFormat = &llvm::APFloat::IEEEquad(); |
495 | } else if (Opts.LongDoubleSize == 80) { |
496 | LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); |
497 | if (getTriple().isWindowsMSVCEnvironment()) { |
498 | LongDoubleWidth = 128; |
499 | LongDoubleAlign = 128; |
500 | } else { // Linux |
501 | if (getTriple().getArch() == llvm::Triple::x86) { |
502 | LongDoubleWidth = 96; |
503 | LongDoubleAlign = 32; |
504 | } else { |
505 | LongDoubleWidth = 128; |
506 | LongDoubleAlign = 128; |
507 | } |
508 | } |
509 | } |
510 | } |
511 | |
512 | if (Opts.NewAlignOverride) |
513 | NewAlign = Opts.NewAlignOverride * getCharWidth(); |
514 | |
515 | // Each unsigned fixed point type has the same number of fractional bits as |
516 | // its corresponding signed type. |
517 | PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint; |
518 | CheckFixedPointBits(); |
519 | |
520 | if (Opts.ProtectParens && !checkArithmeticFenceSupported()) { |
521 | Diags.Report(DiagID: diag::err_opt_not_valid_on_target) << "-fprotect-parens" ; |
522 | Opts.ProtectParens = false; |
523 | } |
524 | |
525 | if (Opts.MaxBitIntWidth) |
526 | MaxBitIntWidth = static_cast<unsigned>(Opts.MaxBitIntWidth); |
527 | |
528 | if (Opts.FakeAddressSpaceMap) |
529 | AddrSpaceMap = &FakeAddrSpaceMap; |
530 | } |
531 | |
532 | bool TargetInfo::initFeatureMap( |
533 | llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, |
534 | const std::vector<std::string> &FeatureVec) const { |
535 | for (const auto &F : FeatureVec) { |
536 | StringRef Name = F; |
537 | if (Name.empty()) |
538 | continue; |
539 | // Apply the feature via the target. |
540 | if (Name[0] != '+' && Name[0] != '-') |
541 | Diags.Report(DiagID: diag::warn_fe_backend_invalid_feature_flag) << Name; |
542 | else |
543 | setFeatureEnabled(Features, Name: Name.substr(Start: 1), Enabled: Name[0] == '+'); |
544 | } |
545 | return true; |
546 | } |
547 | |
548 | ParsedTargetAttr TargetInfo::parseTargetAttr(StringRef Features) const { |
549 | ParsedTargetAttr Ret; |
550 | if (Features == "default" ) |
551 | return Ret; |
552 | SmallVector<StringRef, 1> AttrFeatures; |
553 | Features.split(A&: AttrFeatures, Separator: "," ); |
554 | |
555 | // Grab the various features and prepend a "+" to turn on the feature to |
556 | // the backend and add them to our existing set of features. |
557 | for (auto &Feature : AttrFeatures) { |
558 | // Go ahead and trim whitespace rather than either erroring or |
559 | // accepting it weirdly. |
560 | Feature = Feature.trim(); |
561 | |
562 | // TODO: Support the fpmath option. It will require checking |
563 | // overall feature validity for the function with the rest of the |
564 | // attributes on the function. |
565 | if (Feature.starts_with(Prefix: "fpmath=" )) |
566 | continue; |
567 | |
568 | if (Feature.starts_with(Prefix: "branch-protection=" )) { |
569 | Ret.BranchProtection = Feature.split(Separator: '=').second.trim(); |
570 | continue; |
571 | } |
572 | |
573 | // While we're here iterating check for a different target cpu. |
574 | if (Feature.starts_with(Prefix: "arch=" )) { |
575 | if (!Ret.CPU.empty()) |
576 | Ret.Duplicate = "arch=" ; |
577 | else |
578 | Ret.CPU = Feature.split(Separator: "=" ).second.trim(); |
579 | } else if (Feature.starts_with(Prefix: "tune=" )) { |
580 | if (!Ret.Tune.empty()) |
581 | Ret.Duplicate = "tune=" ; |
582 | else |
583 | Ret.Tune = Feature.split(Separator: "=" ).second.trim(); |
584 | } else if (Feature.starts_with(Prefix: "no-" )) |
585 | Ret.Features.push_back(x: "-" + Feature.split(Separator: "-" ).second.str()); |
586 | else |
587 | Ret.Features.push_back(x: "+" + Feature.str()); |
588 | } |
589 | return Ret; |
590 | } |
591 | |
592 | TargetInfo::CallingConvKind |
593 | TargetInfo::getCallingConvKind(bool ClangABICompat4) const { |
594 | if (getCXXABI() != TargetCXXABI::Microsoft && |
595 | (ClangABICompat4 || getTriple().isPS4())) |
596 | return CCK_ClangABI4OrPS4; |
597 | return CCK_Default; |
598 | } |
599 | |
600 | bool TargetInfo::areDefaultedSMFStillPOD(const LangOptions &LangOpts) const { |
601 | return LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver15; |
602 | } |
603 | |
604 | LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const { |
605 | switch (TK) { |
606 | case OCLTK_Image: |
607 | case OCLTK_Pipe: |
608 | return LangAS::opencl_global; |
609 | |
610 | case OCLTK_Sampler: |
611 | return LangAS::opencl_constant; |
612 | |
613 | default: |
614 | return LangAS::Default; |
615 | } |
616 | } |
617 | |
618 | //===----------------------------------------------------------------------===// |
619 | |
620 | |
621 | static StringRef removeGCCRegisterPrefix(StringRef Name) { |
622 | if (Name[0] == '%' || Name[0] == '#') |
623 | Name = Name.substr(Start: 1); |
624 | |
625 | return Name; |
626 | } |
627 | |
628 | /// isValidClobber - Returns whether the passed in string is |
629 | /// a valid clobber in an inline asm statement. This is used by |
630 | /// Sema. |
631 | bool TargetInfo::isValidClobber(StringRef Name) const { |
632 | return (isValidGCCRegisterName(Name) || Name == "memory" || Name == "cc" || |
633 | Name == "unwind" ); |
634 | } |
635 | |
636 | /// isValidGCCRegisterName - Returns whether the passed in string |
637 | /// is a valid register name according to GCC. This is used by Sema for |
638 | /// inline asm statements. |
639 | bool TargetInfo::isValidGCCRegisterName(StringRef Name) const { |
640 | if (Name.empty()) |
641 | return false; |
642 | |
643 | // Get rid of any register prefix. |
644 | Name = removeGCCRegisterPrefix(Name); |
645 | if (Name.empty()) |
646 | return false; |
647 | |
648 | ArrayRef<const char *> Names = getGCCRegNames(); |
649 | |
650 | // If we have a number it maps to an entry in the register name array. |
651 | if (isDigit(c: Name[0])) { |
652 | unsigned n; |
653 | if (!Name.getAsInteger(Radix: 0, Result&: n)) |
654 | return n < Names.size(); |
655 | } |
656 | |
657 | // Check register names. |
658 | if (llvm::is_contained(Range&: Names, Element: Name)) |
659 | return true; |
660 | |
661 | // Check any additional names that we have. |
662 | for (const AddlRegName &ARN : getGCCAddlRegNames()) |
663 | for (const char *AN : ARN.Names) { |
664 | if (!AN) |
665 | break; |
666 | // Make sure the register that the additional name is for is within |
667 | // the bounds of the register names from above. |
668 | if (AN == Name && ARN.RegNum < Names.size()) |
669 | return true; |
670 | } |
671 | |
672 | // Now check aliases. |
673 | for (const GCCRegAlias &GRA : getGCCRegAliases()) |
674 | for (const char *A : GRA.Aliases) { |
675 | if (!A) |
676 | break; |
677 | if (A == Name) |
678 | return true; |
679 | } |
680 | |
681 | return false; |
682 | } |
683 | |
684 | StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name, |
685 | bool ReturnCanonical) const { |
686 | assert(isValidGCCRegisterName(Name) && "Invalid register passed in" ); |
687 | |
688 | // Get rid of any register prefix. |
689 | Name = removeGCCRegisterPrefix(Name); |
690 | |
691 | ArrayRef<const char *> Names = getGCCRegNames(); |
692 | |
693 | // First, check if we have a number. |
694 | if (isDigit(c: Name[0])) { |
695 | unsigned n; |
696 | if (!Name.getAsInteger(Radix: 0, Result&: n)) { |
697 | assert(n < Names.size() && "Out of bounds register number!" ); |
698 | return Names[n]; |
699 | } |
700 | } |
701 | |
702 | // Check any additional names that we have. |
703 | for (const AddlRegName &ARN : getGCCAddlRegNames()) |
704 | for (const char *AN : ARN.Names) { |
705 | if (!AN) |
706 | break; |
707 | // Make sure the register that the additional name is for is within |
708 | // the bounds of the register names from above. |
709 | if (AN == Name && ARN.RegNum < Names.size()) |
710 | return ReturnCanonical ? Names[ARN.RegNum] : Name; |
711 | } |
712 | |
713 | // Now check aliases. |
714 | for (const GCCRegAlias &RA : getGCCRegAliases()) |
715 | for (const char *A : RA.Aliases) { |
716 | if (!A) |
717 | break; |
718 | if (A == Name) |
719 | return RA.Register; |
720 | } |
721 | |
722 | return Name; |
723 | } |
724 | |
725 | bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const { |
726 | const char *Name = Info.getConstraintStr().c_str(); |
727 | // An output constraint must start with '=' or '+' |
728 | if (*Name != '=' && *Name != '+') |
729 | return false; |
730 | |
731 | if (*Name == '+') |
732 | Info.setIsReadWrite(); |
733 | |
734 | Name++; |
735 | while (*Name) { |
736 | switch (*Name) { |
737 | default: |
738 | if (!validateAsmConstraint(Name, info&: Info)) { |
739 | // FIXME: We temporarily return false |
740 | // so we can add more constraints as we hit it. |
741 | // Eventually, an unknown constraint should just be treated as 'g'. |
742 | return false; |
743 | } |
744 | break; |
745 | case '&': // early clobber. |
746 | Info.setEarlyClobber(); |
747 | break; |
748 | case '%': // commutative. |
749 | // FIXME: Check that there is a another register after this one. |
750 | break; |
751 | case 'r': // general register. |
752 | Info.setAllowsRegister(); |
753 | break; |
754 | case 'm': // memory operand. |
755 | case 'o': // offsetable memory operand. |
756 | case 'V': // non-offsetable memory operand. |
757 | case '<': // autodecrement memory operand. |
758 | case '>': // autoincrement memory operand. |
759 | Info.setAllowsMemory(); |
760 | break; |
761 | case 'g': // general register, memory operand or immediate integer. |
762 | case 'X': // any operand. |
763 | Info.setAllowsRegister(); |
764 | Info.setAllowsMemory(); |
765 | break; |
766 | case ',': // multiple alternative constraint. Pass it. |
767 | // Handle additional optional '=' or '+' modifiers. |
768 | if (Name[1] == '=' || Name[1] == '+') |
769 | Name++; |
770 | break; |
771 | case '#': // Ignore as constraint. |
772 | while (Name[1] && Name[1] != ',') |
773 | Name++; |
774 | break; |
775 | case '?': // Disparage slightly code. |
776 | case '!': // Disparage severely. |
777 | case '*': // Ignore for choosing register preferences. |
778 | case 'i': // Ignore i,n,E,F as output constraints (match from the other |
779 | // chars) |
780 | case 'n': |
781 | case 'E': |
782 | case 'F': |
783 | break; // Pass them. |
784 | } |
785 | |
786 | Name++; |
787 | } |
788 | |
789 | // Early clobber with a read-write constraint which doesn't permit registers |
790 | // is invalid. |
791 | if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister()) |
792 | return false; |
793 | |
794 | // If a constraint allows neither memory nor register operands it contains |
795 | // only modifiers. Reject it. |
796 | return Info.allowsMemory() || Info.allowsRegister(); |
797 | } |
798 | |
799 | bool TargetInfo::resolveSymbolicName(const char *&Name, |
800 | ArrayRef<ConstraintInfo> OutputConstraints, |
801 | unsigned &Index) const { |
802 | assert(*Name == '[' && "Symbolic name did not start with '['" ); |
803 | Name++; |
804 | const char *Start = Name; |
805 | while (*Name && *Name != ']') |
806 | Name++; |
807 | |
808 | if (!*Name) { |
809 | // Missing ']' |
810 | return false; |
811 | } |
812 | |
813 | std::string SymbolicName(Start, Name - Start); |
814 | |
815 | for (Index = 0; Index != OutputConstraints.size(); ++Index) |
816 | if (SymbolicName == OutputConstraints[Index].getName()) |
817 | return true; |
818 | |
819 | return false; |
820 | } |
821 | |
822 | bool TargetInfo::validateInputConstraint( |
823 | MutableArrayRef<ConstraintInfo> OutputConstraints, |
824 | ConstraintInfo &Info) const { |
825 | const char *Name = Info.ConstraintStr.c_str(); |
826 | |
827 | if (!*Name) |
828 | return false; |
829 | |
830 | while (*Name) { |
831 | switch (*Name) { |
832 | default: |
833 | // Check if we have a matching constraint |
834 | if (*Name >= '0' && *Name <= '9') { |
835 | const char *DigitStart = Name; |
836 | while (Name[1] >= '0' && Name[1] <= '9') |
837 | Name++; |
838 | const char *DigitEnd = Name; |
839 | unsigned i; |
840 | if (StringRef(DigitStart, DigitEnd - DigitStart + 1) |
841 | .getAsInteger(Radix: 10, Result&: i)) |
842 | return false; |
843 | |
844 | // Check if matching constraint is out of bounds. |
845 | if (i >= OutputConstraints.size()) return false; |
846 | |
847 | // A number must refer to an output only operand. |
848 | if (OutputConstraints[i].isReadWrite()) |
849 | return false; |
850 | |
851 | // If the constraint is already tied, it must be tied to the |
852 | // same operand referenced to by the number. |
853 | if (Info.hasTiedOperand() && Info.getTiedOperand() != i) |
854 | return false; |
855 | |
856 | // The constraint should have the same info as the respective |
857 | // output constraint. |
858 | Info.setTiedOperand(N: i, Output&: OutputConstraints[i]); |
859 | } else if (!validateAsmConstraint(Name, info&: Info)) { |
860 | // FIXME: This error return is in place temporarily so we can |
861 | // add more constraints as we hit it. Eventually, an unknown |
862 | // constraint should just be treated as 'g'. |
863 | return false; |
864 | } |
865 | break; |
866 | case '[': { |
867 | unsigned Index = 0; |
868 | if (!resolveSymbolicName(Name, OutputConstraints, Index)) |
869 | return false; |
870 | |
871 | // If the constraint is already tied, it must be tied to the |
872 | // same operand referenced to by the number. |
873 | if (Info.hasTiedOperand() && Info.getTiedOperand() != Index) |
874 | return false; |
875 | |
876 | // A number must refer to an output only operand. |
877 | if (OutputConstraints[Index].isReadWrite()) |
878 | return false; |
879 | |
880 | Info.setTiedOperand(N: Index, Output&: OutputConstraints[Index]); |
881 | break; |
882 | } |
883 | case '%': // commutative |
884 | // FIXME: Fail if % is used with the last operand. |
885 | break; |
886 | case 'i': // immediate integer. |
887 | break; |
888 | case 'n': // immediate integer with a known value. |
889 | Info.setRequiresImmediate(); |
890 | break; |
891 | case 'I': // Various constant constraints with target-specific meanings. |
892 | case 'J': |
893 | case 'K': |
894 | case 'L': |
895 | case 'M': |
896 | case 'N': |
897 | case 'O': |
898 | case 'P': |
899 | if (!validateAsmConstraint(Name, info&: Info)) |
900 | return false; |
901 | break; |
902 | case 'r': // general register. |
903 | Info.setAllowsRegister(); |
904 | break; |
905 | case 'm': // memory operand. |
906 | case 'o': // offsettable memory operand. |
907 | case 'V': // non-offsettable memory operand. |
908 | case '<': // autodecrement memory operand. |
909 | case '>': // autoincrement memory operand. |
910 | Info.setAllowsMemory(); |
911 | break; |
912 | case 'g': // general register, memory operand or immediate integer. |
913 | case 'X': // any operand. |
914 | Info.setAllowsRegister(); |
915 | Info.setAllowsMemory(); |
916 | break; |
917 | case 'E': // immediate floating point. |
918 | case 'F': // immediate floating point. |
919 | case 'p': // address operand. |
920 | break; |
921 | case ',': // multiple alternative constraint. Ignore comma. |
922 | break; |
923 | case '#': // Ignore as constraint. |
924 | while (Name[1] && Name[1] != ',') |
925 | Name++; |
926 | break; |
927 | case '?': // Disparage slightly code. |
928 | case '!': // Disparage severely. |
929 | case '*': // Ignore for choosing register preferences. |
930 | break; // Pass them. |
931 | } |
932 | |
933 | Name++; |
934 | } |
935 | |
936 | return true; |
937 | } |
938 | |
939 | bool TargetInfo::validatePointerAuthKey(const llvm::APSInt &value) const { |
940 | return false; |
941 | } |
942 | |
943 | void TargetInfo::CheckFixedPointBits() const { |
944 | // Check that the number of fractional and integral bits (and maybe sign) can |
945 | // fit into the bits given for a fixed point type. |
946 | assert(ShortAccumScale + getShortAccumIBits() + 1 <= ShortAccumWidth); |
947 | assert(AccumScale + getAccumIBits() + 1 <= AccumWidth); |
948 | assert(LongAccumScale + getLongAccumIBits() + 1 <= LongAccumWidth); |
949 | assert(getUnsignedShortAccumScale() + getUnsignedShortAccumIBits() <= |
950 | ShortAccumWidth); |
951 | assert(getUnsignedAccumScale() + getUnsignedAccumIBits() <= AccumWidth); |
952 | assert(getUnsignedLongAccumScale() + getUnsignedLongAccumIBits() <= |
953 | LongAccumWidth); |
954 | |
955 | assert(getShortFractScale() + 1 <= ShortFractWidth); |
956 | assert(getFractScale() + 1 <= FractWidth); |
957 | assert(getLongFractScale() + 1 <= LongFractWidth); |
958 | assert(getUnsignedShortFractScale() <= ShortFractWidth); |
959 | assert(getUnsignedFractScale() <= FractWidth); |
960 | assert(getUnsignedLongFractScale() <= LongFractWidth); |
961 | |
962 | // Each unsigned fract type has either the same number of fractional bits |
963 | // as, or one more fractional bit than, its corresponding signed fract type. |
964 | assert(getShortFractScale() == getUnsignedShortFractScale() || |
965 | getShortFractScale() == getUnsignedShortFractScale() - 1); |
966 | assert(getFractScale() == getUnsignedFractScale() || |
967 | getFractScale() == getUnsignedFractScale() - 1); |
968 | assert(getLongFractScale() == getUnsignedLongFractScale() || |
969 | getLongFractScale() == getUnsignedLongFractScale() - 1); |
970 | |
971 | // When arranged in order of increasing rank (see 6.3.1.3a), the number of |
972 | // fractional bits is nondecreasing for each of the following sets of |
973 | // fixed-point types: |
974 | // - signed fract types |
975 | // - unsigned fract types |
976 | // - signed accum types |
977 | // - unsigned accum types. |
978 | assert(getLongFractScale() >= getFractScale() && |
979 | getFractScale() >= getShortFractScale()); |
980 | assert(getUnsignedLongFractScale() >= getUnsignedFractScale() && |
981 | getUnsignedFractScale() >= getUnsignedShortFractScale()); |
982 | assert(LongAccumScale >= AccumScale && AccumScale >= ShortAccumScale); |
983 | assert(getUnsignedLongAccumScale() >= getUnsignedAccumScale() && |
984 | getUnsignedAccumScale() >= getUnsignedShortAccumScale()); |
985 | |
986 | // When arranged in order of increasing rank (see 6.3.1.3a), the number of |
987 | // integral bits is nondecreasing for each of the following sets of |
988 | // fixed-point types: |
989 | // - signed accum types |
990 | // - unsigned accum types |
991 | assert(getLongAccumIBits() >= getAccumIBits() && |
992 | getAccumIBits() >= getShortAccumIBits()); |
993 | assert(getUnsignedLongAccumIBits() >= getUnsignedAccumIBits() && |
994 | getUnsignedAccumIBits() >= getUnsignedShortAccumIBits()); |
995 | |
996 | // Each signed accum type has at least as many integral bits as its |
997 | // corresponding unsigned accum type. |
998 | assert(getShortAccumIBits() >= getUnsignedShortAccumIBits()); |
999 | assert(getAccumIBits() >= getUnsignedAccumIBits()); |
1000 | assert(getLongAccumIBits() >= getUnsignedLongAccumIBits()); |
1001 | } |
1002 | |
1003 | void TargetInfo::copyAuxTarget(const TargetInfo *Aux) { |
1004 | auto *Target = static_cast<TransferrableTargetInfo*>(this); |
1005 | auto *Src = static_cast<const TransferrableTargetInfo*>(Aux); |
1006 | *Target = *Src; |
1007 | } |
1008 | |