Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/Sparc.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- Sparc.cpp - Implement Sparc target feature support ---------------===//
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 implements Sparc TargetInfo objects.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "Sparc.h"
14
#include "Targets.h"
15
#include "clang/Basic/MacroBuilder.h"
16
#include "llvm/ADT/StringSwitch.h"
17
18
using namespace clang;
19
using namespace clang::targets;
20
21
const char *const SparcTargetInfo::GCCRegNames[] = {
22
    // Integer registers
23
    "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",  "r9",  "r10",
24
    "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
25
    "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
26
27
    // Floating-point registers
28
    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",  "f8",  "f9",  "f10",
29
    "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
30
    "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32",
31
    "f34", "f36", "f38", "f40", "f42", "f44", "f46", "f48", "f50", "f52", "f54",
32
    "f56", "f58", "f60", "f62",
33
};
34
35
198
ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
36
198
  return llvm::makeArrayRef(GCCRegNames);
37
198
}
38
39
const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
40
    {{"g0"}, "r0"},  {{"g1"}, "r1"},  {{"g2"}, "r2"},        {{"g3"}, "r3"},
41
    {{"g4"}, "r4"},  {{"g5"}, "r5"},  {{"g6"}, "r6"},        {{"g7"}, "r7"},
42
    {{"o0"}, "r8"},  {{"o1"}, "r9"},  {{"o2"}, "r10"},       {{"o3"}, "r11"},
43
    {{"o4"}, "r12"}, {{"o5"}, "r13"}, {{"o6", "sp"}, "r14"}, {{"o7"}, "r15"},
44
    {{"l0"}, "r16"}, {{"l1"}, "r17"}, {{"l2"}, "r18"},       {{"l3"}, "r19"},
45
    {{"l4"}, "r20"}, {{"l5"}, "r21"}, {{"l6"}, "r22"},       {{"l7"}, "r23"},
46
    {{"i0"}, "r24"}, {{"i1"}, "r25"}, {{"i2"}, "r26"},       {{"i3"}, "r27"},
47
    {{"i4"}, "r28"}, {{"i5"}, "r29"}, {{"i6", "fp"}, "r30"}, {{"i7"}, "r31"},
48
};
49
50
100
ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
51
100
  return llvm::makeArrayRef(GCCRegAliases);
