Coverage Report

Created: 2022-01-25 06:29

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/Sparc.h
Line
Count
Source (jump to first uncovered line)
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/ADT/Triple.h"
18
#include "llvm/Support/Compiler.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
68
      : TargetInfo(Triple), SoftFloat(false) {}
30
31
0
  int getEHDataRegisterNumber(unsigned RegNo) const override {
32
0
    if (RegNo == 0)
33
0
      return 24;
34
0
    if (RegNo == 1)
35
0
      return 25;
36
0
    return -1;
37
0
  }
38
39
  bool handleTargetFeatures(std::vector<std::string> &Features,
40
58
                            DiagnosticsEngine &Diags) override {
41
    // Check if software floating point is enabled
42
58
    if (llvm::is_contained(Features, "+soft-float"))
43
1
      SoftFloat = true;
44
58
    return true;
45
58
  }
46
  void getTargetDefines(const LangOptions &Opts,
47
                        MacroBuilder &Builder) const override;
48
49
  bool hasFeature(StringRef Feature) const override;
50
51
58
  ArrayRef<Builtin::Info> getTargetBuiltins() const override {
52
    // FIXME: Implement!
53
58
    return None;
54
58
  }
55
47
  BuiltinVaListKind getBuiltinVaListKind() const override {
56
47
    return TargetInfo::VoidPtrBuiltinVaList;
57
47
  }
58
  ArrayRef<const char *> getGCCRegNames() const override;
59
  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
60
  bool validateAsmConstraint(const char *&Name,
61
40
                             TargetInfo::ConstraintInfo &info) const override {
62
    // FIXME: Implement!
63
40
    switch (*Name) {
64
0
    case 'I': // Signed 13-bit constant
65
0
    case 'J': // Zero
66
0
    case 'K': // 32-bit constant with the low 12 bits clear
67
0
    case 'L': // A constant in the range supported by movcc (11-bit signed imm)
68
0
    case 'M': // A constant in the range supported by movrcc (19-bit signed imm)
69
0
    case 'N': // Same as 'K' but zext (required for SIMode)
70
0
    case 'O': // The constant 4096
71
0
      return true;
72
73
38
    case 'f':
74
40
    case 'e':
75
40
      info.setAllowsRegister();
76
40
      return true;
77
40
    }
78
0
    return false;
79
40
  }
80
91
  const char *getClobbers() const override {
81
    // FIXME: Implement!
82
91
    return "";
83
91
  }
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
0
  bool isValidCPUName(StringRef Name) const override {
134
0
    return getCPUKind(Name) != CK_GENERIC;
135
0
  }
136
137
  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
138
139
10
  bool setCPU(const std::string &Name) override {
140
10
    CPU = getCPUKind(Name);
141
10
    return CPU != CK_GENERIC;
142
10
  }
