106f32e7eSjoerg //===--- Hexagon.h - Declare Hexagon target feature support -----*- C++ -*-===// 206f32e7eSjoerg // 306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information. 506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606f32e7eSjoerg // 706f32e7eSjoerg //===----------------------------------------------------------------------===// 806f32e7eSjoerg // 906f32e7eSjoerg // This file declares Hexagon TargetInfo objects. 1006f32e7eSjoerg // 1106f32e7eSjoerg //===----------------------------------------------------------------------===// 1206f32e7eSjoerg 1306f32e7eSjoerg #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H 1406f32e7eSjoerg #define LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H 1506f32e7eSjoerg 1606f32e7eSjoerg #include "clang/Basic/TargetInfo.h" 1706f32e7eSjoerg #include "clang/Basic/TargetOptions.h" 1806f32e7eSjoerg #include "llvm/ADT/Triple.h" 1906f32e7eSjoerg #include "llvm/Support/Compiler.h" 2006f32e7eSjoerg 2106f32e7eSjoerg namespace clang { 2206f32e7eSjoerg namespace targets { 2306f32e7eSjoerg 2406f32e7eSjoerg // Hexagon abstract base class 2506f32e7eSjoerg class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo { 2606f32e7eSjoerg 2706f32e7eSjoerg static const Builtin::Info BuiltinInfo[]; 2806f32e7eSjoerg static const char *const GCCRegNames[]; 2906f32e7eSjoerg static const TargetInfo::GCCRegAlias GCCRegAliases[]; 3006f32e7eSjoerg std::string CPU; 3106f32e7eSjoerg std::string HVXVersion; 3206f32e7eSjoerg bool HasHVX = false; 3306f32e7eSjoerg bool HasHVX64B = false; 3406f32e7eSjoerg bool HasHVX128B = false; 35*13fbcb42Sjoerg bool HasAudio = false; 3606f32e7eSjoerg bool UseLongCalls = false; 3706f32e7eSjoerg 3806f32e7eSjoerg public: HexagonTargetInfo(const llvm::Triple & Triple,const TargetOptions &)3906f32e7eSjoerg HexagonTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 4006f32e7eSjoerg : TargetInfo(Triple) { 4106f32e7eSjoerg // Specify the vector alignment explicitly. For v512x1, the calculated 4206f32e7eSjoerg // alignment would be 512*alignment(i1), which is 512 bytes, instead of 4306f32e7eSjoerg // the required minimum of 64 bytes. 4406f32e7eSjoerg resetDataLayout( 4506f32e7eSjoerg "e-m:e-p:32:32:32-a:0-n16:32-" 4606f32e7eSjoerg "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-" 4706f32e7eSjoerg "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"); 4806f32e7eSjoerg SizeType = UnsignedInt; 4906f32e7eSjoerg PtrDiffType = SignedInt; 5006f32e7eSjoerg IntPtrType = SignedInt; 5106f32e7eSjoerg 5206f32e7eSjoerg // {} in inline assembly are packet specifiers, not assembly variant 5306f32e7eSjoerg // specifiers. 5406f32e7eSjoerg NoAsmVariants = true; 5506f32e7eSjoerg 5606f32e7eSjoerg LargeArrayMinWidth = 64; 5706f32e7eSjoerg LargeArrayAlign = 64; 5806f32e7eSjoerg UseBitFieldTypeAlignment = true; 5906f32e7eSjoerg ZeroLengthBitfieldBoundary = 32; 60*13fbcb42Sjoerg MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 61*13fbcb42Sjoerg 62*13fbcb42Sjoerg // These are the default values anyway, but explicitly make sure 63*13fbcb42Sjoerg // that the size of the boolean type is 8 bits. Bool vectors are used 64*13fbcb42Sjoerg // for modeling predicate registers in HVX, and the bool -> byte 65*13fbcb42Sjoerg // correspondence matches the HVX architecture. 66*13fbcb42Sjoerg BoolWidth = BoolAlign = 8; 6706f32e7eSjoerg } 6806f32e7eSjoerg 6906f32e7eSjoerg ArrayRef<Builtin::Info> getTargetBuiltins() const override; 7006f32e7eSjoerg validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info)7106f32e7eSjoerg bool validateAsmConstraint(const char *&Name, 7206f32e7eSjoerg TargetInfo::ConstraintInfo &Info) const override { 7306f32e7eSjoerg switch (*Name) { 7406f32e7eSjoerg case 'v': 7506f32e7eSjoerg case 'q': 7606f32e7eSjoerg if (HasHVX) { 7706f32e7eSjoerg Info.setAllowsRegister(); 7806f32e7eSjoerg return true; 7906f32e7eSjoerg } 8006f32e7eSjoerg break; 8106f32e7eSjoerg case 'a': // Modifier register m0-m1. 8206f32e7eSjoerg Info.setAllowsRegister(); 8306f32e7eSjoerg return true; 8406f32e7eSjoerg case 's': 8506f32e7eSjoerg // Relocatable constant. 8606f32e7eSjoerg return true; 8706f32e7eSjoerg } 8806f32e7eSjoerg return false; 8906f32e7eSjoerg } 9006f32e7eSjoerg 9106f32e7eSjoerg void getTargetDefines(const LangOptions &Opts, 9206f32e7eSjoerg MacroBuilder &Builder) const override; 9306f32e7eSjoerg isCLZForZeroUndef()9406f32e7eSjoerg bool isCLZForZeroUndef() const override { return false; } 9506f32e7eSjoerg 9606f32e7eSjoerg bool hasFeature(StringRef Feature) const override; 9706f32e7eSjoerg 9806f32e7eSjoerg bool 9906f32e7eSjoerg initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 10006f32e7eSjoerg StringRef CPU, 10106f32e7eSjoerg const std::vector<std::string> &FeaturesVec) const override; 10206f32e7eSjoerg 10306f32e7eSjoerg bool handleTargetFeatures(std::vector<std::string> &Features, 10406f32e7eSjoerg DiagnosticsEngine &Diags) override; 10506f32e7eSjoerg getBuiltinVaListKind()10606f32e7eSjoerg BuiltinVaListKind getBuiltinVaListKind() const override { 107*13fbcb42Sjoerg if (getTriple().isMusl()) 108*13fbcb42Sjoerg return TargetInfo::HexagonBuiltinVaList; 10906f32e7eSjoerg return TargetInfo::CharPtrBuiltinVaList; 11006f32e7eSjoerg } 11106f32e7eSjoerg 11206f32e7eSjoerg ArrayRef<const char *> getGCCRegNames() const override; 11306f32e7eSjoerg 11406f32e7eSjoerg ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; 11506f32e7eSjoerg getClobbers()11606f32e7eSjoerg const char *getClobbers() const override { return ""; } 11706f32e7eSjoerg 11806f32e7eSjoerg static const char *getHexagonCPUSuffix(StringRef Name); 11906f32e7eSjoerg isValidCPUName(StringRef Name)12006f32e7eSjoerg bool isValidCPUName(StringRef Name) const override { 12106f32e7eSjoerg return getHexagonCPUSuffix(Name); 12206f32e7eSjoerg } 12306f32e7eSjoerg 12406f32e7eSjoerg void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 12506f32e7eSjoerg setCPU(const std::string & Name)12606f32e7eSjoerg bool setCPU(const std::string &Name) override { 12706f32e7eSjoerg if (!isValidCPUName(Name)) 12806f32e7eSjoerg return false; 12906f32e7eSjoerg CPU = Name; 13006f32e7eSjoerg return true; 13106f32e7eSjoerg } 13206f32e7eSjoerg getEHDataRegisterNumber(unsigned RegNo)13306f32e7eSjoerg int getEHDataRegisterNumber(unsigned RegNo) const override { 13406f32e7eSjoerg return RegNo < 2 ? RegNo : -1; 13506f32e7eSjoerg } 136*13fbcb42Sjoerg isTinyCore()137*13fbcb42Sjoerg bool isTinyCore() const { 138*13fbcb42Sjoerg // We can write more stricter checks later. 139*13fbcb42Sjoerg return CPU.find('t') != std::string::npos; 140*13fbcb42Sjoerg } 141*13fbcb42Sjoerg hasExtIntType()142*13fbcb42Sjoerg bool hasExtIntType() const override { return true; } 14306f32e7eSjoerg }; 14406f32e7eSjoerg } // namespace targets 14506f32e7eSjoerg } // namespace clang 14606f32e7eSjoerg #endif // LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H 147