52
100
}
53
54
26
bool SparcTargetInfo::hasFeature(StringRef Feature) const {
55
26
  return llvm::StringSwitch<bool>(Feature)
56
26
      .Case("softfloat", SoftFloat)
57
26
      .Case("sparc", true)
58
26
      .Default(false);
59
26
}
60
61
struct SparcCPUInfo {
62
  llvm::StringLiteral Name;
63
  SparcTargetInfo::CPUKind Kind;
64
  SparcTargetInfo::CPUGeneration Generation;
65
};
66
67
static constexpr SparcCPUInfo CPUInfo[] = {
68
    {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8},
69
    {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8},
70
    {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8},
71
    {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8},
72
    {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8},
73
    {{"sparclite86x"},
74
     SparcTargetInfo::CK_SPARCLITE86X,
75
     SparcTargetInfo::CG_V8},
76
    {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8},
77
    {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8},
78
    {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9},
79
    {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9},
80
    {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9},
81
    {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9},
82
    {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9},
83
    {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9},
84
    {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9},
85
    {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
86
    {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8},
87
    {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8},
88
    {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8},
89
    {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8},
90
    {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
91
    {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8},
92
    {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8},
93
    {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8},
94
    {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8},
95
    {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
96
    // FIXME: the myriad2[.n] spellings are obsolete,
97
    // but a grace period is needed to allow updating dependent builds.
98
    {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
99
    {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
100
    {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
101
    {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
102
    {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8},
103
    {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8},
104
    {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8},
105
    {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8},
106
    {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8},
107
    {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8},
108
    {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8},
109
    {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8},
110
};
111
112
SparcTargetInfo::CPUGeneration
113
103
SparcTargetInfo::getCPUGeneration(CPUKind Kind) const {
114
103
  if (Kind == CK_GENERIC)
115
95
    return CG_V8;
116
8
  const SparcCPUInfo *Item = llvm::find_if(
117
36
      CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; });
118
8
  if (Item == std::end(CPUInfo))
119
0
    llvm_unreachable("Unexpected CPU kind");
120
8
  return Item->Generation;
121
103
}
122
123
10
SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const {
124
10
  const SparcCPUInfo *Item = llvm::find_if(
125
112
      CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; });
126
127
10
  if (Item == std::end(CPUInfo))
128
2
    return CK_GENERIC;
129
8
  return Item->Kind;
130
10
}
131
132
void SparcTargetInfo::fillValidCPUList(
133
1
    SmallVectorImpl<StringRef> &Values) const {
134
1
  for (const SparcCPUInfo &Info : CPUInfo)
135
38
    Values.push_back(Info.Name);
136
1
}
137
138
void SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
139
58
                                       MacroBuilder &Builder) const {
140
58
  DefineStd(Builder, "sparc", Opts);
141
58
  Builder.defineMacro("__REGISTER_PREFIX__", "");
142
143
58
  if (SoftFloat)
144
1
    Builder.defineMacro("SOFT_FLOAT", "1");
145
58
}
146
147
void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
148
32
                                         MacroBuilder &Builder) const {
149
32
  SparcTargetInfo::getTargetDefines(Opts, Builder);
150
32
  if (getTriple().getOS() == llvm::Triple::Solaris)
151
2
    Builder.defineMacro("__sparcv8");
152
30
  else {
153
30
    switch (getCPUGeneration(CPU)) {
154
30
    case CG_V8:
155
30
      Builder.defineMacro("__sparcv8");
156
30
      Builder.defineMacro("__sparcv8__");
157
30
      break;
158
0
    case CG_V9:
159
0
      Builder.defineMacro("__sparcv9");
160
0
      Builder.defineMacro("__sparcv9__");
161
0
      Builder.defineMacro("__sparc_v9__");
162
0
      break;
163
30
    }
164
30
  }
165
32
  if (getTriple().getVendor() == llvm::Triple::Myriad) {
166
0
    std::string MyriadArchValue, Myriad2Value;
167
0
    Builder.defineMacro("__sparc_v8__");
168
0
    Builder.defineMacro("__leon__");
169
0
    switch (CPU) {
170
0
    case CK_MYRIAD2100:
171
0
      MyriadArchValue = "__ma2100";
172
0
      Myriad2Value = "1";
173
0
      break;
174
0
    case CK_MYRIAD2150:
175
0
      MyriadArchValue = "__ma2150";
176
0
      Myriad2Value = "2";
177
0
      break;
178
0
    case CK_MYRIAD2155:
179
0
      MyriadArchValue = "__ma2155";
180
0
      Myriad2Value = "2";
181
0
      break;
182
0
    case CK_MYRIAD2450:
183
0
      MyriadArchValue = "__ma2450";
184
0
      Myriad2Value = "2";
185
0
      break;
186
0
    case CK_MYRIAD2455:
187
0
      MyriadArchValue = "__ma2455";
188
0
      Myriad2Value = "2";
189
0
      break;
190
0
    case CK_MYRIAD2x5x:
191
0
      Myriad2Value = "2";
192
0
      break;
193
0
    case CK_MYRIAD2080:
194
0
      MyriadArchValue = "__ma2080";
195
0
      Myriad2Value = "3";
196
0
      break;
197
0
    case CK_MYRIAD2085:
198
0
      MyriadArchValue = "__ma2085";
199
0
      Myriad2Value = "3";
200
0
      break;
201
0
    case CK_MYRIAD2480:
202
0
      MyriadArchValue = "__ma2480";
203
0
      Myriad2Value = "3";
204
0
      break;
205
0
    case CK_MYRIAD2485:
206
0
      MyriadArchValue = "__ma2485";
207
0
      Myriad2Value = "3";
208
0
      break;
209
0
    case CK_MYRIAD2x8x:
210
0
      Myriad2Value = "3";
211
0
      break;
212
0
    default:
213
0
      MyriadArchValue = "__ma2100";
214
0
      Myriad2Value = "1";
215
0
      break;
216
0
    }
217
0
    if (!MyriadArchValue.empty()) {
218
0
      Builder.defineMacro(MyriadArchValue, "1");
219
0
      Builder.defineMacro(MyriadArchValue + "__", "1");
220
0
    }
221
0
    if (Myriad2Value == "2") {
222
0
      Builder.defineMacro("__ma2x5x", "1");
223
0
      Builder.defineMacro("__ma2x5x__", "1");
224
0
    } else if (Myriad2Value == "3") {
225
0
      Builder.defineMacro("__ma2x8x", "1");
226
0
      Builder.defineMacro("__ma2x8x__", "1");
227
0
    }
228
0
    Builder.defineMacro("__myriad2__", Myriad2Value);
229
0
    Builder.defineMacro("__myriad2", Myriad2Value);
230
0
  }
231
32
  if (getCPUGeneration(CPU) == CG_V9) {
232
0
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
233
0
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
234
0
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
235
0
    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
236
0
  }
237
32
}
238
239
void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
240
26
                                         MacroBuilder &Builder) const {
241
26
  SparcTargetInfo::getTargetDefines(Opts, Builder);
242
26
  Builder.defineMacro("__sparcv9");
243
26
  Builder.defineMacro("__arch64__");
244
  // Solaris doesn't need these variants, but the BSDs do.
245
26
  if (getTriple().getOS() != llvm::Triple::Solaris) {
246
25
    Builder.defineMacro("__sparc64__");
247
25
    Builder.defineMacro("__sparc_v9__");
248
25
    Builder.defineMacro("__sparcv9__");
249
25
  }
250
251
26
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
252
26
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
253
26
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
254
26
  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
255
26
}
256
257
void SparcV9TargetInfo::fillValidCPUList(
258
9
    SmallVectorImpl<StringRef> &Values) const {
259
9
  for (const SparcCPUInfo &Info : CPUInfo)
260
342
    if (Info.Generation == CG_V9)
261
63
      Values.push_back(Info.Name);
262
9
}