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/ADT/Triple.h"
19 #include "llvm/Support/Compiler.h"
20 
21 namespace clang {
22 namespace targets {
23 
24 // Hexagon abstract base class
25 class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo {
26 
27   static const Builtin::Info BuiltinInfo[];
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   const char *getClobbers() const override { return ""; }
117 
118   static const char *getHexagonCPUSuffix(StringRef Name);
119 
120   bool isValidCPUName(StringRef Name) const override {
121     return getHexagonCPUSuffix(Name);
122   }
123 
124   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
125 
126   bool setCPU(const std::string &Name) override {
127     if (!isValidCPUName(Name))
128       return false;
129     CPU = Name;
130     return true;
131   }
132 
133   int getEHDataRegisterNumber(unsigned RegNo) const override {
134     return RegNo < 2 ? RegNo : -1;
135   }
136 
137   bool isTinyCore() const {
138     // We can write more stricter checks later.
139     return CPU.find('t') != std::string::npos;
140   }
141 
142   bool hasBitIntType() const override { return true; }
143 };
144 } // namespace targets
145 } // namespace clang
146 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H
147