1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "Hexagon.h" |
14 | #include "Targets.h" |
15 | #include "clang/Basic/MacroBuilder.h" |
16 | #include "clang/Basic/TargetBuiltins.h" |
17 | #include "llvm/ADT/StringSwitch.h" |
18 | |
19 | using namespace clang; |
20 | using namespace clang::targets; |
21 | |
22 | void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, |
23 | MacroBuilder &Builder) const { |
24 | Builder.defineMacro("__qdsp6__", "1"); |
25 | Builder.defineMacro("__hexagon__", "1"); |
26 | |
27 | if (CPU == "hexagonv5") { |
28 | Builder.defineMacro("__HEXAGON_V5__"); |
29 | Builder.defineMacro("__HEXAGON_ARCH__", "5"); |
30 | if (Opts.HexagonQdsp6Compat) { |
31 | Builder.defineMacro("__QDSP6_V5__"); |
32 | Builder.defineMacro("__QDSP6_ARCH__", "5"); |
33 | } |
34 | } else if (CPU == "hexagonv55") { |
35 | Builder.defineMacro("__HEXAGON_V55__"); |
36 | Builder.defineMacro("__HEXAGON_ARCH__", "55"); |
37 | Builder.defineMacro("__QDSP6_V55__"); |
38 | Builder.defineMacro("__QDSP6_ARCH__", "55"); |
39 | } else if (CPU == "hexagonv60") { |
40 | Builder.defineMacro("__HEXAGON_V60__"); |
41 | Builder.defineMacro("__HEXAGON_ARCH__", "60"); |
42 | Builder.defineMacro("__QDSP6_V60__"); |
43 | Builder.defineMacro("__QDSP6_ARCH__", "60"); |
44 | } else if (CPU == "hexagonv62") { |
45 | Builder.defineMacro("__HEXAGON_V62__"); |
46 | Builder.defineMacro("__HEXAGON_ARCH__", "62"); |
47 | } else if (CPU == "hexagonv65") { |
48 | Builder.defineMacro("__HEXAGON_V65__"); |
49 | Builder.defineMacro("__HEXAGON_ARCH__", "65"); |
50 | } else if (CPU == "hexagonv66") { |
51 | Builder.defineMacro("__HEXAGON_V66__"); |
52 | Builder.defineMacro("__HEXAGON_ARCH__", "66"); |
53 | } |
54 | |
55 | if (hasFeature("hvx-length64b")) { |
56 | Builder.defineMacro("__HVX__"); |
57 | Builder.defineMacro("__HVX_ARCH__", HVXVersion); |
58 | Builder.defineMacro("__HVX_LENGTH__", "64"); |
59 | } |
60 | |
61 | if (hasFeature("hvx-length128b")) { |
62 | Builder.defineMacro("__HVX__"); |
63 | Builder.defineMacro("__HVX_ARCH__", HVXVersion); |
64 | Builder.defineMacro("__HVX_LENGTH__", "128"); |
65 | |
66 | Builder.defineMacro("__HVXDBL__"); |
67 | } |
68 | } |
69 | |
70 | bool HexagonTargetInfo::initFeatureMap( |
71 | llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, |
72 | const std::vector<std::string> &FeaturesVec) const { |
73 | Features["long-calls"] = false; |
74 | |
75 | return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); |
76 | } |
77 | |
78 | bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, |
79 | DiagnosticsEngine &Diags) { |
80 | for (auto &F : Features) { |
81 | if (F == "+hvx-length64b") |
82 | HasHVX = HasHVX64B = true; |
83 | else if (F == "+hvx-length128b") |
84 | HasHVX = HasHVX128B = true; |
85 | else if (F.find("+hvxv") != std::string::npos) { |
86 | HasHVX = true; |
87 | HVXVersion = F.substr(std::string("+hvxv").length()); |
88 | } else if (F == "-hvx") |
89 | HasHVX = HasHVX64B = HasHVX128B = false; |
90 | else if (F == "+long-calls") |
91 | UseLongCalls = true; |
92 | else if (F == "-long-calls") |
93 | UseLongCalls = false; |
94 | } |
95 | return true; |
96 | } |
97 | |
98 | const char *const HexagonTargetInfo::GCCRegNames[] = { |
99 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", |
100 | "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", |
101 | "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", |
102 | "r27", "r28", "r29", "r30", "r31", "p0", "p1", "p2", "p3", |
103 | "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp" |
104 | }; |
105 | |
106 | ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const { |
107 | return llvm::makeArrayRef(GCCRegNames); |
108 | } |
109 | |
110 | const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = { |
111 | {{"sp"}, "r29"}, |
112 | {{"fp"}, "r30"}, |
113 | {{"lr"}, "r31"}, |
114 | }; |
115 | |
116 | ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const { |
117 | return llvm::makeArrayRef(GCCRegAliases); |
118 | } |
119 | |
120 | const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { |
121 | #define BUILTIN(ID, TYPE, ATTRS) \ |
122 | {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, |
123 | #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ |
124 | {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr}, |
125 | #include "clang/Basic/BuiltinsHexagon.def" |
126 | }; |
127 | |
128 | bool HexagonTargetInfo::hasFeature(StringRef Feature) const { |
129 | std::string VS = "hvxv" + HVXVersion; |
130 | if (Feature == VS) |
131 | return true; |
132 | |
133 | return llvm::StringSwitch<bool>(Feature) |
134 | .Case("hexagon", true) |
135 | .Case("hvx", HasHVX) |
136 | .Case("hvx-length64b", HasHVX64B) |
137 | .Case("hvx-length128b", HasHVX128B) |
138 | .Case("long-calls", UseLongCalls) |
139 | .Default(false); |
140 | } |
141 | |
142 | struct CPUSuffix { |
143 | llvm::StringLiteral Name; |
144 | llvm::StringLiteral Suffix; |
145 | }; |
146 | |
147 | static constexpr CPUSuffix Suffixes[] = { |
148 | {{"hexagonv5"}, {"5"}}, {{"hexagonv55"}, {"55"}}, |
149 | {{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}}, |
150 | {{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}}, |
151 | }; |
152 | |
153 | const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) { |
154 | const CPUSuffix *Item = llvm::find_if( |
155 | Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; }); |
156 | if (Item == std::end(Suffixes)) |
157 | return nullptr; |
158 | return Item->Suffix.data(); |
159 | } |
160 | |
161 | void HexagonTargetInfo::fillValidCPUList( |
162 | SmallVectorImpl<StringRef> &Values) const { |
163 | for (const CPUSuffix &Suffix : Suffixes) |
164 | Values.push_back(Suffix.Name); |
165 | } |
166 | |
167 | ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const { |
168 | return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin - |
169 | Builtin::FirstTSBuiltin); |
170 | } |
171 | |