blob: d24cf15d7cd6535b9300e6c7345255be9850bc7d [file] [log] [blame]
Erik Pilkington7adcf292018-07-24 00:07:49 +00001//===--- Sparc.h - declare sparc target feature support ---------*- C++ -*-===//
Erich Keaneebba5922017-07-21 22:37:03 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Erich Keaneebba5922017-07-21 22:37:03 +00006//
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"
19namespace clang {
20namespace targets {
21// Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit).
22class LLVM_LIBRARY_VISIBILITY SparcTargetInfo : public TargetInfo {
23 static const TargetInfo::GCCRegAlias GCCRegAliases[];
24 static const char *const GCCRegNames[];
25 bool SoftFloat;
26
27public:
28 SparcTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
29 : TargetInfo(Triple), SoftFloat(false) {}
30
31 int getEHDataRegisterNumber(unsigned RegNo) const override {
32 if (RegNo == 0)
33 return 24;
34 if (RegNo == 1)
35 return 25;
36 return -1;
37 }
38
39 bool handleTargetFeatures(std::vector<std::string> &Features,
40 DiagnosticsEngine &Diags) override {
41 // Check if software floating point is enabled
Fangrui Song75e74e02019-03-31 08:48:19 +000042 auto Feature = llvm::find(Features, "+soft-float");
Erich Keaneebba5922017-07-21 22:37:03 +000043 if (Feature != Features.end()) {
44 SoftFloat = true;
45 }
46 return true;
47 }
48 void getTargetDefines(const LangOptions &Opts,
49 MacroBuilder &Builder) const override;
50
51 bool hasFeature(StringRef Feature) const override;
52
53 bool hasSjLjLowering() const override { return true; }
54
55 ArrayRef<Builtin::Info> getTargetBuiltins() const override {
56 // FIXME: Implement!
57 return None;
58 }
59 BuiltinVaListKind getBuiltinVaListKind() const override {
60 return TargetInfo::VoidPtrBuiltinVaList;
61 }
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 {
66 // FIXME: Implement!
67 switch (*Name) {
68 case 'I': // Signed 13-bit constant
69 case 'J': // Zero
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
75 return true;
76
77 case 'f':
78 case 'e':
79 info.setAllowsRegister();
80 return true;
81 }
82 return false;
83 }
84 const char *getClobbers() const override {
85 // FIXME: Implement!
86 return "";
87 }
88
89 // No Sparc V7 for now, the backend doesn't support it anyway.
90 enum CPUKind {
91 CK_GENERIC,
92 CK_V8,
93 CK_SUPERSPARC,
94 CK_SPARCLITE,
95 CK_F934,
96 CK_HYPERSPARC,
97 CK_SPARCLITE86X,
98 CK_SPARCLET,
99 CK_TSC701,
100 CK_V9,
101 CK_ULTRASPARC,
102 CK_ULTRASPARC3,
103 CK_NIAGARA,
104 CK_NIAGARA2,
105 CK_NIAGARA3,
106 CK_NIAGARA4,
107 CK_MYRIAD2100,
108 CK_MYRIAD2150,
Walter Leefc7f8f22017-10-02 18:50:57 +0000109 CK_MYRIAD2155,
Erich Keaneebba5922017-07-21 22:37:03 +0000110 CK_MYRIAD2450,
Walter Leefc7f8f22017-10-02 18:50:57 +0000111 CK_MYRIAD2455,
112 CK_MYRIAD2x5x,
113 CK_MYRIAD2080,
114 CK_MYRIAD2085,
115 CK_MYRIAD2480,
116 CK_MYRIAD2485,
117 CK_MYRIAD2x8x,
Erich Keaneebba5922017-07-21 22:37:03 +0000118 CK_LEON2,
119 CK_LEON2_AT697E,
120 CK_LEON2_AT697F,
121 CK_LEON3,
122 CK_LEON3_UT699,
123 CK_LEON3_GR712RC,
124 CK_LEON4,
125 CK_LEON4_GR740
126 } CPU = CK_GENERIC;
127
128 enum CPUGeneration {
129 CG_V8,
130 CG_V9,
131 };
132
Erich Keanee44bdb32018-02-08 23:16:55 +0000133 CPUGeneration getCPUGeneration(CPUKind Kind) const;
Erich Keaneebba5922017-07-21 22:37:03 +0000134
135 CPUKind getCPUKind(StringRef Name) const;
136
137 bool isValidCPUName(StringRef Name) const override {
138 return getCPUKind(Name) != CK_GENERIC;
139 }
140
Erich Keanee44bdb32018-02-08 23:16:55 +0000141 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
142
Erich Keaneebba5922017-07-21 22:37:03 +0000143 bool setCPU(const std::string &Name) override {
144 CPU = getCPUKind(Name);
145 return CPU != CK_GENERIC;
146 }
147};
148
149// SPARC v8 is the 32-bit mode selected by Triple::sparc.
150class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo {
151public:
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()) {
157 default:
158 SizeType = UnsignedInt;
159 IntPtrType = SignedInt;
160 PtrDiffType = SignedInt;
161 break;
162 case llvm::Triple::NetBSD:
163 case llvm::Triple::OpenBSD:
164 SizeType = UnsignedLong;
165 IntPtrType = SignedLong;
166 PtrDiffType = SignedLong;
167 break;
168 }
169 // Up to 32 bits are lock-free atomic, but we're willing to do atomic ops
170 // on up to 64 bits.
171 MaxAtomicPromoteWidth = 64;
172 MaxAtomicInlineWidth = 32;
173 }
174
175 void getTargetDefines(const LangOptions &Opts,
176 MacroBuilder &Builder) const override;
177
178 bool hasSjLjLowering() const override { return true; }
Erich Keane8a1c9992020-04-29 12:48:07 -0700179 bool hasExtIntType() const override { return true; }
Erich Keaneebba5922017-07-21 22:37:03 +0000180};
181
182// SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
183class LLVM_LIBRARY_VISIBILITY SparcV8elTargetInfo : public SparcV8TargetInfo {
184public:
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");
188 }
189};
190
191// SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
192class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo : public SparcTargetInfo {
193public:
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;
200
201 // OpenBSD uses long long for int64_t and intmax_t.
Michal Gorny5a409d02018-12-20 13:09:30 +0000202 if (getTriple().isOSOpenBSD())
Erich Keaneebba5922017-07-21 22:37:03 +0000203 IntMaxType = SignedLongLong;
204 else
205 IntMaxType = SignedLong;
206 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 LongDoubleWidth = 128;
211 LongDoubleAlign = 128;
Rainer Orth2da6eea2019-07-23 16:24:00 +0000212 SuitableAlign = 128;
Erich Keaneebba5922017-07-21 22:37:03 +0000213 LongDoubleFormat = &llvm::APFloat::IEEEquad();
214 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
215 }
216
217 void getTargetDefines(const LangOptions &Opts,
218 MacroBuilder &Builder) const override;
219
220 bool isValidCPUName(StringRef Name) const override {
221 return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9;
222 }
223
Erich Keanee44bdb32018-02-08 23:16:55 +0000224 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
225
Erich Keaneebba5922017-07-21 22:37:03 +0000226 bool setCPU(const std::string &Name) override {
227 if (!SparcTargetInfo::setCPU(Name))
228 return false;
229 return getCPUGeneration(CPU) == CG_V9;
230 }
Erich Keane8a1c9992020-04-29 12:48:07 -0700231
232 bool hasExtIntType() const override { return true; }
Erich Keaneebba5922017-07-21 22:37:03 +0000233};
234} // namespace targets
235} // namespace clang
236#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H