143
};
144
145
// SPARC v8 is the 32-bit mode selected by Triple::sparc.
146
class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo {
147
public:
148
  SparcV8TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
149
33
      : SparcTargetInfo(Triple, Opts) {
150
33
    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
33
    switch (getTriple().getOS()) {
153
29
    default:
154
29
      SizeType = UnsignedInt;
155
29
      IntPtrType = SignedInt;
156
29
      PtrDiffType = SignedInt;
157
29
      break;
158
2
    case llvm::Triple::NetBSD:
159
4
    case llvm::Triple::OpenBSD:
160
4
      SizeType = UnsignedLong;
161
4
      IntPtrType = SignedLong;
162
4
      PtrDiffType = SignedLong;
163
4
      break;
164
33
    }
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
33
    MaxAtomicPromoteWidth = 64;
168
33
    if (getCPUGeneration(CPU) == CG_V9)
169
0
      MaxAtomicInlineWidth = 64;
170
33
    else
171
      // FIXME: This isn't correct for plain V8 which lacks CAS,
172
      // only for LEON 3+ and Myriad.
173
33
      MaxAtomicInlineWidth = 32;
174
33
  }
clang::targets::SparcV8TargetInfo::SparcV8TargetInfo(llvm::Triple const&, clang::TargetOptions const&)
Line
Count
Source
149
27
      : SparcTargetInfo(Triple, Opts) {
150
27
    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
27
    switch (getTriple().getOS()) {
153
25
    default:
154
25
      SizeType = UnsignedInt;
155
25
      IntPtrType = SignedInt;
156
25
      PtrDiffType = SignedInt;
157
25
      break;
158
0
    case llvm::Triple::NetBSD:
159
2
    case llvm::Triple::OpenBSD:
160
2
      SizeType = UnsignedLong;
161
2
      IntPtrType = SignedLong;
162
2
      PtrDiffType = SignedLong;
163
2
      break;
164
27
    }
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
27
    MaxAtomicPromoteWidth = 64;
168
27
    if (getCPUGeneration(CPU) == CG_V9)
169
0
      MaxAtomicInlineWidth = 64;
170
27
    else
171
      // FIXME: This isn't correct for plain V8 which lacks CAS,
172
      // only for LEON 3+ and Myriad.
173
27
      MaxAtomicInlineWidth = 32;
174
27
  }
clang::targets::SparcV8TargetInfo::SparcV8TargetInfo(llvm::Triple const&, clang::TargetOptions const&)
Line
Count
Source
149
6
      : SparcTargetInfo(Triple, Opts) {
150
6
    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
6
    switch (getTriple().getOS()) {
153
4
    default:
154
4
      SizeType = UnsignedInt;
155
4
      IntPtrType = SignedInt;
156
4
      PtrDiffType = SignedInt;
157
4
      break;
158
2
    case llvm::Triple::NetBSD:
159
2
    case llvm::Triple::OpenBSD:
160
2
      SizeType = UnsignedLong;
161
2
      IntPtrType = SignedLong;
162
2
      PtrDiffType = SignedLong;
163
2
      break;
164
6
    }
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
6
    MaxAtomicPromoteWidth = 64;
168
6
    if (getCPUGeneration(CPU) == CG_V9)
169
0
      MaxAtomicInlineWidth = 64;
170
6
    else
171
      // FIXME: This isn't correct for plain V8 which lacks CAS,
172
      // only for LEON 3+ and Myriad.
173
6
      MaxAtomicInlineWidth = 32;
174
6
  }
175
176
  void getTargetDefines(const LangOptions &Opts,
177
                        MacroBuilder &Builder) const override;
178
179
15
  bool hasBitIntType() const override { return true; }
180
};
181
182
// SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
183
class LLVM_LIBRARY_VISIBILITY SparcV8elTargetInfo : public SparcV8TargetInfo {
184
public:
185
  SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
186
0
      : SparcV8TargetInfo(Triple, Opts) {
187
0
    resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");
188
0
  }
Unexecuted instantiation: clang::targets::SparcV8elTargetInfo::SparcV8elTargetInfo(llvm::Triple const&, clang::TargetOptions const&)
Unexecuted instantiation: clang::targets::SparcV8elTargetInfo::SparcV8elTargetInfo(llvm::Triple const&, clang::TargetOptions const&)
189
};
190
191
// SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
192
class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo : public SparcTargetInfo {
193
public:
194
  SparcV9TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
195
35
      : SparcTargetInfo(Triple, Opts) {
196
    // FIXME: Support Sparc quad-precision long double?
197
35
    resetDataLayout("E-m:e-i64:64-n32:64-S128");
198
    // This is an LP64 platform.
199
35
    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
200
201
    // OpenBSD uses long long for int64_t and intmax_t.
202
35
    if (getTriple().isOSOpenBSD())
203
11
      IntMaxType = SignedLongLong;
204
24
    else
205
24
      IntMaxType = SignedLong;
206
35
    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
35
    LongDoubleWidth = 128;
211
35
    LongDoubleAlign = 128;
212
35
    SuitableAlign = 128;
213
35
    LongDoubleFormat = &llvm::APFloat::IEEEquad();
214
35
    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
215
35
  }
clang::targets::SparcV9TargetInfo::SparcV9TargetInfo(llvm::Triple const&, clang::TargetOptions const&)
Line
Count
Source
195
9
      : SparcTargetInfo(Triple, Opts) {
196
    // FIXME: Support Sparc quad-precision long double?
197
9
    resetDataLayout("E-m:e-i64:64-n32:64-S128");
198
    // This is an LP64 platform.
199
9
    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
200
201
    // OpenBSD uses long long for int64_t and intmax_t.
202
9
    if (getTriple().isOSOpenBSD())
203
0
      IntMaxType = SignedLongLong;
204
9
    else
205
9
      IntMaxType = SignedLong;
206
9
    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
9
    LongDoubleWidth = 128;
211
9
    LongDoubleAlign = 128;
212
9
    SuitableAlign = 128;
213
9
    LongDoubleFormat = &llvm::APFloat::IEEEquad();
214
9
    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
215
9
  }
clang::targets::SparcV9TargetInfo::SparcV9TargetInfo(llvm::Triple const&, clang::TargetOptions const&)
Line
Count
Source
195
26
      : SparcTargetInfo(Triple, Opts) {
196
    // FIXME: Support Sparc quad-precision long double?
197
26
    resetDataLayout("E-m:e-i64:64-n32:64-S128");
198
    // This is an LP64 platform.
199
26
    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
200
201
    // OpenBSD uses long long for int64_t and intmax_t.
202
26
    if (getTriple().isOSOpenBSD())
203
11
      IntMaxType = SignedLongLong;
204
15
    else
205
15
      IntMaxType = SignedLong;
206
26
    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
26
    LongDoubleWidth = 128;
211
26
    LongDoubleAlign = 128;
212
26
    SuitableAlign = 128;
213
26
    LongDoubleFormat = &llvm::APFloat::IEEEquad();
214
26
    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
215
26
  }
216
217
  void getTargetDefines(const LangOptions &Opts,
218
                        MacroBuilder &Builder) const override;
219
220
0
  bool isValidCPUName(StringRef Name) const override {
221
0
    return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9;
222
0
  }
223
224
  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
225
226
9
  bool setCPU(const std::string &Name) override {
227
9
    if (!SparcTargetInfo::setCPU(Name))
228
1
      return false;
229
8
    return getCPUGeneration(CPU) == CG_V9;
230
9
  }
231
232
15
  bool hasBitIntType() const override { return true; }
233
};
234
} // namespace targets
235
} // namespace clang
236
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H