xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.h (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
1 //===--- Hexagon.h - Declare Hexagon target feature support -----*- C++ -*-===//
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 declares Hexagon TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H
14 #define LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H
15 
16 #include "clang/Basic/TargetInfo.h"
17 #include "clang/Basic/TargetOptions.h"
18 #include "llvm/Support/Compiler.h"
19 #include "llvm/TargetParser/Triple.h"
20 #include <optional>
21 
22 namespace clang {
23 namespace targets {
24 
25 // Hexagon abstract base class
26 class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo {
27 
28   static const char *const GCCRegNames[];
29   static const TargetInfo::GCCRegAlias GCCRegAliases[];
30   std::string CPU;
31   std::string HVXVersion;
32   bool HasHVX = false;
33   bool HasHVX64B = false;
34   bool HasHVX128B = false;
35   bool HasAudio = false;
36   bool UseLongCalls = false;
37 
38 public:
39   HexagonTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
40       : TargetInfo(Triple) {
41     // Specify the vector alignment explicitly. For v512x1, the calculated
42     // alignment would be 512*alignment(i1), which is 512 bytes, instead of
43     // the required minimum of 64 bytes.
44     resetDataLayout(
45         "e-m:e-p:32:32:32-a:0-n16:32-"
46         "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-"
47         "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048");
48     SizeType = UnsignedInt;
49     PtrDiffType = SignedInt;
50     IntPtrType = SignedInt;
51 
52     // {} in inline assembly are packet specifiers, not assembly variant
53     // specifiers.
54     NoAsmVariants = true;
55 
56     LargeArrayMinWidth = 64;
57     LargeArrayAlign = 64;
58     UseBitFieldTypeAlignment = true;
59     ZeroLengthBitfieldBoundary = 32;
60     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
61 
62     // These are the default values anyway, but explicitly make sure
63     // that the size of the boolean type is 8 bits. Bool vectors are used
64     // for modeling predicate registers in HVX, and the bool -> byte
65     // correspondence matches the HVX architecture.
66     BoolWidth = BoolAlign = 8;
67   }
68 
69   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
70 
71   bool validateAsmConstraint(const char *&Name,
72                              TargetInfo::ConstraintInfo &Info) const override {
73     switch (*Name) {
74     case 'v':
75     case 'q':
76       if (HasHVX) {
77         Info.setAllowsRegister();
78         return true;
79       }
80       break;
81     case 'a': // Modifier register m0-m1.
82       Info.setAllowsRegister();
83       return true;
84     case 's':
85       // Relocatable constant.
86       return true;
87     }
88     return false;
89   }
90 
91   void getTargetDefines(const LangOptions &Opts,
92                         MacroBuilder &Builder) const override;
93 
94   bool isCLZForZeroUndef() const override { return false; }
95 
96   bool hasFeature(StringRef Feature) const override;
97 
98   bool
99   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
100                  StringRef CPU,
101                  const std::vector<std::string> &FeaturesVec) const override;
102 
103   bool handleTargetFeatures(std::vector<std::string> &Features,
104                             DiagnosticsEngine &Diags) override;
105 
106   BuiltinVaListKind getBuiltinVaListKind() const override {
107     if (getTriple().isMusl())
108       return TargetInfo::HexagonBuiltinVaList;
109     return TargetInfo::CharPtrBuiltinVaList;
110   }
111 
112   ArrayRef<const char *> getGCCRegNames() const override;
113 
114   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
115 
116   std::string_view getClobbers() const override { return ""; }
117 
118   static const char *getHexagonCPUSuffix(StringRef Name);
119   static std::optional<unsigned> getHexagonCPURev(StringRef Name);
120 
121   bool isValidCPUName(StringRef Name) const override {
122     return getHexagonCPUSuffix(Name);
123   }
124 
125   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
126 
127   bool setCPU(const std::string &Name) override {
128     if (!isValidCPUName(Name))
129       return false;
130     CPU = Name;
131     return true;
132   }
133 
134   int getEHDataRegisterNumber(unsigned RegNo) const override {
135     return RegNo < 2 ? RegNo : -1;
136   }
137 
138   bool isTinyCore() const {
139     // We can write more stricter checks later.
140     return CPU.find('t') != std::string::npos;
141   }
142 
143   bool hasBitIntType() const override { return true; }
144 
145   std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
146     std::optional<unsigned> Rev = getHexagonCPURev(CPU);
147 
148     // V73 and later have 64-byte cache lines.
149     unsigned CacheLineSizeBytes = Rev >= 73U ? 64 : 32;
150     return std::make_pair(CacheLineSizeBytes, CacheLineSizeBytes);
151   }
152 };
153 } // namespace targets
154 } // namespace clang
155 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H
156