/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/Sparc.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- Sparc.h - declare sparc 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 Sparc TargetInfo objects. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H |
14 | | #define LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H |
15 | | #include "clang/Basic/TargetInfo.h" |
16 | | #include "clang/Basic/TargetOptions.h" |
17 | | #include "llvm/ADT/Triple.h" |
18 | | #include "llvm/Support/Compiler.h" |
19 | | namespace clang { |
20 | | namespace targets { |
21 | | // Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit). |
22 | | class LLVM_LIBRARY_VISIBILITY SparcTargetInfo : public TargetInfo { |
23 | | static const TargetInfo::GCCRegAlias GCCRegAliases[]; |
24 | | static const char *const GCCRegNames[]; |
25 | | bool SoftFloat; |
26 | | |
27 | | public: |
28 | | SparcTargetInfo(const llvm::Triple &Triple, const TargetOptions &) |
29 | 88 | : TargetInfo(Triple), SoftFloat(false) {} |
30 | | |
31 | 0 | int getEHDataRegisterNumber(unsigned RegNo) const override { |
32 | 0 | if (RegNo == 0) |
33 | 0 | return 24; |
34 | 0 | if (RegNo == 1) |
35 | 0 | return 25; |
36 | 0 | return -1; |
37 | 0 | } |
38 | | |
39 | | bool handleTargetFeatures(std::vector<std::string> &Features, |
40 | 78 | DiagnosticsEngine &Diags) override { |
41 | | // Check if software floating point is enabled |
42 | 78 | if (llvm::is_contained(Features, "+soft-float")) |
43 | 1 | SoftFloat = true; |
44 | 78 | return true; |
45 | 78 | } |
46 | | void getTargetDefines(const LangOptions &Opts, |
47 | | MacroBuilder &Builder) const override; |
48 | | |
49 | | bool hasFeature(StringRef Feature) const override; |
50 | | |
51 | 78 | ArrayRef<Builtin::Info> getTargetBuiltins() const override { |
52 | | // FIXME: Implement! |
53 | 78 | return None; |
54 | 78 | } |
55 | 47 | BuiltinVaListKind getBuiltinVaListKind() const override { |
56 | 47 | return TargetInfo::VoidPtrBuiltinVaList; |
57 | 47 | } |
58 | | ArrayRef<const char *> getGCCRegNames() const override; |
59 | | ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; |
60 | | bool validateAsmConstraint(const char *&Name, |
61 | 40 | TargetInfo::ConstraintInfo &info) const override { |
62 | | // FIXME: Implement! |
63 | 40 | switch (*Name) { |
64 | 0 | case 'I': // Signed 13-bit constant |
65 | 0 | case 'J': // Zero |
66 | 0 | case 'K': // 32-bit constant with the low 12 bits clear |
67 | 0 | case 'L': // A constant in the range supported by movcc (11-bit signed imm) |
68 | 0 | case 'M': // A constant in the range supported by movrcc (19-bit signed imm) |
69 | 0 | case 'N': // Same as 'K' but zext (required for SIMode) |
70 | 0 | case 'O': // The constant 4096 |
71 | 0 | return true; |
72 | | |
73 | 38 | case 'f': |
74 | 40 | case 'e': |
75 | 40 | info.setAllowsRegister(); |
76 | 40 | return true; |
77 | 40 | } |
78 | 0 | return false; |
79 | 40 | } |
80 | 91 | const char *getClobbers() const override { |
81 | | // FIXME: Implement! |
82 | 91 | return ""; |
83 | 91 | } |
84 | | |
85 | | // No Sparc V7 for now, the backend doesn't support it anyway. |
86 | | enum CPUKind { |
87 | | CK_GENERIC, |
88 | | CK_V8, |
89 | | CK_SUPERSPARC, |
90 | | CK_SPARCLITE, |
91 | | CK_F934, |
92 | | CK_HYPERSPARC, |
93 | | CK_SPARCLITE86X, |
94 | | CK_SPARCLET, |
95 | | CK_TSC701, |
96 | | CK_V9, |
97 | | CK_ULTRASPARC, |
98 | | CK_ULTRASPARC3, |
99 | | CK_NIAGARA, |
100 | | CK_NIAGARA2, |
101 | | CK_NIAGARA3, |
102 | | CK_NIAGARA4, |
103 | | CK_MYRIAD2100, |
104 | | CK_MYRIAD2150, |
105 | | CK_MYRIAD2155, |
106 | | CK_MYRIAD2450, |
107 | | CK_MYRIAD2455, |
108 | | CK_MYRIAD2x5x, |
109 | | CK_MYRIAD2080, |
110 | | CK_MYRIAD2085, |
111 | | CK_MYRIAD2480, |
112 | | CK_MYRIAD2485, |
113 | | CK_MYRIAD2x8x, |
114 | | CK_LEON2, |
115 | | CK_LEON2_AT697E, |
116 | | CK_LEON2_AT697F, |
117 | | CK_LEON3, |
118 | | CK_LEON3_UT699, |
119 | | CK_LEON3_GR712RC, |
120 | | CK_LEON4, |
121 | | CK_LEON4_GR740 |
122 | | } CPU = CK_GENERIC; |
123 | | |
124 | | enum CPUGeneration { |
125 | | CG_V8, |
126 | | CG_V9, |
127 | | }; |
128 | | |
129 | | CPUGeneration getCPUGeneration(CPUKind Kind) const; |
130 | | |
131 | | CPUKind getCPUKind(StringRef Name) const; |
132 | | |
133 | 0 | bool isValidCPUName(StringRef Name) const override { |
134 | 0 | return getCPUKind(Name) != CK_GENERIC; |
135 | 0 | } |
136 | | |
137 | | void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; |
138 | | |
139 | 28 | bool setCPU(const std::string &Name) override { |
140 | 28 | CPU = getCPUKind(Name); |
141 | 28 | return CPU != CK_GENERIC; |
142 | 28 | } |
143 | | }; |
144 | | |
145 | | // SPARC v8 is the 32-bit mode selected by Triple::sparc. |
146 | | class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo { |
147 | | public: |
148 | | SparcV8TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
149 | 51 | : SparcTargetInfo(Triple, Opts) { |
150 | 51 | resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64"); |
151 | | // NetBSD / OpenBSD use long (same as llvm default); everyone else uses int. |
152 | 51 | switch (getTriple().getOS()) { |
153 | 49 | default: |
154 | 49 | SizeType = UnsignedInt; |
155 | 49 | IntPtrType = SignedInt; |
156 | 49 | PtrDiffType = SignedInt; |
157 | 49 | break; |
158 | 2 | case llvm::Triple::NetBSD: |
159 | 2 | case llvm::Triple::OpenBSD: |
160 | 2 | SizeType = UnsignedLong; |
161 | 2 | IntPtrType = SignedLong; |
162 | 2 | PtrDiffType = SignedLong; |
163 | 2 | break; |
164 | 51 | } |
165 | | // Up to 32 bits (V8) or 64 bits (V9) are lock-free atomic, but we're |
166 | | // willing to do atomic ops on up to 64 bits. |
167 | 51 | MaxAtomicPromoteWidth = 64; |
168 | 51 | if (getCPUGeneration(CPU) == CG_V9) |
169 | 0 | MaxAtomicInlineWidth = 64; |
170 | 51 | else |
171 | | // FIXME: This isn't correct for plain V8 which lacks CAS, |
172 | | // only for LEON 3+ and Myriad. |
173 | 51 | MaxAtomicInlineWidth = 32; |
174 | 51 | } clang::targets::SparcV8TargetInfo::SparcV8TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 149 | 25 | : SparcTargetInfo(Triple, Opts) { | 150 | 25 | resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64"); | 151 | | // NetBSD / OpenBSD use long (same as llvm default); everyone else uses int. | 152 | 25 | switch (getTriple().getOS()) { | 153 | 25 | default: | 154 | 25 | SizeType = UnsignedInt; | 155 | 25 | IntPtrType = SignedInt; | 156 | 25 | PtrDiffType = SignedInt; | 157 | 25 | break; | 158 | 0 | case llvm::Triple::NetBSD: | 159 | 0 | case llvm::Triple::OpenBSD: | 160 | 0 | SizeType = UnsignedLong; | 161 | 0 | IntPtrType = SignedLong; | 162 | 0 | PtrDiffType = SignedLong; | 163 | 0 | break; | 164 | 25 | } | 165 | | // Up to 32 bits (V8) or 64 bits (V9) are lock-free atomic, but we're | 166 | | // willing to do atomic ops on up to 64 bits. | 167 | 25 | MaxAtomicPromoteWidth = 64; | 168 | 25 | if (getCPUGeneration(CPU) == CG_V9) | 169 | 0 | MaxAtomicInlineWidth = 64; | 170 | 25 | else | 171 | | // FIXME: This isn't correct for plain V8 which lacks CAS, | 172 | | // only for LEON 3+ and Myriad. | 173 | 25 | MaxAtomicInlineWidth = 32; | 174 | 25 | } |
clang::targets::SparcV8TargetInfo::SparcV8TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 149 | 26 | : SparcTargetInfo(Triple, Opts) { | 150 | 26 | resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64"); | 151 | | // NetBSD / OpenBSD use long (same as llvm default); everyone else uses int. | 152 | 26 | switch (getTriple().getOS()) { | 153 | 24 | default: | 154 | 24 | SizeType = UnsignedInt; | 155 | 24 | IntPtrType = SignedInt; | 156 | 24 | PtrDiffType = SignedInt; | 157 | 24 | break; | 158 | 2 | case llvm::Triple::NetBSD: | 159 | 2 | case llvm::Triple::OpenBSD: | 160 | 2 | SizeType = UnsignedLong; | 161 | 2 | IntPtrType = SignedLong; | 162 | 2 | PtrDiffType = SignedLong; | 163 | 2 | break; | 164 | 26 | } | 165 | | // Up to 32 bits (V8) or 64 bits (V9) are lock-free atomic, but we're | 166 | | // willing to do atomic ops on up to 64 bits. | 167 | 26 | MaxAtomicPromoteWidth = 64; | 168 | 26 | if (getCPUGeneration(CPU) == CG_V9) | 169 | 0 | MaxAtomicInlineWidth = 64; | 170 | 26 | else | 171 | | // FIXME: This isn't correct for plain V8 which lacks CAS, | 172 | | // only for LEON 3+ and Myriad. | 173 | 26 | MaxAtomicInlineWidth = 32; | 174 | 26 | } |
|
175 | | |
176 | | void getTargetDefines(const LangOptions &Opts, |
177 | | MacroBuilder &Builder) const override; |
178 | | |
179 | 10 | bool hasBitIntType() const override { return true; } |
180 | | }; |
181 | | |
182 | | // SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel. |
183 | | class LLVM_LIBRARY_VISIBILITY SparcV8elTargetInfo : public SparcV8TargetInfo { |
184 | | public: |
185 | | SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
186 | 16 | : SparcV8TargetInfo(Triple, Opts) { |
187 | 16 | resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64"); |
188 | 16 | } clang::targets::SparcV8elTargetInfo::SparcV8elTargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 186 | 15 | : SparcV8TargetInfo(Triple, Opts) { | 187 | 15 | resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64"); | 188 | 15 | } |
clang::targets::SparcV8elTargetInfo::SparcV8elTargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 186 | 1 | : SparcV8TargetInfo(Triple, Opts) { | 187 | 1 | resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64"); | 188 | 1 | } |
|
189 | | }; |
190 | | |
191 | | // SPARC v9 is the 64-bit mode selected by Triple::sparcv9. |
192 | | class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo : public SparcTargetInfo { |
193 | | public: |
194 | | SparcV9TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) |
195 | 37 | : SparcTargetInfo(Triple, Opts) { |
196 | | // FIXME: Support Sparc quad-precision long double? |
197 | 37 | resetDataLayout("E-m:e-i64:64-n32:64-S128"); |
198 | | // This is an LP64 platform. |
199 | 37 | LongWidth = LongAlign = PointerWidth = PointerAlign = 64; |
200 | | |
201 | | // OpenBSD uses long long for int64_t and intmax_t. |
202 | 37 | if (getTriple().isOSOpenBSD()) |
203 | 11 | IntMaxType = SignedLongLong; |
204 | 26 | else |
205 | 26 | IntMaxType = SignedLong; |
206 | 37 | Int64Type = IntMaxType; |
207 | | |
208 | | // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit |
209 | | // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned. |
210 | 37 | LongDoubleWidth = 128; |
211 | 37 | LongDoubleAlign = 128; |
212 | 37 | SuitableAlign = 128; |
213 | 37 | LongDoubleFormat = &llvm::APFloat::IEEEquad(); |
214 | 37 | MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; |
215 | 37 | } clang::targets::SparcV9TargetInfo::SparcV9TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 195 | 9 | : SparcTargetInfo(Triple, Opts) { | 196 | | // FIXME: Support Sparc quad-precision long double? | 197 | 9 | resetDataLayout("E-m:e-i64:64-n32:64-S128"); | 198 | | // This is an LP64 platform. | 199 | 9 | LongWidth = LongAlign = PointerWidth = PointerAlign = 64; | 200 | | | 201 | | // OpenBSD uses long long for int64_t and intmax_t. | 202 | 9 | if (getTriple().isOSOpenBSD()) | 203 | 0 | IntMaxType = SignedLongLong; | 204 | 9 | else | 205 | 9 | IntMaxType = SignedLong; | 206 | 9 | Int64Type = IntMaxType; | 207 | | | 208 | | // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit | 209 | | // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned. | 210 | 9 | LongDoubleWidth = 128; | 211 | 9 | LongDoubleAlign = 128; | 212 | 9 | SuitableAlign = 128; | 213 | 9 | LongDoubleFormat = &llvm::APFloat::IEEEquad(); | 214 | 9 | MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; | 215 | 9 | } |
clang::targets::SparcV9TargetInfo::SparcV9TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 195 | 28 | : SparcTargetInfo(Triple, Opts) { | 196 | | // FIXME: Support Sparc quad-precision long double? | 197 | 28 | resetDataLayout("E-m:e-i64:64-n32:64-S128"); | 198 | | // This is an LP64 platform. | 199 | 28 | LongWidth = LongAlign = PointerWidth = PointerAlign = 64; | 200 | | | 201 | | // OpenBSD uses long long for int64_t and intmax_t. | 202 | 28 | if (getTriple().isOSOpenBSD()) | 203 | 11 | IntMaxType = SignedLongLong; | 204 | 17 | else | 205 | 17 | IntMaxType = SignedLong; | 206 | 28 | Int64Type = IntMaxType; | 207 | | | 208 | | // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit | 209 | | // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned. | 210 | 28 | LongDoubleWidth = 128; | 211 | 28 | LongDoubleAlign = 128; | 212 | 28 | SuitableAlign = 128; | 213 | 28 | LongDoubleFormat = &llvm::APFloat::IEEEquad(); | 214 | 28 | MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; | 215 | 28 | } |
|
216 | | |
217 | | void getTargetDefines(const LangOptions &Opts, |
218 | | MacroBuilder &Builder) const override; |
219 | | |
220 | 0 | bool isValidCPUName(StringRef Name) const override { |
221 | 0 | return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9; |
222 | 0 | } |
223 | | |
224 | | void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; |
225 | | |
226 | 9 | bool setCPU(const std::string &Name) override { |
227 | 9 | if (!SparcTargetInfo::setCPU(Name)) |
228 | 1 | return false; |
229 | 8 | return getCPUGeneration(CPU) == CG_V9; |
230 | 9 | } |
231 | | |
232 | 10 | bool hasBitIntType() const override { return true; } |
233 | | }; |
234 | | } // namespace targets |
235 | | } // namespace clang |
236 | | #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H |