1 //===--- Sparc.h - declare sparc target feature support ---------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file declares Sparc TargetInfo objects.
11 //===----------------------------------------------------------------------===//
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"
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[];
28 SparcTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
29 : TargetInfo(Triple), SoftFloat(false) {}
31 int getEHDataRegisterNumber(unsigned RegNo) const override {
39 bool handleTargetFeatures(std::vector<std::string> &Features,
40 DiagnosticsEngine &Diags) override {
41 // Check if software floating point is enabled
42 auto Feature = llvm::find(Features, "+soft-float");
43 if (Feature != Features.end()) {
48 void getTargetDefines(const LangOptions &Opts,
49 MacroBuilder &Builder) const override;
51 bool hasFeature(StringRef Feature) const override;
53 bool hasSjLjLowering() const override { return true; }
55 ArrayRef<Builtin::Info> getTargetBuiltins() const override {
59 BuiltinVaListKind getBuiltinVaListKind() const override {
60 return TargetInfo::VoidPtrBuiltinVaList;
62 ArrayRef<const char *> getGCCRegNames() const override;
63 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
64 bool validateAsmConstraint(const char *&Name,
65 TargetInfo::ConstraintInfo &info) const override {
68 case 'I': // Signed 13-bit constant
70 case 'K': // 32-bit constant with the low 12 bits clear
71 case 'L': // A constant in the range supported by movcc (11-bit signed imm)
72 case 'M': // A constant in the range supported by movrcc (19-bit signed imm)
73 case 'N': // Same as 'K' but zext (required for SIMode)
74 case 'O': // The constant 4096
79 info.setAllowsRegister();
84 const char *getClobbers() const override {
89 // No Sparc V7 for now, the backend doesn't support it anyway.
133 CPUGeneration getCPUGeneration(CPUKind Kind) const;
135 CPUKind getCPUKind(StringRef Name) const;
137 bool isValidCPUName(StringRef Name) const override {
138 return getCPUKind(Name) != CK_GENERIC;
141 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
143 bool setCPU(const std::string &Name) override {
144 CPU = getCPUKind(Name);
145 return CPU != CK_GENERIC;
149 // SPARC v8 is the 32-bit mode selected by Triple::sparc.
150 class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo {
152 SparcV8TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
153 : SparcTargetInfo(Triple, Opts) {
154 resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64");
155 // NetBSD / OpenBSD use long (same as llvm default); everyone else uses int.
156 switch (getTriple().getOS()) {
158 SizeType = UnsignedInt;
159 IntPtrType = SignedInt;
160 PtrDiffType = SignedInt;
162 case llvm::Triple::NetBSD:
163 case llvm::Triple::OpenBSD:
164 SizeType = UnsignedLong;
165 IntPtrType = SignedLong;
166 PtrDiffType = SignedLong;
169 // Up to 32 bits are lock-free atomic, but we're willing to do atomic ops
171 MaxAtomicPromoteWidth = 64;
172 MaxAtomicInlineWidth = 32;
175 void getTargetDefines(const LangOptions &Opts,
176 MacroBuilder &Builder) const override;
178 bool hasSjLjLowering() const override { return true; }
181 // SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
182 class LLVM_LIBRARY_VISIBILITY SparcV8elTargetInfo : public SparcV8TargetInfo {
184 SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
185 : SparcV8TargetInfo(Triple, Opts) {
186 resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");
190 // SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
191 class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo : public SparcTargetInfo {
193 SparcV9TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
194 : SparcTargetInfo(Triple, Opts) {
195 // FIXME: Support Sparc quad-precision long double?
196 resetDataLayout("E-m:e-i64:64-n32:64-S128");
197 // This is an LP64 platform.
198 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
200 // OpenBSD uses long long for int64_t and intmax_t.
201 if (getTriple().isOSOpenBSD())
202 IntMaxType = SignedLongLong;
204 IntMaxType = SignedLong;
205 Int64Type = IntMaxType;
207 // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
208 // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.
209 LongDoubleWidth = 128;
210 LongDoubleAlign = 128;
211 LongDoubleFormat = &llvm::APFloat::IEEEquad();
212 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
215 void getTargetDefines(const LangOptions &Opts,
216 MacroBuilder &Builder) const override;
218 bool isValidCPUName(StringRef Name) const override {
219 return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9;
222 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
224 bool setCPU(const std::string &Name) override {
225 if (!SparcTargetInfo::setCPU(Name))
227 return getCPUGeneration(CPU) == CG_V9;
230 } // namespace targets
232 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H