1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #include "X86.h" |
10 | #include "ToolChains/CommonArgs.h" |
11 | #include "clang/Driver/Driver.h" |
12 | #include "clang/Driver/DriverDiagnostic.h" |
13 | #include "clang/Driver/Options.h" |
14 | #include "llvm/ADT/StringSwitch.h" |
15 | #include "llvm/Option/ArgList.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 *x86::getX86TargetCPU(const ArgList &Args, |
23 | const llvm::Triple &Triple) { |
24 | if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) { |
25 | if (StringRef(A->getValue()) != "native") |
26 | return A->getValue(); |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | std::string CPU = llvm::sys::getHostCPUName(); |
34 | if (!CPU.empty() && CPU != "generic") |
35 | return Args.MakeArgString(CPU); |
36 | } |
37 | |
38 | if (const Arg *A = Args.getLastArgNoClaim(options::OPT__SLASH_arch)) { |
39 | |
40 | StringRef Arch = A->getValue(); |
41 | const char *CPU = nullptr; |
42 | if (Triple.getArch() == llvm::Triple::x86) { |
43 | CPU = llvm::StringSwitch<const char *>(Arch) |
44 | .Case("IA32", "i386") |
45 | .Case("SSE", "pentium3") |
46 | .Case("SSE2", "pentium4") |
47 | .Default(nullptr); |
48 | } |
49 | if (CPU == nullptr) { |
50 | CPU = llvm::StringSwitch<const char *>(Arch) |
51 | .Case("AVX", "sandybridge") |
52 | .Case("AVX2", "haswell") |
53 | .Case("AVX512F", "knl") |
54 | .Case("AVX512", "skylake-avx512") |
55 | .Default(nullptr); |
56 | } |
57 | if (CPU) { |
58 | A->claim(); |
59 | return CPU; |
60 | } |
61 | } |
62 | |
63 | |
64 | |
65 | if (Triple.getArch() != llvm::Triple::x86_64 && |
66 | Triple.getArch() != llvm::Triple::x86) |
67 | return nullptr; |
68 | |
69 | bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64; |
70 | |
71 | |
72 | if (Triple.isOSDarwin()) { |
73 | if (Triple.getArchName() == "x86_64h") |
74 | return "core-avx2"; |
75 | |
76 | |
77 | if (Triple.isMacOSX() && !Triple.isOSVersionLT(10, 12)) |
78 | return "penryn"; |
79 | |
80 | return Is64Bit ? "core2" : "yonah"; |
81 | } |
82 | |
83 | |
84 | if (Triple.isPS4CPU()) |
85 | return "btver2"; |
86 | |
87 | |
88 | if (Triple.isAndroid()) |
89 | return Is64Bit ? "x86-64" : "i686"; |
90 | |
91 | |
92 | if (Is64Bit) |
93 | return "x86-64"; |
94 | |
95 | switch (Triple.getOS()) { |
96 | case llvm::Triple::FreeBSD: |
97 | case llvm::Triple::NetBSD: |
98 | case llvm::Triple::OpenBSD: |
99 | return "i486"; |
100 | case llvm::Triple::Haiku: |
101 | return "i586"; |
102 | default: |
103 | |
104 | return "pentium4"; |
105 | } |
106 | } |
107 | |
108 | void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, |
109 | const ArgList &Args, |
110 | std::vector<StringRef> &Features) { |
111 | |
112 | if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) { |
113 | if (StringRef(A->getValue()) == "native") { |
114 | llvm::StringMap<bool> HostFeatures; |
115 | if (llvm::sys::getHostCPUFeatures(HostFeatures)) |
116 | for (auto &F : HostFeatures) |
117 | Features.push_back( |
118 | Args.MakeArgString((F.second ? "+" : "-") + F.first())); |
119 | } |
120 | } |
121 | |
122 | if (Triple.getArchName() == "x86_64h") { |
123 | |
124 | |
125 | Features.push_back("-rdrnd"); |
126 | Features.push_back("-aes"); |
127 | Features.push_back("-pclmul"); |
128 | Features.push_back("-rtm"); |
129 | Features.push_back("-fsgsbase"); |
130 | } |
131 | |
132 | const llvm::Triple::ArchType ArchType = Triple.getArch(); |
133 | |
134 | if (Triple.isAndroid()) { |
135 | if (ArchType == llvm::Triple::x86_64) { |
136 | Features.push_back("+sse4.2"); |
137 | Features.push_back("+popcnt"); |
138 | } else |
139 | Features.push_back("+ssse3"); |
140 | } |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | if (Args.hasArgNoClaim(options::OPT_mretpoline, options::OPT_mno_retpoline, |
149 | options::OPT_mspeculative_load_hardening, |
150 | options::OPT_mno_speculative_load_hardening)) { |
151 | if (Args.hasFlag(options::OPT_mretpoline, options::OPT_mno_retpoline, |
152 | false)) { |
153 | Features.push_back("+retpoline-indirect-calls"); |
154 | Features.push_back("+retpoline-indirect-branches"); |
155 | } else if (Args.hasFlag(options::OPT_mspeculative_load_hardening, |
156 | options::OPT_mno_speculative_load_hardening, |
157 | false)) { |
158 | |
159 | |
160 | Features.push_back("+retpoline-indirect-calls"); |
161 | } |
162 | } else if (Args.hasFlag(options::OPT_mretpoline_external_thunk, |
163 | options::OPT_mno_retpoline_external_thunk, false)) { |
164 | |
165 | |
166 | Features.push_back("+retpoline-indirect-calls"); |
167 | Features.push_back("+retpoline-indirect-branches"); |
168 | } |
169 | |
170 | |
171 | |
172 | handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group); |
173 | } |
174 | |