1326941Sdim//===--- Sparc.cpp - Implement Sparc target feature support ---------------===//
2326941Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6326941Sdim//
7326941Sdim//===----------------------------------------------------------------------===//
8326941Sdim//
9326941Sdim// This file implements Sparc TargetInfo objects.
10326941Sdim//
11326941Sdim//===----------------------------------------------------------------------===//
12326941Sdim
13326941Sdim#include "Sparc.h"
14326941Sdim#include "Targets.h"
15326941Sdim#include "clang/Basic/MacroBuilder.h"
16326941Sdim#include "llvm/ADT/StringSwitch.h"
17326941Sdim
18326941Sdimusing namespace clang;
19326941Sdimusing namespace clang::targets;
20326941Sdim
21326941Sdimconst char *const SparcTargetInfo::GCCRegNames[] = {
22341825Sdim    // Integer registers
23326941Sdim    "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",  "r9",  "r10",
24326941Sdim    "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
25341825Sdim    "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
26341825Sdim
27341825Sdim    // Floating-point registers
28341825Sdim    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",  "f8",  "f9",  "f10",
29341825Sdim    "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
30341825Sdim    "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32",
31341825Sdim    "f34", "f36", "f38", "f40", "f42", "f44", "f46", "f48", "f50", "f52", "f54",
32341825Sdim    "f56", "f58", "f60", "f62",
33326941Sdim};
34326941Sdim
35326941SdimArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
36326941Sdim  return llvm::makeArrayRef(GCCRegNames);
37326941Sdim}
38326941Sdim
39326941Sdimconst TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
40326941Sdim    {{"g0"}, "r0"},  {{"g1"}, "r1"},  {{"g2"}, "r2"},        {{"g3"}, "r3"},
41326941Sdim    {{"g4"}, "r4"},  {{"g5"}, "r5"},  {{"g6"}, "r6"},        {{"g7"}, "r7"},
42326941Sdim    {{"o0"}, "r8"},  {{"o1"}, "r9"},  {{"o2"}, "r10"},       {{"o3"}, "r11"},
43326941Sdim    {{"o4"}, "r12"}, {{"o5"}, "r13"}, {{"o6", "sp"}, "r14"}, {{"o7"}, "r15"},
44326941Sdim    {{"l0"}, "r16"}, {{"l1"}, "r17"}, {{"l2"}, "r18"},       {{"l3"}, "r19"},
45326941Sdim    {{"l4"}, "r20"}, {{"l5"}, "r21"}, {{"l6"}, "r22"},       {{"l7"}, "r23"},
46326941Sdim    {{"i0"}, "r24"}, {{"i1"}, "r25"}, {{"i2"}, "r26"},       {{"i3"}, "r27"},
47326941Sdim    {{"i4"}, "r28"}, {{"i5"}, "r29"}, {{"i6", "fp"}, "r30"}, {{"i7"}, "r31"},
48326941Sdim};
49326941Sdim
50326941SdimArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
51326941Sdim  return llvm::makeArrayRef(GCCRegAliases);
52326941Sdim}
53326941Sdim
54326941Sdimbool SparcTargetInfo::hasFeature(StringRef Feature) const {
55326941Sdim  return llvm::StringSwitch<bool>(Feature)
56326941Sdim      .Case("softfloat", SoftFloat)
57326941Sdim      .Case("sparc", true)
58326941Sdim      .Default(false);
59326941Sdim}
60326941Sdim
61341825Sdimstruct SparcCPUInfo {
62341825Sdim  llvm::StringLiteral Name;
63341825Sdim  SparcTargetInfo::CPUKind Kind;
64341825Sdim  SparcTargetInfo::CPUGeneration Generation;
65341825Sdim};
66341825Sdim
67341825Sdimstatic constexpr SparcCPUInfo CPUInfo[] = {
68341825Sdim    {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8},
69341825Sdim    {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8},
70341825Sdim    {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8},
71341825Sdim    {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8},
72341825Sdim    {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8},
73341825Sdim    {{"sparclite86x"},
74341825Sdim     SparcTargetInfo::CK_SPARCLITE86X,
75341825Sdim     SparcTargetInfo::CG_V8},
76341825Sdim    {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8},
77341825Sdim    {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8},
78341825Sdim    {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9},
79341825Sdim    {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9},
80341825Sdim    {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9},
81341825Sdim    {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9},
82341825Sdim    {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9},
83341825Sdim    {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9},
84341825Sdim    {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9},
85341825Sdim    {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
86341825Sdim    {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8},
87341825Sdim    {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8},
88341825Sdim    {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8},
89341825Sdim    {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8},
90341825Sdim    {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
91341825Sdim    {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8},
92341825Sdim    {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8},
93341825Sdim    {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8},
94341825Sdim    {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8},
95341825Sdim    {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
96341825Sdim    // FIXME: the myriad2[.n] spellings are obsolete,
97341825Sdim    // but a grace period is needed to allow updating dependent builds.
98341825Sdim    {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
99341825Sdim    {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8},
100341825Sdim    {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8},
101341825Sdim    {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8},
102341825Sdim    {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8},
103341825Sdim    {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8},
104341825Sdim    {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8},
105341825Sdim    {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8},
106341825Sdim    {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8},
107341825Sdim    {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8},
108341825Sdim    {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8},
109341825Sdim    {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8},
110341825Sdim};
111341825Sdim
112341825SdimSparcTargetInfo::CPUGeneration
113341825SdimSparcTargetInfo::getCPUGeneration(CPUKind Kind) const {
114341825Sdim  if (Kind == CK_GENERIC)
115341825Sdim    return CG_V8;
116341825Sdim  const SparcCPUInfo *Item = llvm::find_if(
117341825Sdim      CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; });
118341825Sdim  if (Item == std::end(CPUInfo))
119341825Sdim    llvm_unreachable("Unexpected CPU kind");
120341825Sdim  return Item->Generation;
121341825Sdim}
122341825Sdim
123326941SdimSparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const {
124341825Sdim  const SparcCPUInfo *Item = llvm::find_if(
125341825Sdim      CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; });
126341825Sdim
127341825Sdim  if (Item == std::end(CPUInfo))
128341825Sdim    return CK_GENERIC;
129341825Sdim  return Item->Kind;
130326941Sdim}
131326941Sdim
132341825Sdimvoid SparcTargetInfo::fillValidCPUList(
133341825Sdim    SmallVectorImpl<StringRef> &Values) const {
134341825Sdim  for (const SparcCPUInfo &Info : CPUInfo)
135341825Sdim    Values.push_back(Info.Name);
136341825Sdim}
137341825Sdim
138326941Sdimvoid SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
139326941Sdim                                       MacroBuilder &Builder) const {
140326941Sdim  DefineStd(Builder, "sparc", Opts);
141326941Sdim  Builder.defineMacro("__REGISTER_PREFIX__", "");
142326941Sdim
143326941Sdim  if (SoftFloat)
144326941Sdim    Builder.defineMacro("SOFT_FLOAT", "1");
145326941Sdim}
146326941Sdim
147326941Sdimvoid SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
148326941Sdim                                         MacroBuilder &Builder) const {
149326941Sdim  SparcTargetInfo::getTargetDefines(Opts, Builder);
150326941Sdim  switch (getCPUGeneration(CPU)) {
151326941Sdim  case CG_V8:
152326941Sdim    Builder.defineMacro("__sparcv8");
153326941Sdim    if (getTriple().getOS() != llvm::Triple::Solaris)
154326941Sdim      Builder.defineMacro("__sparcv8__");
155326941Sdim    break;
156326941Sdim  case CG_V9:
157326941Sdim    Builder.defineMacro("__sparcv9");
158326941Sdim    if (getTriple().getOS() != llvm::Triple::Solaris) {
159326941Sdim      Builder.defineMacro("__sparcv9__");
160326941Sdim      Builder.defineMacro("__sparc_v9__");
161326941Sdim    }
162326941Sdim    break;
163326941Sdim  }
164326941Sdim  if (getTriple().getVendor() == llvm::Triple::Myriad) {
165326941Sdim    std::string MyriadArchValue, Myriad2Value;
166326941Sdim    Builder.defineMacro("__sparc_v8__");
167326941Sdim    Builder.defineMacro("__leon__");
168326941Sdim    switch (CPU) {
169326941Sdim    case CK_MYRIAD2100:
170326941Sdim      MyriadArchValue = "__ma2100";
171326941Sdim      Myriad2Value = "1";
172326941Sdim      break;
173326941Sdim    case CK_MYRIAD2150:
174326941Sdim      MyriadArchValue = "__ma2150";
175326941Sdim      Myriad2Value = "2";
176326941Sdim      break;
177326941Sdim    case CK_MYRIAD2155:
178326941Sdim      MyriadArchValue = "__ma2155";
179326941Sdim      Myriad2Value = "2";
180326941Sdim      break;
181326941Sdim    case CK_MYRIAD2450:
182326941Sdim      MyriadArchValue = "__ma2450";
183326941Sdim      Myriad2Value = "2";
184326941Sdim      break;
185326941Sdim    case CK_MYRIAD2455:
186326941Sdim      MyriadArchValue = "__ma2455";
187326941Sdim      Myriad2Value = "2";
188326941Sdim      break;
189326941Sdim    case CK_MYRIAD2x5x:
190326941Sdim      Myriad2Value = "2";
191326941Sdim      break;
192326941Sdim    case CK_MYRIAD2080:
193326941Sdim      MyriadArchValue = "__ma2080";
194326941Sdim      Myriad2Value = "3";
195326941Sdim      break;
196326941Sdim    case CK_MYRIAD2085:
197326941Sdim      MyriadArchValue = "__ma2085";
198326941Sdim      Myriad2Value = "3";
199326941Sdim      break;
200326941Sdim    case CK_MYRIAD2480:
201326941Sdim      MyriadArchValue = "__ma2480";
202326941Sdim      Myriad2Value = "3";
203326941Sdim      break;
204326941Sdim    case CK_MYRIAD2485:
205326941Sdim      MyriadArchValue = "__ma2485";
206326941Sdim      Myriad2Value = "3";
207326941Sdim      break;
208326941Sdim    case CK_MYRIAD2x8x:
209326941Sdim      Myriad2Value = "3";
210326941Sdim      break;
211326941Sdim    default:
212326941Sdim      MyriadArchValue = "__ma2100";
213326941Sdim      Myriad2Value = "1";
214326941Sdim      break;
215326941Sdim    }
216326941Sdim    if (!MyriadArchValue.empty()) {
217326941Sdim      Builder.defineMacro(MyriadArchValue, "1");
218326941Sdim      Builder.defineMacro(MyriadArchValue + "__", "1");
219326941Sdim    }
220341825Sdim    if (Myriad2Value == "2") {
221341825Sdim      Builder.defineMacro("__ma2x5x", "1");
222341825Sdim      Builder.defineMacro("__ma2x5x__", "1");
223341825Sdim    } else if (Myriad2Value == "3") {
224341825Sdim      Builder.defineMacro("__ma2x8x", "1");
225341825Sdim      Builder.defineMacro("__ma2x8x__", "1");
226341825Sdim    }
227326941Sdim    Builder.defineMacro("__myriad2__", Myriad2Value);
228326941Sdim    Builder.defineMacro("__myriad2", Myriad2Value);
229326941Sdim  }
230326941Sdim}
231326941Sdim
232326941Sdimvoid SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
233326941Sdim                                         MacroBuilder &Builder) const {
234326941Sdim  SparcTargetInfo::getTargetDefines(Opts, Builder);
235326941Sdim  Builder.defineMacro("__sparcv9");
236326941Sdim  Builder.defineMacro("__arch64__");
237326941Sdim  // Solaris doesn't need these variants, but the BSDs do.
238326941Sdim  if (getTriple().getOS() != llvm::Triple::Solaris) {
239326941Sdim    Builder.defineMacro("__sparc64__");
240326941Sdim    Builder.defineMacro("__sparc_v9__");
241326941Sdim    Builder.defineMacro("__sparcv9__");
242326941Sdim  }
243326941Sdim}
244341825Sdim
245341825Sdimvoid SparcV9TargetInfo::fillValidCPUList(
246341825Sdim    SmallVectorImpl<StringRef> &Values) const {
247341825Sdim  for (const SparcCPUInfo &Info : CPUInfo)
248341825Sdim    if (Info.Generation == CG_V9)
249341825Sdim      Values.push_back(Info.Name);
250341825Sdim}
251