Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.h
35266 views
1
//===--- Sparc.h - declare sparc target feature support ---------*- C++ -*-===//
2
//
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
6
//
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/Support/Compiler.h"
18
#include "llvm/TargetParser/Triple.h"
19
namespace clang {
20
namespace targets {
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[];
25
bool SoftFloat;
26
27
public:
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
42
if (llvm::is_contained(Features, "+soft-float"))
43
SoftFloat = true;
44
return true;
45
}
46
void getTargetDefines(const LangOptions &Opts,
47
MacroBuilder &Builder) const override;
48
49
bool hasFeature(StringRef Feature) const override;
50
51
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
52
// FIXME: Implement!
53
return std::nullopt;
54
}
55
BuiltinVaListKind getBuiltinVaListKind() const override {
56
return TargetInfo::VoidPtrBuiltinVaList;
57
}
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 {
62
// FIXME: Implement!
63
switch (*Name) {
64
case 'I': // Signed 13-bit constant
65
case 'J': // Zero
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
71
return true;
72
73
case 'f':
74
case 'e':
75
info.setAllowsRegister();
76
return true;
77
}
78
return false;
79
}
80
std::string_view getClobbers() const override {
81
// FIXME: Implement!
82
return "";
83
}
84
85
// No Sparc V7 for now, the backend doesn't support it anyway.
86
enum CPUKind {
87
CK_GENERIC,
88
CK_V8,
89
CK_SUPERSPARC,
90
CK_SPARCLITE,
91
CK_F934,
92
CK_HYPERSPARC,
93
CK_SPARCLITE86X,
94
CK_SPARCLET,
95
CK_TSC701,
96
CK_V9,
97
CK_ULTRASPARC,
98
CK_ULTRASPARC3,
99
CK_NIAGARA,
100
CK_NIAGARA2,
101
CK_NIAGARA3,
102
CK_NIAGARA4,
103
CK_MYRIAD2100,
104
CK_MYRIAD2150,
105
CK_MYRIAD2155,
106
CK_MYRIAD2450,
107
CK_MYRIAD2455,
108
CK_MYRIAD2x5x,
109
CK_MYRIAD2080,
110
CK_MYRIAD2085,
111
CK_MYRIAD2480,
112
CK_MYRIAD2485,
113
CK_MYRIAD2x8x,
114
CK_LEON2,
115
CK_LEON2_AT697E,
116
CK_LEON2_AT697F,
117
CK_LEON3,
118
CK_LEON3_UT699,
119
CK_LEON3_GR712RC,
120
CK_LEON4,
121
CK_LEON4_GR740
122
} CPU = CK_GENERIC;
123
124
enum CPUGeneration {
125
CG_V8,
126
CG_V9,
127
};
128
129
CPUGeneration getCPUGeneration(CPUKind Kind) const;
130
131
CPUKind getCPUKind(StringRef Name) const;
132
133
bool isValidCPUName(StringRef Name) const override {
134
return getCPUKind(Name) != CK_GENERIC;
135
}
136
137
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
138
139
bool setCPU(const std::string &Name) override {
140
CPU = getCPUKind(Name);
141
return CPU != CK_GENERIC;
142
}
143
144
std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
145
return std::make_pair(32, 32);
146
}
147
};
148
149
// SPARC v8 is the 32-bit mode selected by Triple::sparc.
150
class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo {
151
public:
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 (V8) or 64 bits (V9) are lock-free atomic, but we're
170
// willing to do atomic ops on up to 64 bits.
171
MaxAtomicPromoteWidth = 64;
172
if (getCPUGeneration(CPU) == CG_V9)
173
MaxAtomicInlineWidth = 64;
174
else
175
// FIXME: This isn't correct for plain V8 which lacks CAS,
176
// only for LEON 3+ and Myriad.
177
MaxAtomicInlineWidth = 32;
178
}
179
180
void getTargetDefines(const LangOptions &Opts,
181
MacroBuilder &Builder) const override;
182
183
bool hasBitIntType() const override { return true; }
184
};
185
186
// SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
187
class LLVM_LIBRARY_VISIBILITY SparcV8elTargetInfo : public SparcV8TargetInfo {
188
public:
189
SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
190
: SparcV8TargetInfo(Triple, Opts) {
191
resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");
192
}
193
};
194
195
// SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
196
class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo : public SparcTargetInfo {
197
public:
198
SparcV9TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
199
: SparcTargetInfo(Triple, Opts) {
200
// FIXME: Support Sparc quad-precision long double?
201
resetDataLayout("E-m:e-i64:64-n32:64-S128");
202
// This is an LP64 platform.
203
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
204
205
// OpenBSD uses long long for int64_t and intmax_t.
206
if (getTriple().isOSOpenBSD())
207
IntMaxType = SignedLongLong;
208
else
209
IntMaxType = SignedLong;
210
Int64Type = IntMaxType;
211
212
// The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
213
// aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.
214
LongDoubleWidth = 128;
215
LongDoubleAlign = 128;
216
SuitableAlign = 128;
217
LongDoubleFormat = &llvm::APFloat::IEEEquad();
218
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
219
}
220
221
void getTargetDefines(const LangOptions &Opts,
222
MacroBuilder &Builder) const override;
223
224
bool isValidCPUName(StringRef Name) const override {
225
return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9;
226
}
227
228
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
229
230
bool setCPU(const std::string &Name) override {
231
if (!SparcTargetInfo::setCPU(Name))
232
return false;
233
return getCPUGeneration(CPU) == CG_V9;
234
}
235
236
bool hasBitIntType() const override { return true; }
237
};
238
} // namespace targets
239
} // namespace clang
240
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H
241
242