Clang Project

clang_source_code/lib/Basic/Targets/Sparc.cpp
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
18using namespace clang;
19using namespace clang::targets;
20
21const 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
35ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
36  return llvm::makeArrayRef(GCCRegNames);
37}
38
39const 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
50ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
51  return llvm::makeArrayRef(GCCRegAliases);
52}
53
54bool SparcTargetInfo::hasFeature(StringRef Feature) const {
55  return llvm::StringSwitch<bool>(Feature)
56      .Case("softfloat", SoftFloat)
57      .Case("sparc"true)
58      .Default(false);
59}
60
61struct SparcCPUInfo {
62  llvm::StringLiteral Name;
63  SparcTargetInfo::CPUKind Kind;
64  SparcTargetInfo::CPUGeneration Generation;
65};
66
67static 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
112SparcTargetInfo::CPUGeneration
113SparcTargetInfo::getCPUGeneration(CPUKind Kind) const {
114  if (Kind == CK_GENERIC)
115    return CG_V8;
116  const SparcCPUInfo *Item = llvm::find_if(
117      CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; });
118  if (Item == std::end(CPUInfo))
119    llvm_unreachable("Unexpected CPU kind");
120  return Item->Generation;
121}
122
123SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const {
124  const SparcCPUInfo *Item = llvm::find_if(
125      CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; });
126
127  if (Item == std::end(CPUInfo))
128    return CK_GENERIC;
129  return Item->Kind;
130}
131
132void SparcTargetInfo::fillValidCPUList(
133    SmallVectorImpl<StringRef> &Values) const {
134  for (const SparcCPUInfo &Info : CPUInfo)
135    Values.push_back(Info.Name);
136}
137
138void SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
139                                       MacroBuilder &Builder) const {
140  DefineStd(Builder, "sparc", Opts);
141  Builder.defineMacro("__REGISTER_PREFIX__""");
142
143  if (SoftFloat)
144    Builder.defineMacro("SOFT_FLOAT""1");
145}
146
147void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
148                                         MacroBuilder &Builder) const {
149  SparcTargetInfo::getTargetDefines(Opts, Builder);
150  switch (getCPUGeneration(CPU)) {
151  case CG_V8:
152    Builder.defineMacro("__sparcv8");
153    if (getTriple().getOS() != llvm::Triple::Solaris)
154      Builder.defineMacro("__sparcv8__");
155    break;
156  case CG_V9:
157    Builder.defineMacro("__sparcv9");
158    if (getTriple().getOS() != llvm::Triple::Solaris) {
159      Builder.defineMacro("__sparcv9__");
160      Builder.defineMacro("__sparc_v9__");
161    }
162    break;
163  }
164  if (getTriple().getVendor() == llvm::Triple::Myriad) {
165    std::string MyriadArchValue, Myriad2Value;
166    Builder.defineMacro("__sparc_v8__");
167    Builder.defineMacro("__leon__");
168    switch (CPU) {
169    case CK_MYRIAD2100:
170      MyriadArchValue = "__ma2100";
171      Myriad2Value = "1";
172      break;
173    case CK_MYRIAD2150:
174      MyriadArchValue = "__ma2150";
175      Myriad2Value = "2";
176      break;
177    case CK_MYRIAD2155:
178      MyriadArchValue = "__ma2155";
179      Myriad2Value = "2";
180      break;
181    case CK_MYRIAD2450:
182      MyriadArchValue = "__ma2450";
183      Myriad2Value = "2";
184      break;
185    case CK_MYRIAD2455:
186      MyriadArchValue = "__ma2455";
187      Myriad2Value = "2";
188      break;
189    case CK_MYRIAD2x5x:
190      Myriad2Value = "2";
191      break;
192    case CK_MYRIAD2080:
193      MyriadArchValue = "__ma2080";
194      Myriad2Value = "3";
195      break;
196    case CK_MYRIAD2085:
197      MyriadArchValue = "__ma2085";
198      Myriad2Value = "3";
199      break;
200    case CK_MYRIAD2480:
201      MyriadArchValue = "__ma2480";
202      Myriad2Value = "3";
203      break;
204    case CK_MYRIAD2485:
205      MyriadArchValue = "__ma2485";
206      Myriad2Value = "3";
207      break;
208    case CK_MYRIAD2x8x:
209      Myriad2Value = "3";
210      break;
211    default:
212      MyriadArchValue = "__ma2100";
213      Myriad2Value = "1";
214      break;
215    }
216    if (!MyriadArchValue.empty()) {
217      Builder.defineMacro(MyriadArchValue, "1");
218      Builder.defineMacro(MyriadArchValue + "__""1");
219    }
220    if (Myriad2Value == "2") {
221      Builder.defineMacro("__ma2x5x""1");
222      Builder.defineMacro("__ma2x5x__""1");
223    } else if (Myriad2Value == "3") {
224      Builder.defineMacro("__ma2x8x""1");
225      Builder.defineMacro("__ma2x8x__""1");
226    }
227    Builder.defineMacro("__myriad2__", Myriad2Value);
228    Builder.defineMacro("__myriad2", Myriad2Value);
229  }
230}
231
232void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
233                                         MacroBuilder &Builder) const {
234  SparcTargetInfo::getTargetDefines(Opts, Builder);
235  Builder.defineMacro("__sparcv9");
236  Builder.defineMacro("__arch64__");
237  // Solaris doesn't need these variants, but the BSDs do.
238  if (getTriple().getOS() != llvm::Triple::Solaris) {
239    Builder.defineMacro("__sparc64__");
240    Builder.defineMacro("__sparc_v9__");
241    Builder.defineMacro("__sparcv9__");
242  }
243}
244
245void SparcV9TargetInfo::fillValidCPUList(
246    SmallVectorImpl<StringRef> &Values) const {
247  for (const SparcCPUInfo &Info : CPUInfo)
248    if (Info.Generation == CG_V9)
249      Values.push_back(Info.Name);
250}
251