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 { 36bdd1243dSDimitry 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 { 51bdd1243dSDimitry 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 {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8}, 970b57cec5SDimitry Andric {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8}, 980b57cec5SDimitry Andric {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8}, 990b57cec5SDimitry Andric {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8}, 1000b57cec5SDimitry Andric {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8}, 1010b57cec5SDimitry Andric {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8}, 1020b57cec5SDimitry Andric {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8}, 1030b57cec5SDimitry Andric {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8}, 1040b57cec5SDimitry Andric }; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric SparcTargetInfo::CPUGeneration 1070b57cec5SDimitry Andric SparcTargetInfo::getCPUGeneration(CPUKind Kind) const { 1080b57cec5SDimitry Andric if (Kind == CK_GENERIC) 1090b57cec5SDimitry Andric return CG_V8; 1100b57cec5SDimitry Andric const SparcCPUInfo *Item = llvm::find_if( 1110b57cec5SDimitry Andric CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; }); 1120b57cec5SDimitry Andric if (Item == std::end(CPUInfo)) 1130b57cec5SDimitry Andric llvm_unreachable("Unexpected CPU kind"); 1140b57cec5SDimitry Andric return Item->Generation; 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const { 1180b57cec5SDimitry Andric const SparcCPUInfo *Item = llvm::find_if( 1190b57cec5SDimitry Andric CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; }); 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric if (Item == std::end(CPUInfo)) 1220b57cec5SDimitry Andric return CK_GENERIC; 1230b57cec5SDimitry Andric return Item->Kind; 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric void SparcTargetInfo::fillValidCPUList( 1270b57cec5SDimitry Andric SmallVectorImpl<StringRef> &Values) const { 1280b57cec5SDimitry Andric for (const SparcCPUInfo &Info : CPUInfo) 1290b57cec5SDimitry Andric Values.push_back(Info.Name); 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric void SparcTargetInfo::getTargetDefines(const LangOptions &Opts, 1330b57cec5SDimitry Andric MacroBuilder &Builder) const { 1340b57cec5SDimitry Andric DefineStd(Builder, "sparc", Opts); 1350b57cec5SDimitry Andric Builder.defineMacro("__REGISTER_PREFIX__", ""); 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric if (SoftFloat) 1380b57cec5SDimitry Andric Builder.defineMacro("SOFT_FLOAT", "1"); 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts, 1420b57cec5SDimitry Andric MacroBuilder &Builder) const { 1430b57cec5SDimitry Andric SparcTargetInfo::getTargetDefines(Opts, Builder); 144*5f757f3fSDimitry Andric if (getTriple().isOSSolaris()) 145e8d8bef9SDimitry Andric Builder.defineMacro("__sparcv8"); 146e8d8bef9SDimitry Andric else { 1470b57cec5SDimitry Andric switch (getCPUGeneration(CPU)) { 1480b57cec5SDimitry Andric case CG_V8: 1490b57cec5SDimitry Andric Builder.defineMacro("__sparcv8"); 1500b57cec5SDimitry Andric Builder.defineMacro("__sparcv8__"); 1510b57cec5SDimitry Andric break; 1520b57cec5SDimitry Andric case CG_V9: 1530b57cec5SDimitry Andric Builder.defineMacro("__sparc_v9__"); 1540b57cec5SDimitry Andric break; 1550b57cec5SDimitry Andric } 156e8d8bef9SDimitry Andric } 157e8d8bef9SDimitry Andric if (getCPUGeneration(CPU) == CG_V9) { 158e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 159e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 160e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 161e8d8bef9SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 162e8d8bef9SDimitry Andric } 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts, 1660b57cec5SDimitry Andric MacroBuilder &Builder) const { 1670b57cec5SDimitry Andric SparcTargetInfo::getTargetDefines(Opts, Builder); 1680b57cec5SDimitry Andric Builder.defineMacro("__sparcv9"); 1690b57cec5SDimitry Andric Builder.defineMacro("__arch64__"); 1700b57cec5SDimitry Andric // Solaris doesn't need these variants, but the BSDs do. 171*5f757f3fSDimitry Andric if (!getTriple().isOSSolaris()) { 1720b57cec5SDimitry Andric Builder.defineMacro("__sparc64__"); 1730b57cec5SDimitry Andric Builder.defineMacro("__sparc_v9__"); 1740b57cec5SDimitry Andric Builder.defineMacro("__sparcv9__"); 1750b57cec5SDimitry Andric } 17675b4d546SDimitry Andric 17775b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 17875b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 17975b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 18075b4d546SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric void SparcV9TargetInfo::fillValidCPUList( 1840b57cec5SDimitry Andric SmallVectorImpl<StringRef> &Values) const { 1850b57cec5SDimitry Andric for (const SparcCPUInfo &Info : CPUInfo) 1860b57cec5SDimitry Andric if (Info.Generation == CG_V9) 1870b57cec5SDimitry Andric Values.push_back(Info.Name); 1880b57cec5SDimitry Andric } 189