Coverage Report

Created: 2020-09-19 12:23

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