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