10b57cec5SDimitry Andric //===--- Hexagon.h - Declare Hexagon target feature support -----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares Hexagon TargetInfo objects. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H 140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 170b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h" 180b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 190b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace clang { 220b57cec5SDimitry Andric namespace targets { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric // Hexagon abstract base class 250b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo { 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric static const Builtin::Info BuiltinInfo[]; 280b57cec5SDimitry Andric static const char *const GCCRegNames[]; 290b57cec5SDimitry Andric static const TargetInfo::GCCRegAlias GCCRegAliases[]; 300b57cec5SDimitry Andric std::string CPU; 310b57cec5SDimitry Andric std::string HVXVersion; 320b57cec5SDimitry Andric bool HasHVX = false; 330b57cec5SDimitry Andric bool HasHVX64B = false; 340b57cec5SDimitry Andric bool HasHVX128B = false; 35*5ffd83dbSDimitry Andric bool HasAudio = false; 360b57cec5SDimitry Andric bool UseLongCalls = false; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric public: 390b57cec5SDimitry Andric HexagonTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 400b57cec5SDimitry Andric : TargetInfo(Triple) { 410b57cec5SDimitry Andric // Specify the vector alignment explicitly. For v512x1, the calculated 420b57cec5SDimitry Andric // alignment would be 512*alignment(i1), which is 512 bytes, instead of 430b57cec5SDimitry Andric // the required minimum of 64 bytes. 440b57cec5SDimitry Andric resetDataLayout( 450b57cec5SDimitry Andric "e-m:e-p:32:32:32-a:0-n16:32-" 460b57cec5SDimitry Andric "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-" 470b57cec5SDimitry Andric "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"); 480b57cec5SDimitry Andric SizeType = UnsignedInt; 490b57cec5SDimitry Andric PtrDiffType = SignedInt; 500b57cec5SDimitry Andric IntPtrType = SignedInt; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric // {} in inline assembly are packet specifiers, not assembly variant 530b57cec5SDimitry Andric // specifiers. 540b57cec5SDimitry Andric NoAsmVariants = true; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric LargeArrayMinWidth = 64; 570b57cec5SDimitry Andric LargeArrayAlign = 64; 580b57cec5SDimitry Andric UseBitFieldTypeAlignment = true; 590b57cec5SDimitry Andric ZeroLengthBitfieldBoundary = 32; 60*5ffd83dbSDimitry Andric MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 61*5ffd83dbSDimitry Andric 62*5ffd83dbSDimitry Andric // These are the default values anyway, but explicitly make sure 63*5ffd83dbSDimitry Andric // that the size of the boolean type is 8 bits. Bool vectors are used 64*5ffd83dbSDimitry Andric // for modeling predicate registers in HVX, and the bool -> byte 65*5ffd83dbSDimitry Andric // correspondence matches the HVX architecture. 66*5ffd83dbSDimitry Andric BoolWidth = BoolAlign = 8; 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 720b57cec5SDimitry Andric TargetInfo::ConstraintInfo &Info) const override { 730b57cec5SDimitry Andric switch (*Name) { 740b57cec5SDimitry Andric case 'v': 750b57cec5SDimitry Andric case 'q': 760b57cec5SDimitry Andric if (HasHVX) { 770b57cec5SDimitry Andric Info.setAllowsRegister(); 780b57cec5SDimitry Andric return true; 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric break; 810b57cec5SDimitry Andric case 'a': // Modifier register m0-m1. 820b57cec5SDimitry Andric Info.setAllowsRegister(); 830b57cec5SDimitry Andric return true; 840b57cec5SDimitry Andric case 's': 850b57cec5SDimitry Andric // Relocatable constant. 860b57cec5SDimitry Andric return true; 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric return false; 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 920b57cec5SDimitry Andric MacroBuilder &Builder) const override; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric bool isCLZForZeroUndef() const override { return false; } 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric bool hasFeature(StringRef Feature) const override; 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric bool 990b57cec5SDimitry Andric initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 1000b57cec5SDimitry Andric StringRef CPU, 1010b57cec5SDimitry Andric const std::vector<std::string> &FeaturesVec) const override; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric bool handleTargetFeatures(std::vector<std::string> &Features, 1040b57cec5SDimitry Andric DiagnosticsEngine &Diags) override; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override { 107*5ffd83dbSDimitry Andric if (getTriple().isMusl()) 108*5ffd83dbSDimitry Andric return TargetInfo::HexagonBuiltinVaList; 1090b57cec5SDimitry Andric return TargetInfo::CharPtrBuiltinVaList; 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric ArrayRef<const char *> getGCCRegNames() const override; 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric const char *getClobbers() const override { return ""; } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric static const char *getHexagonCPUSuffix(StringRef Name); 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric bool isValidCPUName(StringRef Name) const override { 1210b57cec5SDimitry Andric return getHexagonCPUSuffix(Name); 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric bool setCPU(const std::string &Name) override { 1270b57cec5SDimitry Andric if (!isValidCPUName(Name)) 1280b57cec5SDimitry Andric return false; 1290b57cec5SDimitry Andric CPU = Name; 1300b57cec5SDimitry Andric return true; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric int getEHDataRegisterNumber(unsigned RegNo) const override { 1340b57cec5SDimitry Andric return RegNo < 2 ? RegNo : -1; 1350b57cec5SDimitry Andric } 136*5ffd83dbSDimitry Andric 137*5ffd83dbSDimitry Andric bool isTinyCore() const { 138*5ffd83dbSDimitry Andric // We can write more stricter checks later. 139*5ffd83dbSDimitry Andric return CPU.find('t') != std::string::npos; 140*5ffd83dbSDimitry Andric } 141*5ffd83dbSDimitry Andric 142*5ffd83dbSDimitry Andric bool hasExtIntType() const override { return true; } 1430b57cec5SDimitry Andric }; 1440b57cec5SDimitry Andric } // namespace targets 1450b57cec5SDimitry Andric } // namespace clang 1460b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H 147