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