1 //===--- Sparc.h - Declare Sparc target feature support -------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares Sparc TargetInfo objects.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H
15 #define LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H
16 #include "clang/Basic/TargetInfo.h"
17 #include "clang/Basic/TargetOptions.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/Compiler.h"
22 // Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit).
23 class LLVM_LIBRARY_VISIBILITY SparcTargetInfo : public TargetInfo {
24 static const TargetInfo::GCCRegAlias GCCRegAliases[];
25 static const char *const GCCRegNames[];
29 SparcTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
30 : TargetInfo(Triple), SoftFloat(false) {}
32 int getEHDataRegisterNumber(unsigned RegNo) const override {
40 bool handleTargetFeatures(std::vector<std::string> &Features,
41 DiagnosticsEngine &Diags) override {
42 // Check if software floating point is enabled
43 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float");
44 if (Feature != Features.end()) {
49 void getTargetDefines(const LangOptions &Opts,
50 MacroBuilder &Builder) const override;
52 bool hasFeature(StringRef Feature) const override;
54 bool hasSjLjLowering() const override { return true; }
56 ArrayRef<Builtin::Info> getTargetBuiltins() const override {
60 BuiltinVaListKind getBuiltinVaListKind() const override {
61 return TargetInfo::VoidPtrBuiltinVaList;
63 ArrayRef<const char *> getGCCRegNames() const override;
64 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
65 bool validateAsmConstraint(const char *&Name,
66 TargetInfo::ConstraintInfo &info) const override {
69 case 'I': // Signed 13-bit constant
71 case 'K': // 32-bit constant with the low 12 bits clear
72 case 'L': // A constant in the range supported by movcc (11-bit signed imm)
73 case 'M': // A constant in the range supported by movrcc (19-bit signed imm)
74 case 'N': // Same as 'K' but zext (required for SIMode)
75 case 'O': // The constant 4096
80 info.setAllowsRegister();
85 const char *getClobbers() const override {
90 // No Sparc V7 for now, the backend doesn't support it anyway.
134 CPUGeneration getCPUGeneration(CPUKind Kind) const {
142 case CK_SPARCLITE86X:
157 case CK_LEON2_AT697E:
158 case CK_LEON2_AT697F:
161 case CK_LEON3_GR712RC:
174 llvm_unreachable("Unexpected CPU kind");
177 CPUKind getCPUKind(StringRef Name) const;
179 bool isValidCPUName(StringRef Name) const override {
180 return getCPUKind(Name) != CK_GENERIC;
183 bool setCPU(const std::string &Name) override {
184 CPU = getCPUKind(Name);
185 return CPU != CK_GENERIC;
189 // SPARC v8 is the 32-bit mode selected by Triple::sparc.
190 class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo {
192 SparcV8TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
193 : SparcTargetInfo(Triple, Opts) {
194 resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64");
195 // NetBSD / OpenBSD use long (same as llvm default); everyone else uses int.
196 switch (getTriple().getOS()) {
198 SizeType = UnsignedInt;
199 IntPtrType = SignedInt;
200 PtrDiffType = SignedInt;
202 case llvm::Triple::NetBSD:
203 case llvm::Triple::OpenBSD:
204 SizeType = UnsignedLong;
205 IntPtrType = SignedLong;
206 PtrDiffType = SignedLong;
209 // Up to 32 bits are lock-free atomic, but we're willing to do atomic ops
211 MaxAtomicPromoteWidth = 64;
212 MaxAtomicInlineWidth = 32;
215 void getTargetDefines(const LangOptions &Opts,
216 MacroBuilder &Builder) const override;
218 bool hasSjLjLowering() const override { return true; }
221 // SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
222 class LLVM_LIBRARY_VISIBILITY SparcV8elTargetInfo : public SparcV8TargetInfo {
224 SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
225 : SparcV8TargetInfo(Triple, Opts) {
226 resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");
230 // SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
231 class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo : public SparcTargetInfo {
233 SparcV9TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
234 : SparcTargetInfo(Triple, Opts) {
235 // FIXME: Support Sparc quad-precision long double?
236 resetDataLayout("E-m:e-i64:64-n32:64-S128");
237 // This is an LP64 platform.
238 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
240 // OpenBSD uses long long for int64_t and intmax_t.
241 if (getTriple().getOS() == llvm::Triple::OpenBSD)
242 IntMaxType = SignedLongLong;
244 IntMaxType = SignedLong;
245 Int64Type = IntMaxType;
247 // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
248 // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.
249 LongDoubleWidth = 128;
250 LongDoubleAlign = 128;
251 LongDoubleFormat = &llvm::APFloat::IEEEquad();
252 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
255 void getTargetDefines(const LangOptions &Opts,
256 MacroBuilder &Builder) const override;
258 bool isValidCPUName(StringRef Name) const override {
259 return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9;
262 bool setCPU(const std::string &Name) override {
263 if (!SparcTargetInfo::setCPU(Name))
265 return getCPUGeneration(CPU) == CG_V9;
268 } // namespace targets
270 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H