10b57cec5SDimitry Andric //===--- Sparc.cpp - Implement Sparc target feature support ---------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements Sparc TargetInfo objects. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "Sparc.h" 140b57cec5SDimitry Andric #include "Targets.h" 150b57cec5SDimitry Andric #include "clang/Basic/MacroBuilder.h" 160b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric using namespace clang; 190b57cec5SDimitry Andric using namespace clang::targets; 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric const char *const SparcTargetInfo::GCCRegNames[] = { 220b57cec5SDimitry Andric // Integer registers 230b57cec5SDimitry Andric "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 240b57cec5SDimitry Andric "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", 250b57cec5SDimitry Andric "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric // Floating-point registers 280b57cec5SDimitry Andric "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", 290b57cec5SDimitry Andric "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", 300b57cec5SDimitry Andric "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32", 310b57cec5SDimitry Andric "f34", "f36", "f38", "f40", "f42", "f44", "f46", "f48", "f50", "f52", "f54", 320b57cec5SDimitry Andric "f56", "f58", "f60", "f62", 330b57cec5SDimitry Andric }; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const { 36*bdd1243dSDimitry Andric return llvm::ArrayRef(GCCRegNames); 370b57cec5SDimitry Andric } 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = { 400b57cec5SDimitry Andric {{"g0"}, "r0"}, {{"g1"}, "r1"}, {{"g2"}, "r2"}, {{"g3"}, "r3"}, 410b57cec5SDimitry Andric {{"g4"}, "r4"}, {{"g5"}, "r5"}, {{"g6"}, "r6"}, {{"g7"}, "r7"}, 420b57cec5SDimitry Andric {{"o0"}, "r8"}, {{"o1"}, "r9"}, {{"o2"}, "r10"}, {{"o3"}, "r11"}, 430b57cec5SDimitry Andric {{"o4"}, "r12"}, {{"o5"}, "r13"}, {{"o6", "sp"}, "r14"}, {{"o7"}, "r15"}, 440b57cec5SDimitry Andric {{"l0"}, "r16"}, {{"l1"}, "r17"}, {{"l2"}, "r18"}, {{"l3"}, "r19"}, 450b57cec5SDimitry Andric {{"l4"}, "r20"}, {{"l5"}, "r21"}, {{"l6"}, "r22"}, {{"l7"}, "r23"}, 460b57cec5SDimitry Andric {{"i0"}, "r24"}, {{"i1"}, "r25"}, {{"i2"}, "r26"}, {{"i3"}, "r27"}, 470b57cec5SDimitry Andric {{"i4"}, "r28"}, {{"i5"}, "r29"}, {{"i6", "fp"}, "r30"}, {{"i7"}, "r31"}, 480b57cec5SDimitry Andric }; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const { 51*bdd1243dSDimitry Andric return llvm::ArrayRef(GCCRegAliases); 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric bool SparcTargetInfo::hasFeature(StringRef Feature) const { 550b57cec5SDimitry Andric return llvm::StringSwitch<bool>(Feature) 560b57cec5SDimitry Andric .Case("softfloat", SoftFloat) 570b57cec5SDimitry Andric .Case("sparc", true) 580b57cec5SDimitry Andric .Default(false); 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric struct SparcCPUInfo { 620b57cec5SDimitry Andric llvm::StringLiteral Name; 630b57cec5SDimitry Andric SparcTargetInfo::CPUKind Kind; 640b57cec5SDimitry Andric SparcTargetInfo::CPUGeneration Generation; 650b57cec5SDimitry Andric }; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric static constexpr SparcCPUInfo CPUInfo[] = { 680b57cec5SDimitry Andric {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8}, 690b57cec5SDimitry Andric {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8}, 700b57cec5SDimitry Andric {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8}, 710b57cec5SDimitry Andric {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8}, 720b57cec5SDimitry Andric {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8}, 730b57cec5SDimitry Andric {{"sparclite86x"}, 740b57cec5SDimitry Andric SparcTargetInfo::CK_SPARCLITE86X, 750b57cec5SDimitry Andric SparcTargetInfo::CG_V8}, 760b57cec5SDimitry Andric {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8}, 770b57cec5SDimitry Andric {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8}, 780b57cec5SDimitry Andric {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9}, 790b57cec5SDimitry Andric {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9}, 800b57cec5SDimitry Andric {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9}, 810b57cec5SDimitry Andric {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9}, 820b57cec5SDimitry Andric {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9}, 830b57cec5SDimitry Andric {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9}, 840b57cec5SDimitry Andric {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9}, 850b57cec5SDimitry Andric {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8}, 860b57cec5SDimitry Andric {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8}, 870b57cec5SDimitry Andric {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8}, 880b57cec5SDimitry Andric {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8}, 890b57cec5SDimitry Andric {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8}, 900b57cec5SDimitry Andric {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, 910b57cec5SDimitry Andric {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8}, 920b57cec5SDimitry Andric {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8}, 930b57cec5SDimitry Andric {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8}, 940b57cec5SDimitry Andric {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8}, 950b57cec5SDimitry Andric {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8}, 960b57cec5SDimitry Andric // FIXME: the myriad2[.n] spellings are obsolete, 970b57cec5SDimitry Andric // but a grace period is needed to allow updating dependent builds. 980b57cec5SDimitry Andric {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, 990b57cec5SDimitry Andric {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8}, 1000b57cec5SDimitry Andric {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, 1010b57cec5SDimitry Andric {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8}, 1020b57cec5SDimitry Andric {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8}, 1030b57cec5SDimitry Andric {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8}, 1040b57cec5SDimitry Andric {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8}, 1050b57cec5SDimitry Andric {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8}, 1060b57cec5SDimitry Andric {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8}, 1070b57cec5SDimitry Andric {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8}, 1080b57cec5SDimitry Andric {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8}, 1090b57cec5SDimitry Andric {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8}, 1100b57cec5SDimitry Andric }; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric SparcTargetInfo::CPUGeneration 1130b57cec5SDimitry Andric SparcTargetInfo::getCPUGeneration(CPUKind Kind) const { 1140b57cec5SDimitry Andric if (Kind == CK_GENERIC) 1150b57cec5SDimitry Andric return CG_V8; 1160b57cec5SDimitry Andric const SparcCPUInfo *Item = llvm::find_if( 1170b57cec5SDimitry Andric CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; }); 1180b57cec5SDimitry Andric if (Item == std::end(CPUInfo)) 1190b57cec5SDimitry Andric llvm_unreachable("Unexpected CPU kind"); 1200b57cec5SDimitry Andric return Item->Generation; 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const { 1240b57cec5SDimitry Andric const SparcCPUInfo *Item = llvm::find_if( 1250b57cec5SDimitry Andric CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; }); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric if (Item == std::end(CPUInfo)) 1280b57cec5SDimitry Andric return CK_GENERIC; 1290b57cec5SDimitry Andric return Item->Kind; 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric void SparcTargetInfo::fillValidCPUList( 1330b57cec5SDimitry Andric SmallVectorImpl<StringRef> &Values) const { 1340b57cec5SDimitry Andric for (const SparcCPUInfo &Info : CPUInfo) 1350b57cec5SDimitry Andric Values.push_back(Info.Name); 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric void SparcTargetInfo::getTargetDefines(const LangOptions &Opts, 1390b57cec5SDimitry Andric MacroBuilder &Builder) const { 1400b57cec5SDimitry Andric DefineStd(Builder, "sparc", Opts); 1410b57cec5SDimitry Andric Builder.defineMacro("__REGISTER_PREFIX__", ""); 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric if (SoftFloat) 1440b57cec5SDimitry Andric Builder.defineMacro("SOFT_FLOAT", "1"); 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts, 1480b57cec5SDimitry Andric MacroBuilder &Builder) const { 1490b57cec5SDimitry Andric SparcTargetInfo::getTargetDefines(Opts, Builder); 150e8d8bef9SDimitry Andric if (getTriple().getOS() == llvm::Triple::Solaris) 151e8d8bef9SDimitry Andric Builder.defineMacro("__sparcv8"); 152e8d8bef9SDimitry Andric else { 1530b57cec5SDimitry Andric switch (getCPUGeneration(CPU)) { 1540b57cec5SDimitry Andric case CG_V8: 1550b57cec5SDimitry Andric Builder.defineMacro("__sparcv8"); 1560b57cec5SDimitry Andric Builder.defineMacro("__sparcv8__"); 1570b57cec5SDimitry Andric break; 1580b57cec5SDimitry Andric case CG_V9: 1590b57cec5SDimitry Andric Builder.defineMacro("__sparc_v9__"); 1600b57cec5SDimitry Andric break; 1610b57cec5SDimitry Andric } 162e8d8bef9SDimitry Andric } 1630b57cec5SDimitry Andric if (getTriple().getVendor() == llvm::Triple::Myriad) { 1640b57cec5SDimitry Andric std::string MyriadArchValue, Myriad2Value; 1650b57cec5SDimitry Andric Builder.defineMacro("__sparc_v8__"); 1660b57cec5SDimitry Andric Builder.defineMacro("__leon__"); 1670b57cec5SDimitry Andric switch (CPU) { 1680b57cec5SDimitry Andric case CK_MYRIAD2100: 1690b57cec5SDimitry Andric MyriadArchValue = "__ma2100"; 1700b57cec5SDimitry Andric Myriad2Value = "1"; 1710b57cec5SDimitry Andric break; 1720b57cec5SDimitry Andric case CK_MYRIAD2150: 1730b57cec5SDimitry Andric MyriadArchValue = "__ma2150"; 1740b57cec5SDimitry Andric Myriad2Value = "2"; 1750b57cec5SDimitry Andric break; 1760b57cec5SDimitry Andric case CK_MYRIAD2155: 1770b57cec5SDimitry Andric MyriadArchValue = "__ma2155"; 1780b57cec5SDimitry Andric Myriad2Value = "2"; 1790b57cec5SDimitry Andric break; 1800b57cec5SDimitry Andric case CK_MYRIAD2450: 1810b57cec5SDimitry Andric MyriadArchValue = "__ma2450"; 1820b57cec5SDimitry Andric Myriad2Value = "2"; 1830b57cec5SDimitry Andric break; 1840b57cec5SDimitry Andric case CK_MYRIAD2455: 1850b57cec5SDimitry Andric MyriadArchValue = "__ma2455"; 1860b57cec5SDimitry Andric Myriad2Value = "2"; 1870b57cec5SDimitry Andric break; 1880b57cec5SDimitry Andric case CK_MYRIAD2x5x: 1890b57cec5SDimitry Andric Myriad2Value = "2"; 1900b57cec5SDimitry Andric break; 1910b57cec5SDimitry Andric case CK_MYRIAD2080: 1920b57cec5SDimitry Andric MyriadArchValue = "__ma2080"; 1930b57cec5SDimitry Andric Myriad2Value = "3"; 1940b57cec5SDimitry Andric break; 1950b57cec5SDimitry Andric case CK_MYRIAD2085: 1960b57cec5SDimitry Andric MyriadArchValue = "__ma2085"; 1970b57cec5SDimitry Andric Myriad2Value = "3"; 1980b57cec5SDimitry Andric break; 1990b57cec5SDimitry Andric case CK_MYRIAD2480: 2000b57cec5SDimitry Andric MyriadArchValue = "__ma2480"; 2010b57cec5SDimitry Andric Myriad2Value = "3"; 2020b57cec5SDimitry Andric break; 2030b57cec5SDimitry Andric case CK_MYRIAD2485: 2040b57cec5SDimitry Andric MyriadArchValue = "__ma2485"; 2050b57cec5SDimitry Andric Myriad2Value = "3"; 2060b57cec5SDimitry Andric break; 2070b57cec5SDimitry Andric case CK_MYRIAD2x8x: 2080b57cec5SDimitry Andric Myriad2Value = "3"; 2090b57cec5SDimitry Andric break; 2100b57cec5SDimitry Andric default: 2110b57cec5SDimitry Andric MyriadArchValue = "__ma2100"; 2120b57cec5SDimitry Andric Myriad2Value = "1"; 2130b57cec5SDimitry Andric break; 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric if (!MyriadArchValue.empty()) { 2160b57cec5SDimitry Andric Builder.defineMacro(MyriadArchValue, "1"); 2170b57cec5SDimitry Andric Builder.defineMacro(MyriadArchValue + "__", "1"); 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric if (Myriad2Value == "2") { 2200b57cec5SDimitry Andric Builder.defineMacro("__ma2x5x", "1"); 2210b57cec5SDimitry Andric Builder.defineMacro("__ma2x5x__", "1"); 2220b57cec5SDimitry Andric } else if (Myriad2Value == "3") { 2230b57cec5SDimitry Andric Builder.defineMacro("__ma2x8x", "1"); 2240b57cec5SDimitry Andric Builder.defineMacro("__ma2x8x__", "1"); 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric Builder.defineMacro("__myriad2__", Myriad2Value); 2270b57cec5SDimitry Andric Builder.defineMacro("__myriad2", Myriad2Value); 2280b57cec5SDimitry Andric } 229e8d8bef9SDimitry Andric if (getCPUGeneration(CPU) == CG_V9) { 230e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 231e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 232e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 233e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 234e8d8bef9SDimitry Andric } 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts, 2380b57cec5SDimitry Andric MacroBuilder &Builder) const { 2390b57cec5SDimitry Andric SparcTargetInfo::getTargetDefines(Opts, Builder); 2400b57cec5SDimitry Andric Builder.defineMacro("__sparcv9"); 2410b57cec5SDimitry Andric Builder.defineMacro("__arch64__"); 2420b57cec5SDimitry Andric // Solaris doesn't need these variants, but the BSDs do. 2430b57cec5SDimitry Andric if (getTriple().getOS() != llvm::Triple::Solaris) { 2440b57cec5SDimitry Andric Builder.defineMacro("__sparc64__"); 2450b57cec5SDimitry Andric Builder.defineMacro("__sparc_v9__"); 2460b57cec5SDimitry Andric Builder.defineMacro("__sparcv9__"); 2470b57cec5SDimitry Andric } 24875b4d546SDimitry Andric 24975b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 25075b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 25175b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 25275b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric void SparcV9TargetInfo::fillValidCPUList( 2560b57cec5SDimitry Andric SmallVectorImpl<StringRef> &Values) const { 2570b57cec5SDimitry Andric for (const SparcCPUInfo &Info : CPUInfo) 2580b57cec5SDimitry Andric if (Info.Generation == CG_V9) 2590b57cec5SDimitry Andric Values.push_back(Info.Name); 2600b57cec5SDimitry Andric } 261