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 if (llvm::is_contained(Features
, "+soft-float"))
46 void getTargetDefines(const LangOptions
&Opts
,
47 MacroBuilder
&Builder
) const override
;
49 bool hasFeature(StringRef Feature
) const override
;
51 ArrayRef
<Builtin::Info
> getTargetBuiltins() const override
{
55 BuiltinVaListKind
getBuiltinVaListKind() const override
{
56 return TargetInfo::VoidPtrBuiltinVaList
;
58 ArrayRef
<const char *> getGCCRegNames() const override
;
59 ArrayRef
<TargetInfo::GCCRegAlias
> getGCCRegAliases() const override
;
60 bool validateAsmConstraint(const char *&Name
,
61 TargetInfo::ConstraintInfo
&info
) const override
{
64 case 'I': // Signed 13-bit constant
66 case 'K': // 32-bit constant with the low 12 bits clear
67 case 'L': // A constant in the range supported by movcc (11-bit signed imm)
68 case 'M': // A constant in the range supported by movrcc (19-bit signed imm)
69 case 'N': // Same as 'K' but zext (required for SIMode)
70 case 'O': // The constant 4096
75 info
.setAllowsRegister();
80 const char *getClobbers() const override
{
85 // No Sparc V7 for now, the backend doesn't support it anyway.
129 CPUGeneration
getCPUGeneration(CPUKind Kind
) const;
131 CPUKind
getCPUKind(StringRef Name
) const;
133 bool isValidCPUName(StringRef Name
) const override
{
134 return getCPUKind(Name
) != CK_GENERIC
;
137 void fillValidCPUList(SmallVectorImpl
<StringRef
> &Values
) const override
;
139 bool setCPU(const std::string
&Name
) override
{
140 CPU
= getCPUKind(Name
);
141 return CPU
!= CK_GENERIC
;
145 // SPARC v8 is the 32-bit mode selected by Triple::sparc.
146 class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo
: public SparcTargetInfo
{
148 SparcV8TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
149 : SparcTargetInfo(Triple
, Opts
) {
150 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 switch (getTriple().getOS()) {
154 SizeType
= UnsignedInt
;
155 IntPtrType
= SignedInt
;
156 PtrDiffType
= SignedInt
;
158 case llvm::Triple::NetBSD
:
159 case llvm::Triple::OpenBSD
:
160 SizeType
= UnsignedLong
;
161 IntPtrType
= SignedLong
;
162 PtrDiffType
= SignedLong
;
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 MaxAtomicPromoteWidth
= 64;
168 if (getCPUGeneration(CPU
) == CG_V9
)
169 MaxAtomicInlineWidth
= 64;
171 // FIXME: This isn't correct for plain V8 which lacks CAS,
172 // only for LEON 3+ and Myriad.
173 MaxAtomicInlineWidth
= 32;
176 void getTargetDefines(const LangOptions
&Opts
,
177 MacroBuilder
&Builder
) const override
;
179 bool hasBitIntType() const override
{ return true; }
182 // SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
183 class LLVM_LIBRARY_VISIBILITY SparcV8elTargetInfo
: public SparcV8TargetInfo
{
185 SparcV8elTargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
186 : SparcV8TargetInfo(Triple
, Opts
) {
187 resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");
191 // SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
192 class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo
: public SparcTargetInfo
{
194 SparcV9TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
195 : SparcTargetInfo(Triple
, Opts
) {
196 // FIXME: Support Sparc quad-precision long double?
197 resetDataLayout("E-m:e-i64:64-n32:64-S128");
198 // This is an LP64 platform.
199 LongWidth
= LongAlign
= PointerWidth
= PointerAlign
= 64;
201 // OpenBSD uses long long for int64_t and intmax_t.
202 if (getTriple().isOSOpenBSD())
203 IntMaxType
= SignedLongLong
;
205 IntMaxType
= SignedLong
;
206 Int64Type
= IntMaxType
;
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 LongDoubleWidth
= 128;
211 LongDoubleAlign
= 128;
213 LongDoubleFormat
= &llvm::APFloat::IEEEquad();
214 MaxAtomicPromoteWidth
= MaxAtomicInlineWidth
= 64;
217 void getTargetDefines(const LangOptions
&Opts
,
218 MacroBuilder
&Builder
) const override
;
220 bool isValidCPUName(StringRef Name
) const override
{
221 return getCPUGeneration(SparcTargetInfo::getCPUKind(Name
)) == CG_V9
;
224 void fillValidCPUList(SmallVectorImpl
<StringRef
> &Values
) const override
;
226 bool setCPU(const std::string
&Name
) override
{
227 if (!SparcTargetInfo::setCPU(Name
))
229 return getCPUGeneration(CPU
) == CG_V9
;
232 bool hasBitIntType() const override
{ return true; }
234 } // namespace targets
236 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H