diff options
Diffstat (limited to 'include/clang/Basic/TargetInfo.h')
-rw-r--r-- | include/clang/Basic/TargetInfo.h | 412 |
1 files changed, 309 insertions, 103 deletions
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 6ba58779114f5..ec5c59b239069 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief Defines the clang::TargetInfo interface. +/// Defines the clang::TargetInfo interface. /// //===----------------------------------------------------------------------===// @@ -20,7 +20,6 @@ #include "clang/Basic/Specifiers.h" #include "clang/Basic/TargetCXXABI.h" #include "clang/Basic/TargetOptions.h" -#include "clang/Basic/VersionTuple.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/Optional.h" @@ -30,6 +29,7 @@ #include "llvm/ADT/Triple.h" #include "llvm/IR/DataLayout.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/VersionTuple.h" #include <cassert> #include <string> #include <vector> @@ -49,7 +49,7 @@ class SourceManager; namespace Builtin { struct Info; } -/// \brief Exposes information about the current target. +/// Exposes information about the current target. /// class TargetInfo : public RefCountedBase<TargetInfo> { std::shared_ptr<TargetOptions> TargetOpts; @@ -61,6 +61,8 @@ protected: bool TLSSupported; bool VLASupported; bool NoAsmVariants; // True if {|} are normal characters. + bool HasLegalHalfType; // True if the backend supports operations on the half + // LLVM IR type. bool HasFloat128; unsigned char PointerWidth, PointerAlign; unsigned char BoolWidth, BoolAlign; @@ -72,6 +74,33 @@ protected: unsigned char LargeArrayMinWidth, LargeArrayAlign; unsigned char LongWidth, LongAlign; unsigned char LongLongWidth, LongLongAlign; + + // Fixed point bit widths + unsigned char ShortAccumWidth, ShortAccumAlign; + unsigned char AccumWidth, AccumAlign; + unsigned char LongAccumWidth, LongAccumAlign; + unsigned char ShortFractWidth, ShortFractAlign; + unsigned char FractWidth, FractAlign; + unsigned char LongFractWidth, LongFractAlign; + + // If true, unsigned fixed point types have the same number of fractional bits + // as their signed counterparts, forcing the unsigned types to have one extra + // bit of padding. Otherwise, unsigned fixed point types have + // one more fractional bit than its corresponding signed type. This is false + // by default. + bool PaddingOnUnsignedFixedPoint; + + // Fixed point integral and fractional bit sizes + // Saturated types share the same integral/fractional bits as their + // corresponding unsaturated types. + // For simplicity, the fractional bits in a _Fract type will be one less the + // width of that _Fract type. This leaves all signed _Fract types having no + // padding and unsigned _Fract types will only have 1 bit of padding after the + // sign if PaddingOnUnsignedFixedPoint is set. + unsigned char ShortAccumScale; + unsigned char AccumScale; + unsigned char LongAccumScale; + unsigned char SuitableAlign; unsigned char DefaultAlignForAttributeAligned; unsigned char MinGlobalAlign; @@ -107,7 +136,7 @@ protected: } public: - /// \brief Construct a target for the given options. + /// Construct a target for the given options. /// /// \param Opts - The options to use to initialize the target. The target may /// modify the options to canonicalize the target feature information to match @@ -118,7 +147,7 @@ public: virtual ~TargetInfo(); - /// \brief Retrieve the target options. + /// Retrieve the target options. TargetOptions &getTargetOpts() const { assert(TargetOpts && "Missing target options"); return *TargetOpts; @@ -147,7 +176,7 @@ public: Float128 }; - /// \brief The different kinds of __builtin_va_list types defined by + /// The different kinds of __builtin_va_list types defined by /// the target implementation. enum BuiltinVaListKind { /// typedef char* __builtin_va_list; @@ -193,7 +222,7 @@ protected: WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType, ProcessIDType; - /// \brief Whether Objective-C's built-in boolean type should be signed char. + /// Whether Objective-C's built-in boolean type should be signed char. /// /// Otherwise, when this flag is not set, the normal built-in boolean type is /// used. @@ -206,7 +235,7 @@ protected: /// boundary. unsigned UseBitFieldTypeAlignment : 1; - /// \brief Whether zero length bitfields (e.g., int : 0;) force alignment of + /// Whether zero length bitfields (e.g., int : 0;) force alignment of /// the next bitfield. /// /// If the alignment of the zero length bitfield is greater than the member @@ -214,14 +243,14 @@ protected: /// zero-length bitfield. unsigned UseZeroLengthBitfieldAlignment : 1; - /// \brief Whether explicit bit field alignment attributes are honored. + /// Whether explicit bit field alignment attributes are honored. unsigned UseExplicitBitFieldAlignment : 1; /// If non-zero, specifies a fixed alignment value for bitfields that follow /// zero length bitfield, regardless of the zero length bitfield type. unsigned ZeroLengthBitfieldBoundary; - /// \brief Specify if mangling based on address space map should be used or + /// Specify if mangling based on address space map should be used or /// not for language specific address spaces bool UseAddrSpaceMapMangling; @@ -283,30 +312,30 @@ public: } } - /// \brief Return the width (in bits) of the specified integer type enum. + /// Return the width (in bits) of the specified integer type enum. /// /// For example, SignedInt -> getIntWidth(). unsigned getTypeWidth(IntType T) const; - /// \brief Return integer type with specified width. + /// Return integer type with specified width. virtual IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const; - /// \brief Return the smallest integer type with at least the specified width. + /// Return the smallest integer type with at least the specified width. virtual IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const; - /// \brief Return floating point type with specified width. + /// Return floating point type with specified width. RealType getRealTypeByWidth(unsigned BitWidth) const; - /// \brief Return the alignment (in bits) of the specified integer type enum. + /// Return the alignment (in bits) of the specified integer type enum. /// /// For example, SignedInt -> getIntAlign(). unsigned getTypeAlign(IntType T) const; - /// \brief Returns true if the type is signed; false otherwise. + /// Returns true if the type is signed; false otherwise. static bool isTypeSigned(IntType T); - /// \brief Return the width of pointers on this target, for the + /// Return the width of pointers on this target, for the /// specified address space. uint64_t getPointerWidth(unsigned AddrSpace) const { return AddrSpace == 0 ? PointerWidth : getPointerWidthV(AddrSpace); @@ -315,29 +344,29 @@ public: return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace); } - /// \brief Return the maximum width of pointers on this target. + /// Return the maximum width of pointers on this target. virtual uint64_t getMaxPointerWidth() const { return PointerWidth; } - /// \brief Get integer value for null pointer. + /// Get integer value for null pointer. /// \param AddrSpace address space of pointee in source language. virtual uint64_t getNullPointerValue(LangAS AddrSpace) const { return 0; } - /// \brief Return the size of '_Bool' and C++ 'bool' for this target, in bits. + /// Return the size of '_Bool' and C++ 'bool' for this target, in bits. unsigned getBoolWidth() const { return BoolWidth; } - /// \brief Return the alignment of '_Bool' and C++ 'bool' for this target. + /// Return the alignment of '_Bool' and C++ 'bool' for this target. unsigned getBoolAlign() const { return BoolAlign; } unsigned getCharWidth() const { return 8; } // FIXME unsigned getCharAlign() const { return 8; } // FIXME - /// \brief Return the size of 'signed short' and 'unsigned short' for this + /// Return the size of 'signed short' and 'unsigned short' for this /// target, in bits. unsigned getShortWidth() const { return 16; } // FIXME - /// \brief Return the alignment of 'signed short' and 'unsigned short' for + /// Return the alignment of 'signed short' and 'unsigned short' for /// this target. unsigned getShortAlign() const { return 16; } // FIXME @@ -356,19 +385,135 @@ public: unsigned getLongLongWidth() const { return LongLongWidth; } unsigned getLongLongAlign() const { return LongLongAlign; } - /// \brief Determine whether the __int128 type is supported on this target. + /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and + /// 'unsigned short _Accum' for this target, in bits. + unsigned getShortAccumWidth() const { return ShortAccumWidth; } + unsigned getShortAccumAlign() const { return ShortAccumAlign; } + + /// getAccumWidth/Align - Return the size of 'signed _Accum' and + /// 'unsigned _Accum' for this target, in bits. + unsigned getAccumWidth() const { return AccumWidth; } + unsigned getAccumAlign() const { return AccumAlign; } + + /// getLongAccumWidth/Align - Return the size of 'signed long _Accum' and + /// 'unsigned long _Accum' for this target, in bits. + unsigned getLongAccumWidth() const { return LongAccumWidth; } + unsigned getLongAccumAlign() const { return LongAccumAlign; } + + /// getShortFractWidth/Align - Return the size of 'signed short _Fract' and + /// 'unsigned short _Fract' for this target, in bits. + unsigned getShortFractWidth() const { return ShortFractWidth; } + unsigned getShortFractAlign() const { return ShortFractAlign; } + + /// getFractWidth/Align - Return the size of 'signed _Fract' and + /// 'unsigned _Fract' for this target, in bits. + unsigned getFractWidth() const { return FractWidth; } + unsigned getFractAlign() const { return FractAlign; } + + /// getLongFractWidth/Align - Return the size of 'signed long _Fract' and + /// 'unsigned long _Fract' for this target, in bits. + unsigned getLongFractWidth() const { return LongFractWidth; } + unsigned getLongFractAlign() const { return LongFractAlign; } + + /// getShortAccumScale/IBits - Return the number of fractional/integral bits + /// in a 'signed short _Accum' type. + unsigned getShortAccumScale() const { return ShortAccumScale; } + unsigned getShortAccumIBits() const { + return ShortAccumWidth - ShortAccumScale - 1; + } + + /// getAccumScale/IBits - Return the number of fractional/integral bits + /// in a 'signed _Accum' type. + unsigned getAccumScale() const { return AccumScale; } + unsigned getAccumIBits() const { return AccumWidth - AccumScale - 1; } + + /// getLongAccumScale/IBits - Return the number of fractional/integral bits + /// in a 'signed long _Accum' type. + unsigned getLongAccumScale() const { return LongAccumScale; } + unsigned getLongAccumIBits() const { + return LongAccumWidth - LongAccumScale - 1; + } + + /// getUnsignedShortAccumScale/IBits - Return the number of + /// fractional/integral bits in a 'unsigned short _Accum' type. + unsigned getUnsignedShortAccumScale() const { + return PaddingOnUnsignedFixedPoint ? ShortAccumScale : ShortAccumScale + 1; + } + unsigned getUnsignedShortAccumIBits() const { + return PaddingOnUnsignedFixedPoint + ? getShortAccumIBits() + : ShortAccumWidth - getUnsignedShortAccumScale(); + } + + /// getUnsignedAccumScale/IBits - Return the number of fractional/integral + /// bits in a 'unsigned _Accum' type. + unsigned getUnsignedAccumScale() const { + return PaddingOnUnsignedFixedPoint ? AccumScale : AccumScale + 1; + } + unsigned getUnsignedAccumIBits() const { + return PaddingOnUnsignedFixedPoint ? getAccumIBits() + : AccumWidth - getUnsignedAccumScale(); + } + + /// getUnsignedLongAccumScale/IBits - Return the number of fractional/integral + /// bits in a 'unsigned long _Accum' type. + unsigned getUnsignedLongAccumScale() const { + return PaddingOnUnsignedFixedPoint ? LongAccumScale : LongAccumScale + 1; + } + unsigned getUnsignedLongAccumIBits() const { + return PaddingOnUnsignedFixedPoint + ? getLongAccumIBits() + : LongAccumWidth - getUnsignedLongAccumScale(); + } + + /// getShortFractScale - Return the number of fractional bits + /// in a 'signed short _Fract' type. + unsigned getShortFractScale() const { return ShortFractWidth - 1; } + + /// getFractScale - Return the number of fractional bits + /// in a 'signed _Fract' type. + unsigned getFractScale() const { return FractWidth - 1; } + + /// getLongFractScale - Return the number of fractional bits + /// in a 'signed long _Fract' type. + unsigned getLongFractScale() const { return LongFractWidth - 1; } + + /// getUnsignedShortFractScale - Return the number of fractional bits + /// in a 'unsigned short _Fract' type. + unsigned getUnsignedShortFractScale() const { + return PaddingOnUnsignedFixedPoint ? getShortFractScale() + : getShortFractScale() + 1; + } + + /// getUnsignedFractScale - Return the number of fractional bits + /// in a 'unsigned _Fract' type. + unsigned getUnsignedFractScale() const { + return PaddingOnUnsignedFixedPoint ? getFractScale() : getFractScale() + 1; + } + + /// getUnsignedLongFractScale - Return the number of fractional bits + /// in a 'unsigned long _Fract' type. + unsigned getUnsignedLongFractScale() const { + return PaddingOnUnsignedFixedPoint ? getLongFractScale() + : getLongFractScale() + 1; + } + + /// Determine whether the __int128 type is supported on this target. virtual bool hasInt128Type() const { - return getPointerWidth(0) >= 64; + return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128; } // FIXME - /// \brief Determine whether the __float128 type is supported on this target. + /// Determine whether _Float16 is supported on this target. + virtual bool hasLegalHalfType() const { return HasLegalHalfType; } + + /// Determine whether the __float128 type is supported on this target. virtual bool hasFloat128Type() const { return HasFloat128; } - /// \brief Return the alignment that is suitable for storing any + /// Return the alignment that is suitable for storing any /// object with a fundamental alignment requirement. unsigned getSuitableAlign() const { return SuitableAlign; } - /// \brief Return the default alignment for __attribute__((aligned)) on + /// Return the default alignment for __attribute__((aligned)) on /// this target, to be used if no alignment value is specified. unsigned getDefaultAlignForAttributeAligned() const { return DefaultAlignForAttributeAligned; @@ -431,11 +576,11 @@ public: return *Float128Format; } - /// \brief Return true if the 'long double' type should be mangled like + /// Return true if the 'long double' type should be mangled like /// __float128. virtual bool useFloat128ManglingForLongDouble() const { return false; } - /// \brief Return the value for the C99 FLT_EVAL_METHOD macro. + /// Return the value for the C99 FLT_EVAL_METHOD macro. virtual unsigned getFloatEvalMethod() const { return 0; } // getLargeArrayMinWidth/Align - Return the minimum array size that is @@ -443,16 +588,16 @@ public: unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; } unsigned getLargeArrayAlign() const { return LargeArrayAlign; } - /// \brief Return the maximum width lock-free atomic operation which will + /// Return the maximum width lock-free atomic operation which will /// ever be supported for the given target unsigned getMaxAtomicPromoteWidth() const { return MaxAtomicPromoteWidth; } - /// \brief Return the maximum width lock-free atomic operation which can be + /// Return the maximum width lock-free atomic operation which can be /// inlined given the supported features of the given target. unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; } - /// \brief Set the maximum inline or promote width lock-free atomic operation + /// Set the maximum inline or promote width lock-free atomic operation /// for the given target. virtual void setMaxAtomicWidth() {} - /// \brief Returns true if the given target supports lock-free atomic + /// Returns true if the given target supports lock-free atomic /// operations at the specified width and alignment. virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits, uint64_t AlignmentInBits) const { @@ -462,14 +607,14 @@ public: llvm::isPowerOf2_64(AtomicSizeInBits / getCharWidth())); } - /// \brief Return the maximum vector alignment supported for the given target. + /// Return the maximum vector alignment supported for the given target. unsigned getMaxVectorAlign() const { return MaxVectorAlign; } - /// \brief Return default simd alignment for the given target. Generally, this + /// Return default simd alignment for the given target. Generally, this /// value is type-specific, but this alignment can be used for most of the /// types for the given target. unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; } - /// \brief Return the size of intmax_t and uintmax_t for this target, in bits. + /// Return the size of intmax_t and uintmax_t for this target, in bits. unsigned getIntMaxTWidth() const { return getTypeWidth(IntMaxType); } @@ -477,7 +622,7 @@ public: // Return the size of unwind_word for this target. virtual unsigned getUnwindWordWidth() const { return getPointerWidth(0); } - /// \brief Return the "preferred" register width on this target. + /// Return the "preferred" register width on this target. virtual unsigned getRegisterWidth() const { // Currently we assume the register width on the target matches the pointer // width, we can introduce a new variable for this if/when some target wants @@ -485,12 +630,12 @@ public: return PointerWidth; } - /// \brief Returns the name of the mcount instrumentation function. + /// Returns the name of the mcount instrumentation function. const char *getMCountName() const { return MCountName; } - /// \brief Check if the Objective-C built-in boolean type should be signed + /// Check if the Objective-C built-in boolean type should be signed /// char. /// /// Otherwise, if this returns false, the normal built-in boolean type @@ -502,58 +647,58 @@ public: UseSignedCharForObjCBool = false; } - /// \brief Check whether the alignment of bit-field types is respected + /// Check whether the alignment of bit-field types is respected /// when laying out structures. bool useBitFieldTypeAlignment() const { return UseBitFieldTypeAlignment; } - /// \brief Check whether zero length bitfields should force alignment of + /// Check whether zero length bitfields should force alignment of /// the next member. bool useZeroLengthBitfieldAlignment() const { return UseZeroLengthBitfieldAlignment; } - /// \brief Get the fixed alignment value in bits for a member that follows + /// Get the fixed alignment value in bits for a member that follows /// a zero length bitfield. unsigned getZeroLengthBitfieldBoundary() const { return ZeroLengthBitfieldBoundary; } - /// \brief Check whether explicit bitfield alignment attributes should be + /// Check whether explicit bitfield alignment attributes should be // honored, as in "__attribute__((aligned(2))) int b : 1;". bool useExplicitBitFieldAlignment() const { return UseExplicitBitFieldAlignment; } - /// \brief Check whether this target support '\#pragma options align=mac68k'. + /// Check whether this target support '\#pragma options align=mac68k'. bool hasAlignMac68kSupport() const { return HasAlignMac68kSupport; } - /// \brief Return the user string for the specified integer type enum. + /// Return the user string for the specified integer type enum. /// /// For example, SignedShort -> "short". static const char *getTypeName(IntType T); - /// \brief Return the constant suffix for the specified integer type enum. + /// Return the constant suffix for the specified integer type enum. /// /// For example, SignedLong -> "L". const char *getTypeConstantSuffix(IntType T) const; - /// \brief Return the printf format modifier for the specified + /// Return the printf format modifier for the specified /// integer type enum. /// /// For example, SignedLong -> "l". static const char *getTypeFormatModifier(IntType T); - /// \brief Check whether the given real type should use the "fpret" flavor of + /// Check whether the given real type should use the "fpret" flavor of /// Objective-C message passing on this target. bool useObjCFPRetForRealType(RealType T) const { return RealTypeUsesObjCFPRet & (1 << T); } - /// \brief Check whether _Complex long double should use the "fp2ret" flavor + /// Check whether _Complex long double should use the "fp2ret" flavor /// of Objective-C message passing on this target. bool useObjCFP2RetForComplexLongDouble() const { return ComplexLongDoubleUsesFP2Ret; @@ -567,7 +712,7 @@ public: return true; } - /// \brief Specify if mangling based on address space map should be used or + /// Specify if mangling based on address space map should be used or /// not for language specific address spaces bool useAddressSpaceMapMangling() const { return UseAddrSpaceMapMangling; @@ -575,7 +720,7 @@ public: ///===---- Other target property query methods --------------------------===// - /// \brief Appends the target-specific \#define values for this + /// Appends the target-specific \#define values for this /// target set to the specified buffer. virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const = 0; @@ -593,7 +738,7 @@ public: /// idea to avoid optimizing based on that undef behavior. virtual bool isCLZForZeroUndef() const { return true; } - /// \brief Returns the kind of __builtin_va_list type that should be used + /// Returns the kind of __builtin_va_list type that should be used /// with this target. virtual BuiltinVaListKind getBuiltinVaListKind() const = 0; @@ -604,28 +749,34 @@ public: /// Returns true for RenderScript. bool isRenderScriptTarget() const { return IsRenderScriptTarget; } - /// \brief Returns whether the passed in string is a valid clobber in an + /// Returns whether the passed in string is a valid clobber in an /// inline asm statement. /// /// This is used by Sema. bool isValidClobber(StringRef Name) const; - /// \brief Returns whether the passed in string is a valid register name + /// Returns whether the passed in string is a valid register name /// according to GCC. /// /// This is used by Sema for inline asm statements. - bool isValidGCCRegisterName(StringRef Name) const; + virtual bool isValidGCCRegisterName(StringRef Name) const; - /// \brief Returns the "normalized" GCC register name. + /// Returns the "normalized" GCC register name. /// /// ReturnCannonical true will return the register name without any additions /// such as "{}" or "%" in it's canonical form, for example: /// ReturnCanonical = true and Name = "rax", will return "ax". StringRef getNormalizedGCCRegisterName(StringRef Name, bool ReturnCanonical = false) const; - - virtual StringRef getConstraintRegister(const StringRef &Constraint, - const StringRef &Expression) const { + + /// Extracts a register from the passed constraint (if it is a + /// single-register constraint) and the asm label expression related to a + /// variable in the input or output list of an inline asm statement. + /// + /// This function is used by Sema in order to diagnose conflicts between + /// the clobber list and the input/output lists. + virtual StringRef getConstraintRegister(StringRef Constraint, + StringRef Expression) const { return ""; } @@ -663,11 +814,11 @@ public: bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; } bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; } - /// \brief Return true if this output operand has a matching + /// Return true if this output operand has a matching /// (tied) input operand. bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; } - /// \brief Return true if this input operand is a matching + /// Return true if this input operand is a matching /// constraint that ties it to an output operand. /// /// If this returns true then getTiedOperand will indicate which output @@ -711,7 +862,7 @@ public: ImmRange.Max = INT_MAX; } - /// \brief Indicate that this is an input operand that is tied to + /// Indicate that this is an input operand that is tied to /// the specified output operand. /// /// Copy over the various constraint information from the output. @@ -723,7 +874,7 @@ public: } }; - /// \brief Validate register name used for global register variables. + /// Validate register name used for global register variables. /// /// This function returns true if the register passed in RegName can be used /// for global register variables on this target. In addition, it returns @@ -777,16 +928,16 @@ public: return std::string(1, *Constraint); } - /// \brief Returns a string of target-specific clobbers, in LLVM format. + /// Returns a string of target-specific clobbers, in LLVM format. virtual const char *getClobbers() const = 0; - /// \brief Returns true if NaN encoding is IEEE 754-2008. + /// Returns true if NaN encoding is IEEE 754-2008. /// Only MIPS allows a different encoding. virtual bool isNan2008() const { return true; } - /// \brief Returns the target triple of the primary target. + /// Returns the target triple of the primary target. const llvm::Triple &getTriple() const { return Triple; } @@ -806,7 +957,7 @@ public: const unsigned RegNum; }; - /// \brief Does this target support "protected" visibility? + /// Does this target support "protected" visibility? /// /// Any target which dynamic libraries will naturally support /// something like "default" (meaning that the symbol is visible @@ -818,7 +969,7 @@ public: /// either; the entire thing is pretty badly mangled. virtual bool hasProtectedVisibility() const { return true; } - /// \brief An optional hook that targets can implement to perform semantic + /// An optional hook that targets can implement to perform semantic /// checking on attribute((section("foo"))) specifiers. /// /// In this case, "foo" is passed in to be checked. If the section @@ -833,18 +984,18 @@ public: return ""; } - /// \brief Set forced language options. + /// Set forced language options. /// /// Apply changes to the target information with respect to certain /// language options which change the target configuration and adjust /// the language based on the target options where applicable. virtual void adjust(LangOptions &Opts); - /// \brief Adjust target options based on codegen options. + /// Adjust target options based on codegen options. virtual void adjustTargetOptions(const CodeGenOptions &CGOpts, TargetOptions &TargetOpts) const {} - /// \brief Initialize the map with the default set of target features for the + /// Initialize the map with the default set of target features for the /// CPU this should include all legal feature strings on the target. /// /// \return False on error (invalid features). @@ -852,41 +1003,44 @@ public: DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeatureVec) const; - /// \brief Get the ABI currently in use. + /// Get the ABI currently in use. virtual StringRef getABI() const { return StringRef(); } - /// \brief Get the C++ ABI currently in use. + /// Get the C++ ABI currently in use. TargetCXXABI getCXXABI() const { return TheCXXABI; } - /// \brief Target the specified CPU. + /// Target the specified CPU. /// /// \return False on error (invalid CPU name). virtual bool setCPU(const std::string &Name) { return false; } + /// Fill a SmallVectorImpl with the valid values to setCPU. + virtual void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {} + /// brief Determine whether this TargetInfo supports the given CPU name. virtual bool isValidCPUName(StringRef Name) const { return true; } - /// \brief Use the specified ABI. + /// Use the specified ABI. /// /// \return False on error (invalid ABI name). virtual bool setABI(const std::string &Name) { return false; } - /// \brief Use the specified unit for FP math. + /// Use the specified unit for FP math. /// /// \return False on error (invalid unit name). virtual bool setFPMath(StringRef Name) { return false; } - /// \brief Enable or disable a specific target feature; + /// Enable or disable a specific target feature; /// the feature name must be valid. virtual void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, @@ -894,12 +1048,12 @@ public: Features[Name] = Enabled; } - /// \brief Determine whether this TargetInfo supports the given feature. + /// Determine whether this TargetInfo supports the given feature. virtual bool isValidFeatureName(StringRef Feature) const { return true; } - /// \brief Perform initialization based on the user configured + /// Perform initialization based on the user configured /// set of features (e.g., +sse4). /// /// The list is guaranteed to have at most one entry per feature. @@ -915,31 +1069,62 @@ public: return true; } - /// \brief Determine whether the given target has the given feature. + /// Determine whether the given target has the given feature. virtual bool hasFeature(StringRef Feature) const { return false; } - // \brief Validate the contents of the __builtin_cpu_supports(const char*) + /// Identify whether this taret supports multiversioning of functions, + /// which requires support for cpu_supports and cpu_is functionality. + virtual bool supportsMultiVersioning() const { return false; } + + // Validate the contents of the __builtin_cpu_supports(const char*) // argument. virtual bool validateCpuSupports(StringRef Name) const { return false; } - // \brief Validate the contents of the __builtin_cpu_is(const char*) + // Return the target-specific priority for features/cpus/vendors so + // that they can be properly sorted for checking. + virtual unsigned multiVersionSortPriority(StringRef Name) const { + return 0; + } + + // Validate the contents of the __builtin_cpu_is(const char*) // argument. virtual bool validateCpuIs(StringRef Name) const { return false; } - // \brief Returns maximal number of args passed in registers. + // Validate a cpu_dispatch/cpu_specific CPU option, which is a different list + // from cpu_is, since it checks via features rather than CPUs directly. + virtual bool validateCPUSpecificCPUDispatch(StringRef Name) const { + return false; + } + + // Get the character to be added for mangling purposes for cpu_specific. + virtual char CPUSpecificManglingCharacter(StringRef Name) const { + llvm_unreachable( + "cpu_specific Multiversioning not implemented on this target"); + } + + // Get a list of the features that make up the CPU option for + // cpu_specific/cpu_dispatch so that it can be passed to llvm as optimization + // options. + virtual void getCPUSpecificCPUDispatchFeatures( + StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const { + llvm_unreachable( + "cpu_specific Multiversioning not implemented on this target"); + } + + // Returns maximal number of args passed in registers. unsigned getRegParmMax() const { assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle"); return RegParmMax; } - /// \brief Whether the target supports thread-local storage. + /// Whether the target supports thread-local storage. bool isTLSSupported() const { return TLSSupported; } - /// \brief Return the maximum alignment (in bits) of a TLS variable + /// Return the maximum alignment (in bits) of a TLS variable /// /// Gets the maximum alignment (in bits) of a TLS variable on this target. /// Returns zero if there is no such constraint. @@ -947,17 +1132,17 @@ public: return MaxTLSAlign; } - /// \brief Whether target supports variable-length arrays. + /// Whether target supports variable-length arrays. bool isVLASupported() const { return VLASupported; } - /// \brief Whether the target supports SEH __try. + /// Whether the target supports SEH __try. bool isSEHTrySupported() const { return getTriple().isOSWindows() && (getTriple().getArch() == llvm::Triple::x86 || getTriple().getArch() == llvm::Triple::x86_64); } - /// \brief Return true if {|} are normal characters in the asm string. + /// Return true if {|} are normal characters in the asm string. /// /// If this returns false (the default), then {abc|xyz} is syntax /// that says that when compiling for asm variant #0, "abc" should be @@ -967,7 +1152,7 @@ public: return NoAsmVariants; } - /// \brief Return the register number that __builtin_eh_return_regno would + /// Return the register number that __builtin_eh_return_regno would /// return with the specified argument. /// This corresponds with TargetLowering's getExceptionPointerRegister /// and getExceptionSelectorRegister in the backend. @@ -975,14 +1160,14 @@ public: return -1; } - /// \brief Return the section to use for C++ static initialization functions. + /// Return the section to use for C++ static initialization functions. virtual const char *getStaticInitSectionSpecifier() const { return nullptr; } const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; } - /// \brief Return an AST address space which can be used opportunistically + /// Return an AST address space which can be used opportunistically /// for constant global memory. It must be possible to convert pointers into /// this address space to LangAS::Default. If no such address space exists, /// this may return None, and such optimizations will be disabled. @@ -990,11 +1175,11 @@ public: return LangAS::Default; } - /// \brief Retrieve the name of the platform as it is used in the + /// Retrieve the name of the platform as it is used in the /// availability attribute. StringRef getPlatformName() const { return PlatformName; } - /// \brief Retrieve the minimum desired version of the platform, to + /// Retrieve the minimum desired version of the platform, to /// which the program should be compiled. VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; } @@ -1007,7 +1192,7 @@ public: CCMT_NonMember }; - /// \brief Gets the default calling convention for the given target and + /// Gets the default calling convention for the given target and /// declaration context. virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const { // Not all targets will specify an explicit calling convention that we can @@ -1022,7 +1207,7 @@ public: CCCR_Ignore, }; - /// \brief Determines whether a given calling convention is valid for the + /// Determines whether a given calling convention is valid for the /// target. A calling convention can either be accepted, produce a warning /// and be substituted with the default calling convention, or (someday) /// produce an error (such as using thiscall on a non-instance function). @@ -1035,31 +1220,47 @@ public: } } + enum CallingConvKind { + CCK_Default, + CCK_ClangABI4OrPS4, + CCK_MicrosoftWin64 + }; + + virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const; + /// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp. virtual bool hasSjLjLowering() const { return false; } - /// \brief Whether target allows to overalign ABI-specified preferred alignment + /// Check if the target supports CFProtection branch. + virtual bool + checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const; + + /// Check if the target supports CFProtection branch. + virtual bool + checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const; + + /// Whether target allows to overalign ABI-specified preferred alignment virtual bool allowsLargerPreferedTypeAlignment() const { return true; } - /// \brief Set supported OpenCL extensions and optional core features. + /// Set supported OpenCL extensions and optional core features. virtual void setSupportedOpenCLOpts() {} - /// \brief Set supported OpenCL extensions as written on command line + /// Set supported OpenCL extensions as written on command line virtual void setOpenCLExtensionOpts() { for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) { getTargetOpts().SupportedOpenCLOptions.support(Ext); } } - /// \brief Get supported OpenCL extensions and optional core features. + /// Get supported OpenCL extensions and optional core features. OpenCLOptions &getSupportedOpenCLOpts() { return getTargetOpts().SupportedOpenCLOptions; } - /// \brief Get const supported OpenCL extensions and optional core features. + /// Get const supported OpenCL extensions and optional core features. const OpenCLOptions &getSupportedOpenCLOpts() const { return getTargetOpts().SupportedOpenCLOptions; } @@ -1075,7 +1276,7 @@ public: OCLTK_Sampler, }; - /// \brief Get address space for OpenCL type. + /// Get address space for OpenCL type. virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const; /// \returns Target specific vtbl ptr address space. @@ -1093,7 +1294,7 @@ public: return None; } - /// \brief Check the target is valid after it is fully initialized. + /// Check the target is valid after it is fully initialized. virtual bool validateTarget(DiagnosticsEngine &Diags) const { return true; } @@ -1113,6 +1314,11 @@ protected: virtual ArrayRef<AddlRegName> getGCCAddlRegNames() const { return None; } + + private: + // Assert the values for the fractional and integral bits for each fixed point + // type follow the restrictions given in clause 6.2.6.3 of N1169. + void CheckFixedPointBits() const; }; } // end namespace clang |