Coverage Report

Created: 2022-07-16 07:03

/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
88
      : 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
78
                            DiagnosticsEngine &Diags) override {
41
    // Check if software floating point is enabled
42
78
    if (llvm::is_contained(Features, "+soft-float"))
43
1
      SoftFloat = true;
44
78
    return true;
45
78
  }
46
  void getTargetDefines(const LangOptions &Opts,
47
                        MacroBuilder &Builder) const override;
48
49
  bool hasFeature(StringRef Feature) const override;
50
51
78
  ArrayRef<Builtin::Info> getTargetBuiltins() const override {
52
    // FIXME: Implement!
53
78
    return None;
54
78
  }
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
28
  bool setCPU(const std::string &Name) override {
140
28
    CPU = getCPUKind(Name);
141
28
    return CPU != CK_GENERIC;
142
28
  }
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
51
      : SparcTargetInfo(Triple, Opts) {
150
51
    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
51
    switch (getTriple().getOS()) {
153
49
    default:
154
49
      SizeType = UnsignedInt;
155
49
      IntPtrType = SignedInt;
156
49
      PtrDiffType = SignedInt;
157
49
      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
51
    }
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
51
    MaxAtomicPromoteWidth = 64;
168
51
    if (getCPUGeneration(CPU) == CG_V9)
169
0
      MaxAtomicInlineWidth = 64;
170
51
    else
171
      // FIXME: This isn't correct for plain V8 which lacks CAS,
172
      // only for LEON 3+ and Myriad.
173
51
      MaxAtomicInlineWidth = 32;
174
51
  }
clang::targets::SparcV8TargetInfo::SparcV8TargetInfo(llvm::Triple const&, clang::TargetOptions const&)
Line
Count
Source
149
25
      : SparcTargetInfo(Triple, Opts) {
150
25
    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
25
    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
0
    case llvm::Triple::OpenBSD:
160
0
      SizeType = UnsignedLong;
161
0
      IntPtrType = SignedLong;
162
0
      PtrDiffType = SignedLong;
163
0
      break;
164
25
    }
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
25
    MaxAtomicPromoteWidth = 64;
168
25
    if (getCPUGeneration(CPU) == CG_V9)
169
0
      MaxAtomicInlineWidth = 64;
170
25
    else
171
      // FIXME: This isn't correct for plain V8 which lacks CAS,
172
      // only for LEON 3+ and Myriad.
173
25
      MaxAtomicInlineWidth = 32;
174
25
  }
clang::targets::SparcV8TargetInfo::SparcV8TargetInfo(llvm::Triple const&, clang::TargetOptions const&)
Line
Count
Source
149
26
      : SparcTargetInfo(Triple, Opts) {
150
26
    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
26
    switch (getTriple().getOS()) {
153
24
    default:
154
24
      SizeType = UnsignedInt;
155
24
      IntPtrType = SignedInt;
156
24
      PtrDiffType = SignedInt;
157
24
      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
26
    }
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
26
    MaxAtomicPromoteWidth = 64;
168
26
    if (getCPUGeneration(CPU) == CG_V9)
169
0
      MaxAtomicInlineWidth = 64;
170
26
    else
171
      // FIXME: This isn't correct for plain V8 which lacks CAS,
172
      // only for LEON 3+ and Myriad.
173
26
      MaxAtomicInlineWidth = 32;
174
26
  }
175
176
  void getTargetDefines(const LangOptions &Opts,
177
                        MacroBuilder &Builder) const override;
178
179
10
  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
16
      : SparcV8TargetInfo(Triple, Opts) {
187
16
    resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");
188
16
  }
clang::targets::SparcV8elTargetInfo::SparcV8elTargetInfo(llvm::Triple const&, clang::TargetOptions const&)
Line
Count
Source
186
15
      : SparcV8TargetInfo(Triple, Opts) {
187
15
    resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");
188
15
  }
clang::targets::SparcV8elTargetInfo::SparcV8elTargetInfo(llvm::Triple const&, clang::TargetOptions const&)
Line
Count
Source
186
1
      : SparcV8TargetInfo(Triple, Opts) {
187
1
    resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");
188
1
  }
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
37
      : SparcTargetInfo(Triple, Opts) {
196
    // FIXME: Support Sparc quad-precision long double?
197
37
    resetDataLayout("E-m:e-i64:64-n32:64-S128");
198
    // This is an LP64 platform.
199
37
    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
200
201
    // OpenBSD uses long long for int64_t and intmax_t.
202
37
    if (getTriple().isOSOpenBSD())
203
11
      IntMaxType = SignedLongLong;
204
26
    else
205
26
      IntMaxType = SignedLong;
206
37
    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
37
    LongDoubleWidth = 128;
211
37
    LongDoubleAlign = 128;
212
37
    SuitableAlign = 128;
213
37
    LongDoubleFormat = &llvm::APFloat::IEEEquad();
214
37
    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
215
37
  }
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
28
      : SparcTargetInfo(Triple, Opts) {
196
    // FIXME: Support Sparc quad-precision long double?
197
28
    resetDataLayout("E-m:e-i64:64-n32:64-S128");
198
    // This is an LP64 platform.
199
28
    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
200
201
    // OpenBSD uses long long for int64_t and intmax_t.
202
28
    if (getTriple().isOSOpenBSD())
203
11
      IntMaxType = SignedLongLong;
204
17
    else
205
17
      IntMaxType = SignedLong;
206
28
    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
28
    LongDoubleWidth = 128;
211
28
    LongDoubleAlign = 128;
212
28
    SuitableAlign = 128;
213
28
    LongDoubleFormat = &llvm::APFloat::IEEEquad();
214
28
    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
215
28
  }
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
10
  bool hasBitIntType() const override { return true; }
233
};
234
} // namespace targets
235
} // namespace clang
236
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H