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 { 360b57cec5SDimitry Andric return llvm::makeArrayRef(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 { 510b57cec5SDimitry Andric return llvm::makeArrayRef(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); 150*e8d8bef9SDimitry Andric if (getTriple().getOS() == llvm::Triple::Solaris) 151*e8d8bef9SDimitry Andric Builder.defineMacro("__sparcv8"); 152*e8d8bef9SDimitry 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("__sparcv9"); 1600b57cec5SDimitry Andric Builder.defineMacro("__sparcv9__"); 1610b57cec5SDimitry Andric Builder.defineMacro("__sparc_v9__"); 1620b57cec5SDimitry Andric break; 1630b57cec5SDimitry Andric } 164*e8d8bef9SDimitry Andric } 1650b57cec5SDimitry Andric if (getTriple().getVendor() == llvm::Triple::Myriad) { 1660b57cec5SDimitry Andric std::string MyriadArchValue, Myriad2Value; 1670b57cec5SDimitry Andric Builder.defineMacro("__sparc_v8__"); 1680b57cec5SDimitry Andric Builder.defineMacro("__leon__"); 1690b57cec5SDimitry Andric switch (CPU) { 1700b57cec5SDimitry Andric case CK_MYRIAD2100: 1710b57cec5SDimitry Andric MyriadArchValue = "__ma2100"; 1720b57cec5SDimitry Andric Myriad2Value = "1"; 1730b57cec5SDimitry Andric break; 1740b57cec5SDimitry Andric case CK_MYRIAD2150: 1750b57cec5SDimitry Andric MyriadArchValue = "__ma2150"; 1760b57cec5SDimitry Andric Myriad2Value = "2"; 1770b57cec5SDimitry Andric break; 1780b57cec5SDimitry Andric case CK_MYRIAD2155: 1790b57cec5SDimitry Andric MyriadArchValue = "__ma2155"; 1800b57cec5SDimitry Andric Myriad2Value = "2"; 1810b57cec5SDimitry Andric break; 1820b57cec5SDimitry Andric case CK_MYRIAD2450: 1830b57cec5SDimitry Andric MyriadArchValue = "__ma2450"; 1840b57cec5SDimitry Andric Myriad2Value = "2"; 1850b57cec5SDimitry Andric break; 1860b57cec5SDimitry Andric case CK_MYRIAD2455: 1870b57cec5SDimitry Andric MyriadArchValue = "__ma2455"; 1880b57cec5SDimitry Andric Myriad2Value = "2"; 1890b57cec5SDimitry Andric break; 1900b57cec5SDimitry Andric case CK_MYRIAD2x5x: 1910b57cec5SDimitry Andric Myriad2Value = "2"; 1920b57cec5SDimitry Andric break; 1930b57cec5SDimitry Andric case CK_MYRIAD2080: 1940b57cec5SDimitry Andric MyriadArchValue = "__ma2080"; 1950b57cec5SDimitry Andric Myriad2Value = "3"; 1960b57cec5SDimitry Andric break; 1970b57cec5SDimitry Andric case CK_MYRIAD2085: 1980b57cec5SDimitry Andric MyriadArchValue = "__ma2085"; 1990b57cec5SDimitry Andric Myriad2Value = "3"; 2000b57cec5SDimitry Andric break; 2010b57cec5SDimitry Andric case CK_MYRIAD2480: 2020b57cec5SDimitry Andric MyriadArchValue = "__ma2480"; 2030b57cec5SDimitry Andric Myriad2Value = "3"; 2040b57cec5SDimitry Andric break; 2050b57cec5SDimitry Andric case CK_MYRIAD2485: 2060b57cec5SDimitry Andric MyriadArchValue = "__ma2485"; 2070b57cec5SDimitry Andric Myriad2Value = "3"; 2080b57cec5SDimitry Andric break; 2090b57cec5SDimitry Andric case CK_MYRIAD2x8x: 2100b57cec5SDimitry Andric Myriad2Value = "3"; 2110b57cec5SDimitry Andric break; 2120b57cec5SDimitry Andric default: 2130b57cec5SDimitry Andric MyriadArchValue = "__ma2100"; 2140b57cec5SDimitry Andric Myriad2Value = "1"; 2150b57cec5SDimitry Andric break; 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric if (!MyriadArchValue.empty()) { 2180b57cec5SDimitry Andric Builder.defineMacro(MyriadArchValue, "1"); 2190b57cec5SDimitry Andric Builder.defineMacro(MyriadArchValue + "__", "1"); 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric if (Myriad2Value == "2") { 2220b57cec5SDimitry Andric Builder.defineMacro("__ma2x5x", "1"); 2230b57cec5SDimitry Andric Builder.defineMacro("__ma2x5x__", "1"); 2240b57cec5SDimitry Andric } else if (Myriad2Value == "3") { 2250b57cec5SDimitry Andric Builder.defineMacro("__ma2x8x", "1"); 2260b57cec5SDimitry Andric Builder.defineMacro("__ma2x8x__", "1"); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric Builder.defineMacro("__myriad2__", Myriad2Value); 2290b57cec5SDimitry Andric Builder.defineMacro("__myriad2", Myriad2Value); 2300b57cec5SDimitry Andric } 231*e8d8bef9SDimitry Andric if (getCPUGeneration(CPU) == CG_V9) { 232*e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 233*e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 234*e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 235*e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 236*e8d8bef9SDimitry Andric } 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts, 2400b57cec5SDimitry Andric MacroBuilder &Builder) const { 2410b57cec5SDimitry Andric SparcTargetInfo::getTargetDefines(Opts, Builder); 2420b57cec5SDimitry Andric Builder.defineMacro("__sparcv9"); 2430b57cec5SDimitry Andric Builder.defineMacro("__arch64__"); 2440b57cec5SDimitry Andric // Solaris doesn't need these variants, but the BSDs do. 2450b57cec5SDimitry Andric if (getTriple().getOS() != llvm::Triple::Solaris) { 2460b57cec5SDimitry Andric Builder.defineMacro("__sparc64__"); 2470b57cec5SDimitry Andric Builder.defineMacro("__sparc_v9__"); 2480b57cec5SDimitry Andric Builder.defineMacro("__sparcv9__"); 2490b57cec5SDimitry Andric } 25075b4d546SDimitry Andric 25175b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 25275b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 25375b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 25475b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 2550b57cec5SDimitry Andric } 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric void SparcV9TargetInfo::fillValidCPUList( 2580b57cec5SDimitry Andric SmallVectorImpl<StringRef> &Values) const { 2590b57cec5SDimitry Andric for (const SparcCPUInfo &Info : CPUInfo) 2600b57cec5SDimitry Andric if (Info.Generation == CG_V9) 2610b57cec5SDimitry Andric Values.push_back(Info.Name); 2620b57cec5SDimitry Andric } 263