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