/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/Arch/Sparc.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- Sparc.cpp - Tools Implementations ----------------------*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #include "Sparc.h" |
10 | | #include "clang/Driver/Driver.h" |
11 | | #include "clang/Driver/DriverDiagnostic.h" |
12 | | #include "clang/Driver/Options.h" |
13 | | #include "llvm/ADT/StringSwitch.h" |
14 | | #include "llvm/Option/ArgList.h" |
15 | | #include "llvm/TargetParser/Host.h" |
16 | | |
17 | | using namespace clang::driver; |
18 | | using namespace clang::driver::tools; |
19 | | using namespace clang; |
20 | | using namespace llvm::opt; |
21 | | |
22 | | const char *sparc::getSparcAsmModeForCPU(StringRef Name, |
23 | 66 | const llvm::Triple &Triple) { |
24 | 66 | if (Triple.getArch() == llvm::Triple::sparcv9) { |
25 | 23 | const char *DefV9CPU; |
26 | | |
27 | 23 | if (Triple.isOSLinux() || Triple.isOSFreeBSD()20 || Triple.isOSOpenBSD()19 ) |
28 | 5 | DefV9CPU = "-Av9a"; |
29 | 18 | else |
30 | 18 | DefV9CPU = "-Av9"; |
31 | | |
32 | 23 | return llvm::StringSwitch<const char *>(Name) |
33 | 23 | .Case("niagara", "-Av9b") |
34 | 23 | .Case("niagara2", "-Av9b") |
35 | 23 | .Case("niagara3", "-Av9d") |
36 | 23 | .Case("niagara4", "-Av9d") |
37 | 23 | .Default(DefV9CPU); |
38 | 43 | } else { |
39 | 43 | return llvm::StringSwitch<const char *>(Name) |
40 | 43 | .Case("v8", "-Av8") |
41 | 43 | .Case("supersparc", "-Av8") |
42 | 43 | .Case("sparclite", "-Asparclite") |
43 | 43 | .Case("f934", "-Asparclite") |
44 | 43 | .Case("hypersparc", "-Av8") |
45 | 43 | .Case("sparclite86x", "-Asparclite") |
46 | 43 | .Case("sparclet", "-Asparclet") |
47 | 43 | .Case("tsc701", "-Asparclet") |
48 | 43 | .Case("v9", "-Av8plus") |
49 | 43 | .Case("ultrasparc", "-Av8plus") |
50 | 43 | .Case("ultrasparc3", "-Av8plus") |
51 | 43 | .Case("niagara", "-Av8plusb") |
52 | 43 | .Case("niagara2", "-Av8plusb") |
53 | 43 | .Case("niagara3", "-Av8plusd") |
54 | 43 | .Case("niagara4", "-Av8plusd") |
55 | 43 | .Case("ma2100", "-Aleon") |
56 | 43 | .Case("ma2150", "-Aleon") |
57 | 43 | .Case("ma2155", "-Aleon") |
58 | 43 | .Case("ma2450", "-Aleon") |
59 | 43 | .Case("ma2455", "-Aleon") |
60 | 43 | .Case("ma2x5x", "-Aleon") |
61 | 43 | .Case("ma2080", "-Aleon") |
62 | 43 | .Case("ma2085", "-Aleon") |
63 | 43 | .Case("ma2480", "-Aleon") |
64 | 43 | .Case("ma2485", "-Aleon") |
65 | 43 | .Case("ma2x8x", "-Aleon") |
66 | 43 | .Case("leon2", "-Av8") |
67 | 43 | .Case("at697e", "-Av8") |
68 | 43 | .Case("at697f", "-Av8") |
69 | 43 | .Case("leon3", "-Aleon") |
70 | 43 | .Case("ut699", "-Av8") |
71 | 43 | .Case("gr712rc", "-Aleon") |
72 | 43 | .Case("leon4", "-Aleon") |
73 | 43 | .Case("gr740", "-Aleon") |
74 | 43 | .Default("-Av8"); |
75 | 43 | } |
76 | 66 | } |
77 | | |
78 | | sparc::FloatABI sparc::getSparcFloatABI(const Driver &D, |
79 | 418 | const ArgList &Args) { |
80 | 418 | sparc::FloatABI ABI = sparc::FloatABI::Invalid; |
81 | 418 | if (Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mno_fpu, |
82 | 418 | options::OPT_mhard_float, options::OPT_mfpu, |
83 | 418 | options::OPT_mfloat_abi_EQ)) { |
84 | 24 | if (A->getOption().matches(options::OPT_msoft_float) || |
85 | 24 | A->getOption().matches(options::OPT_mno_fpu)20 ) |
86 | 6 | ABI = sparc::FloatABI::Soft; |
87 | 18 | else if (A->getOption().matches(options::OPT_mhard_float) || |
88 | 18 | A->getOption().matches(options::OPT_mfpu)14 ) |
89 | 6 | ABI = sparc::FloatABI::Hard; |
90 | 12 | else { |
91 | 12 | ABI = llvm::StringSwitch<sparc::FloatABI>(A->getValue()) |
92 | 12 | .Case("soft", sparc::FloatABI::Soft) |
93 | 12 | .Case("hard", sparc::FloatABI::Hard) |
94 | 12 | .Default(sparc::FloatABI::Invalid); |
95 | 12 | if (ABI == sparc::FloatABI::Invalid && |
96 | 12 | !StringRef(A->getValue()).empty()4 ) { |
97 | 4 | D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); |
98 | 4 | ABI = sparc::FloatABI::Hard; |
99 | 4 | } |
100 | 12 | } |
101 | 24 | } |
102 | | |
103 | | // If unspecified, choose the default based on the platform. |
104 | | // Only the hard-float ABI on Sparc is standardized, and it is the |
105 | | // default. GCC also supports a nonstandard soft-float ABI mode, also |
106 | | // implemented in LLVM. However as this is not standard we set the default |
107 | | // to be hard-float. |
108 | 418 | if (ABI == sparc::FloatABI::Invalid) { |
109 | 394 | ABI = sparc::FloatABI::Hard; |
110 | 394 | } |
111 | | |
112 | 418 | return ABI; |
113 | 418 | } |
114 | | |
115 | | std::string sparc::getSparcTargetCPU(const Driver &D, const ArgList &Args, |
116 | 275 | const llvm::Triple &Triple) { |
117 | 275 | if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) { |
118 | 114 | StringRef CPUName = A->getValue(); |
119 | 114 | if (CPUName == "native") { |
120 | 0 | std::string CPU = std::string(llvm::sys::getHostCPUName()); |
121 | 0 | if (!CPU.empty() && CPU != "generic") |
122 | 0 | return CPU; |
123 | 0 | return ""; |
124 | 0 | } |
125 | 114 | return std::string(CPUName); |
126 | 114 | } |
127 | | |
128 | 161 | if (Triple.getArch() == llvm::Triple::sparc && Triple.isOSSolaris()101 ) |
129 | 45 | return "v9"; |
130 | 116 | return ""; |
131 | 161 | } |
132 | | |
133 | | void sparc::getSparcTargetFeatures(const Driver &D, const ArgList &Args, |
134 | 209 | std::vector<StringRef> &Features) { |
135 | 209 | sparc::FloatABI FloatABI = sparc::getSparcFloatABI(D, Args); |
136 | 209 | if (FloatABI == sparc::FloatABI::Soft) |
137 | 5 | Features.push_back("+soft-float"); |
138 | | |
139 | 209 | if (Arg *A = Args.getLastArg(options::OPT_mfsmuld, options::OPT_mno_fsmuld)) { |
140 | 2 | if (A->getOption().matches(options::OPT_mfsmuld)) |
141 | 1 | Features.push_back("+fsmuld"); |
142 | 1 | else |
143 | 1 | Features.push_back("-fsmuld"); |
144 | 2 | } |
145 | | |
146 | 209 | if (Arg *A = Args.getLastArg(options::OPT_mpopc, options::OPT_mno_popc)) { |
147 | 2 | if (A->getOption().matches(options::OPT_mpopc)) |
148 | 1 | Features.push_back("+popc"); |
149 | 1 | else |
150 | 1 | Features.push_back("-popc"); |
151 | 2 | } |
152 | | |
153 | 209 | if (Arg *A = Args.getLastArg(options::OPT_mvis, options::OPT_mno_vis)) { |
154 | 2 | if (A->getOption().matches(options::OPT_mvis)) |
155 | 1 | Features.push_back("+vis"); |
156 | 1 | else |
157 | 1 | Features.push_back("-vis"); |
158 | 2 | } |
159 | | |
160 | 209 | if (Arg *A = Args.getLastArg(options::OPT_mvis2, options::OPT_mno_vis2)) { |
161 | 2 | if (A->getOption().matches(options::OPT_mvis2)) |
162 | 1 | Features.push_back("+vis2"); |
163 | 1 | else |
164 | 1 | Features.push_back("-vis2"); |
165 | 2 | } |
166 | | |
167 | 209 | if (Arg *A = Args.getLastArg(options::OPT_mvis3, options::OPT_mno_vis3)) { |
168 | 2 | if (A->getOption().matches(options::OPT_mvis3)) |
169 | 1 | Features.push_back("+vis3"); |
170 | 1 | else |
171 | 1 | Features.push_back("-vis3"); |
172 | 2 | } |
173 | | |
174 | 209 | if (Arg *A = Args.getLastArg(options::OPT_mhard_quad_float, |
175 | 209 | options::OPT_msoft_quad_float)) { |
176 | 2 | if (A->getOption().matches(options::OPT_mhard_quad_float)) |
177 | 1 | Features.push_back("+hard-quad-float"); |
178 | 1 | else |
179 | 1 | Features.push_back("-hard-quad-float"); |
180 | 2 | } |
181 | 209 | } |