10b57cec5SDimitry Andric //===--- Sparc.cpp - Tools Implementations ----------------------*- C++ -*-===//
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 #include "Sparc.h"
100b57cec5SDimitry Andric #include "clang/Driver/Driver.h"
110b57cec5SDimitry Andric #include "clang/Driver/DriverDiagnostic.h"
120b57cec5SDimitry Andric #include "clang/Driver/Options.h"
130b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
140b57cec5SDimitry Andric #include "llvm/Option/ArgList.h"
1506c3fb27SDimitry Andric #include "llvm/TargetParser/Host.h"
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric using namespace clang::driver;
180b57cec5SDimitry Andric using namespace clang::driver::tools;
190b57cec5SDimitry Andric using namespace clang;
200b57cec5SDimitry Andric using namespace llvm::opt;
210b57cec5SDimitry Andric
getSparcAsmModeForCPU(StringRef Name,const llvm::Triple & Triple)220b57cec5SDimitry Andric const char *sparc::getSparcAsmModeForCPU(StringRef Name,
230b57cec5SDimitry Andric const llvm::Triple &Triple) {
240b57cec5SDimitry Andric if (Triple.getArch() == llvm::Triple::sparcv9) {
2516d6b3b3SDimitry Andric const char *DefV9CPU;
2616d6b3b3SDimitry Andric
2716d6b3b3SDimitry Andric if (Triple.isOSLinux() || Triple.isOSFreeBSD() || Triple.isOSOpenBSD())
2816d6b3b3SDimitry Andric DefV9CPU = "-Av9a";
2916d6b3b3SDimitry Andric else
3016d6b3b3SDimitry Andric DefV9CPU = "-Av9";
3116d6b3b3SDimitry Andric
320b57cec5SDimitry Andric return llvm::StringSwitch<const char *>(Name)
330b57cec5SDimitry Andric .Case("niagara", "-Av9b")
340b57cec5SDimitry Andric .Case("niagara2", "-Av9b")
350b57cec5SDimitry Andric .Case("niagara3", "-Av9d")
360b57cec5SDimitry Andric .Case("niagara4", "-Av9d")
3716d6b3b3SDimitry Andric .Default(DefV9CPU);
380b57cec5SDimitry Andric } else {
390b57cec5SDimitry Andric return llvm::StringSwitch<const char *>(Name)
400b57cec5SDimitry Andric .Case("v8", "-Av8")
410b57cec5SDimitry Andric .Case("supersparc", "-Av8")
420b57cec5SDimitry Andric .Case("sparclite", "-Asparclite")
430b57cec5SDimitry Andric .Case("f934", "-Asparclite")
440b57cec5SDimitry Andric .Case("hypersparc", "-Av8")
450b57cec5SDimitry Andric .Case("sparclite86x", "-Asparclite")
460b57cec5SDimitry Andric .Case("sparclet", "-Asparclet")
470b57cec5SDimitry Andric .Case("tsc701", "-Asparclet")
480b57cec5SDimitry Andric .Case("v9", "-Av8plus")
490b57cec5SDimitry Andric .Case("ultrasparc", "-Av8plus")
500b57cec5SDimitry Andric .Case("ultrasparc3", "-Av8plus")
510b57cec5SDimitry Andric .Case("niagara", "-Av8plusb")
520b57cec5SDimitry Andric .Case("niagara2", "-Av8plusb")
530b57cec5SDimitry Andric .Case("niagara3", "-Av8plusd")
540b57cec5SDimitry Andric .Case("niagara4", "-Av8plusd")
550b57cec5SDimitry Andric .Case("ma2100", "-Aleon")
560b57cec5SDimitry Andric .Case("ma2150", "-Aleon")
570b57cec5SDimitry Andric .Case("ma2155", "-Aleon")
580b57cec5SDimitry Andric .Case("ma2450", "-Aleon")
590b57cec5SDimitry Andric .Case("ma2455", "-Aleon")
600b57cec5SDimitry Andric .Case("ma2x5x", "-Aleon")
610b57cec5SDimitry Andric .Case("ma2080", "-Aleon")
620b57cec5SDimitry Andric .Case("ma2085", "-Aleon")
630b57cec5SDimitry Andric .Case("ma2480", "-Aleon")
640b57cec5SDimitry Andric .Case("ma2485", "-Aleon")
650b57cec5SDimitry Andric .Case("ma2x8x", "-Aleon")
660b57cec5SDimitry Andric .Case("leon2", "-Av8")
670b57cec5SDimitry Andric .Case("at697e", "-Av8")
680b57cec5SDimitry Andric .Case("at697f", "-Av8")
690b57cec5SDimitry Andric .Case("leon3", "-Aleon")
700b57cec5SDimitry Andric .Case("ut699", "-Av8")
710b57cec5SDimitry Andric .Case("gr712rc", "-Aleon")
720b57cec5SDimitry Andric .Case("leon4", "-Aleon")
730b57cec5SDimitry Andric .Case("gr740", "-Aleon")
740b57cec5SDimitry Andric .Default("-Av8");
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric
getSparcFloatABI(const Driver & D,const ArgList & Args)780b57cec5SDimitry Andric sparc::FloatABI sparc::getSparcFloatABI(const Driver &D,
790b57cec5SDimitry Andric const ArgList &Args) {
800b57cec5SDimitry Andric sparc::FloatABI ABI = sparc::FloatABI::Invalid;
81bdd1243dSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mno_fpu,
82bdd1243dSDimitry Andric options::OPT_mhard_float, options::OPT_mfpu,
830b57cec5SDimitry Andric options::OPT_mfloat_abi_EQ)) {
84bdd1243dSDimitry Andric if (A->getOption().matches(options::OPT_msoft_float) ||
85bdd1243dSDimitry Andric A->getOption().matches(options::OPT_mno_fpu))
860b57cec5SDimitry Andric ABI = sparc::FloatABI::Soft;
87bdd1243dSDimitry Andric else if (A->getOption().matches(options::OPT_mhard_float) ||
88bdd1243dSDimitry Andric A->getOption().matches(options::OPT_mfpu))
890b57cec5SDimitry Andric ABI = sparc::FloatABI::Hard;
900b57cec5SDimitry Andric else {
910b57cec5SDimitry Andric ABI = llvm::StringSwitch<sparc::FloatABI>(A->getValue())
920b57cec5SDimitry Andric .Case("soft", sparc::FloatABI::Soft)
930b57cec5SDimitry Andric .Case("hard", sparc::FloatABI::Hard)
940b57cec5SDimitry Andric .Default(sparc::FloatABI::Invalid);
950b57cec5SDimitry Andric if (ABI == sparc::FloatABI::Invalid &&
960b57cec5SDimitry Andric !StringRef(A->getValue()).empty()) {
970b57cec5SDimitry Andric D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
980b57cec5SDimitry Andric ABI = sparc::FloatABI::Hard;
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andric // If unspecified, choose the default based on the platform.
1040b57cec5SDimitry Andric // Only the hard-float ABI on Sparc is standardized, and it is the
1050b57cec5SDimitry Andric // default. GCC also supports a nonstandard soft-float ABI mode, also
1060b57cec5SDimitry Andric // implemented in LLVM. However as this is not standard we set the default
1070b57cec5SDimitry Andric // to be hard-float.
1080b57cec5SDimitry Andric if (ABI == sparc::FloatABI::Invalid) {
1090b57cec5SDimitry Andric ABI = sparc::FloatABI::Hard;
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andric return ABI;
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric
getSparcTargetCPU(const Driver & D,const ArgList & Args,const llvm::Triple & Triple)11561cfbce3SDimitry Andric std::string sparc::getSparcTargetCPU(const Driver &D, const ArgList &Args,
11661cfbce3SDimitry Andric const llvm::Triple &Triple) {
11761cfbce3SDimitry Andric if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {
11861cfbce3SDimitry Andric StringRef CPUName = A->getValue();
11961cfbce3SDimitry Andric if (CPUName == "native") {
12061cfbce3SDimitry Andric std::string CPU = std::string(llvm::sys::getHostCPUName());
12161cfbce3SDimitry Andric if (!CPU.empty() && CPU != "generic")
12261cfbce3SDimitry Andric return CPU;
12361cfbce3SDimitry Andric return "";
12461cfbce3SDimitry Andric }
12561cfbce3SDimitry Andric return std::string(CPUName);
12661cfbce3SDimitry Andric }
12761cfbce3SDimitry Andric
12861cfbce3SDimitry Andric if (Triple.getArch() == llvm::Triple::sparc && Triple.isOSSolaris())
12961cfbce3SDimitry Andric return "v9";
13061cfbce3SDimitry Andric return "";
13161cfbce3SDimitry Andric }
13261cfbce3SDimitry Andric
getSparcTargetFeatures(const Driver & D,const ArgList & Args,std::vector<StringRef> & Features)1330b57cec5SDimitry Andric void sparc::getSparcTargetFeatures(const Driver &D, const ArgList &Args,
1340b57cec5SDimitry Andric std::vector<StringRef> &Features) {
1350b57cec5SDimitry Andric sparc::FloatABI FloatABI = sparc::getSparcFloatABI(D, Args);
1360b57cec5SDimitry Andric if (FloatABI == sparc::FloatABI::Soft)
1370b57cec5SDimitry Andric Features.push_back("+soft-float");
138bdd1243dSDimitry Andric
139bdd1243dSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_mfsmuld, options::OPT_mno_fsmuld)) {
140bdd1243dSDimitry Andric if (A->getOption().matches(options::OPT_mfsmuld))
141bdd1243dSDimitry Andric Features.push_back("+fsmuld");
142bdd1243dSDimitry Andric else
143bdd1243dSDimitry Andric Features.push_back("-fsmuld");
144bdd1243dSDimitry Andric }
145bdd1243dSDimitry Andric
146bdd1243dSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_mpopc, options::OPT_mno_popc)) {
147bdd1243dSDimitry Andric if (A->getOption().matches(options::OPT_mpopc))
148bdd1243dSDimitry Andric Features.push_back("+popc");
149bdd1243dSDimitry Andric else
150bdd1243dSDimitry Andric Features.push_back("-popc");
151bdd1243dSDimitry Andric }
152bdd1243dSDimitry Andric
153bdd1243dSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_mvis, options::OPT_mno_vis)) {
154bdd1243dSDimitry Andric if (A->getOption().matches(options::OPT_mvis))
155bdd1243dSDimitry Andric Features.push_back("+vis");
156bdd1243dSDimitry Andric else
157bdd1243dSDimitry Andric Features.push_back("-vis");
158bdd1243dSDimitry Andric }
159bdd1243dSDimitry Andric
160bdd1243dSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_mvis2, options::OPT_mno_vis2)) {
161bdd1243dSDimitry Andric if (A->getOption().matches(options::OPT_mvis2))
162bdd1243dSDimitry Andric Features.push_back("+vis2");
163bdd1243dSDimitry Andric else
164bdd1243dSDimitry Andric Features.push_back("-vis2");
165bdd1243dSDimitry Andric }
166bdd1243dSDimitry Andric
167bdd1243dSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_mvis3, options::OPT_mno_vis3)) {
168bdd1243dSDimitry Andric if (A->getOption().matches(options::OPT_mvis3))
169bdd1243dSDimitry Andric Features.push_back("+vis3");
170bdd1243dSDimitry Andric else
171bdd1243dSDimitry Andric Features.push_back("-vis3");
172bdd1243dSDimitry Andric }
173bdd1243dSDimitry Andric
174bdd1243dSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_mhard_quad_float,
175bdd1243dSDimitry Andric options::OPT_msoft_quad_float)) {
176bdd1243dSDimitry Andric if (A->getOption().matches(options::OPT_mhard_quad_float))
177bdd1243dSDimitry Andric Features.push_back("+hard-quad-float");
178bdd1243dSDimitry Andric else
179bdd1243dSDimitry Andric Features.push_back("-hard-quad-float");
180bdd1243dSDimitry Andric }
18174626c16SDimitry Andric
18274626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_g1))
18374626c16SDimitry Andric Features.push_back("+reserve-g1");
18474626c16SDimitry Andric
18574626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_g2))
18674626c16SDimitry Andric Features.push_back("+reserve-g2");
18774626c16SDimitry Andric
18874626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_g3))
18974626c16SDimitry Andric Features.push_back("+reserve-g3");
19074626c16SDimitry Andric
19174626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_g4))
19274626c16SDimitry Andric Features.push_back("+reserve-g4");
19374626c16SDimitry Andric
19474626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_g5))
19574626c16SDimitry Andric Features.push_back("+reserve-g5");
19674626c16SDimitry Andric
19774626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_g6))
19874626c16SDimitry Andric Features.push_back("+reserve-g6");
19974626c16SDimitry Andric
20074626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_g7))
20174626c16SDimitry Andric Features.push_back("+reserve-g7");
20274626c16SDimitry Andric
20374626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_o0))
20474626c16SDimitry Andric Features.push_back("+reserve-o0");
20574626c16SDimitry Andric
20674626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_o1))
20774626c16SDimitry Andric Features.push_back("+reserve-o1");
20874626c16SDimitry Andric
20974626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_o2))
21074626c16SDimitry Andric Features.push_back("+reserve-o2");
21174626c16SDimitry Andric
21274626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_o3))
21374626c16SDimitry Andric Features.push_back("+reserve-o3");
21474626c16SDimitry Andric
21574626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_o4))
21674626c16SDimitry Andric Features.push_back("+reserve-o4");
21774626c16SDimitry Andric
21874626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_o5))
21974626c16SDimitry Andric Features.push_back("+reserve-o5");
22074626c16SDimitry Andric
22174626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_l0))
22274626c16SDimitry Andric Features.push_back("+reserve-l0");
22374626c16SDimitry Andric
22474626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_l1))
22574626c16SDimitry Andric Features.push_back("+reserve-l1");
22674626c16SDimitry Andric
22774626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_l2))
22874626c16SDimitry Andric Features.push_back("+reserve-l2");
22974626c16SDimitry Andric
23074626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_l3))
23174626c16SDimitry Andric Features.push_back("+reserve-l3");
23274626c16SDimitry Andric
23374626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_l4))
23474626c16SDimitry Andric Features.push_back("+reserve-l4");
23574626c16SDimitry Andric
23674626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_l5))
23774626c16SDimitry Andric Features.push_back("+reserve-l5");
23874626c16SDimitry Andric
23974626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_l6))
24074626c16SDimitry Andric Features.push_back("+reserve-l6");
24174626c16SDimitry Andric
24274626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_l7))
24374626c16SDimitry Andric Features.push_back("+reserve-l7");
24474626c16SDimitry Andric
24574626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_i0))
24674626c16SDimitry Andric Features.push_back("+reserve-i0");
24774626c16SDimitry Andric
24874626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_i1))
24974626c16SDimitry Andric Features.push_back("+reserve-i1");
25074626c16SDimitry Andric
25174626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_i2))
25274626c16SDimitry Andric Features.push_back("+reserve-i2");
25374626c16SDimitry Andric
25474626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_i3))
25574626c16SDimitry Andric Features.push_back("+reserve-i3");
25674626c16SDimitry Andric
25774626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_i4))
25874626c16SDimitry Andric Features.push_back("+reserve-i4");
25974626c16SDimitry Andric
26074626c16SDimitry Andric if (Args.hasArg(options::OPT_ffixed_i5))
26174626c16SDimitry Andric Features.push_back("+reserve-i5");
2620b57cec5SDimitry Andric }
263