]>
Commit | Line | Data |
---|---|---|
0531ce1d | 1 | use std::env; |
041b39d2 | 2 | |
0531ce1d XL |
3 | fn main() { |
4 | println!("cargo:rerun-if-changed=build.rs"); | |
041b39d2 | 5 | |
0531ce1d | 6 | let target = env::var("TARGET").unwrap(); |
0731742a XL |
7 | let cwd = env::current_dir().unwrap(); |
8 | ||
9 | println!("cargo:compiler-rt={}", cwd.join("compiler-rt").display()); | |
041b39d2 | 10 | |
60c5eb7d XL |
11 | // Activate libm's unstable features to make full use of Nightly. |
12 | println!("cargo:rustc-cfg=feature=\"unstable\""); | |
13 | ||
0531ce1d XL |
14 | // Emscripten's runtime includes all the builtins |
15 | if target.contains("emscripten") { | |
16 | return; | |
041b39d2 XL |
17 | } |
18 | ||
94b46f34 XL |
19 | // OpenBSD provides compiler_rt by default, use it instead of rebuilding it from source |
20 | if target.contains("openbsd") { | |
21 | println!("cargo:rustc-link-search=native=/usr/lib"); | |
8faf50e0 | 22 | println!("cargo:rustc-link-lib=compiler_rt"); |
94b46f34 XL |
23 | return; |
24 | } | |
25 | ||
0731742a | 26 | // Forcibly enable memory intrinsics on wasm32 & SGX as we don't have a libc to |
0531ce1d | 27 | // provide them. |
48663c56 XL |
28 | if (target.contains("wasm32") && !target.contains("wasi")) |
29 | || (target.contains("sgx") && target.contains("fortanix")) | |
f9f354fc XL |
30 | || target.contains("-none") |
31 | || target.contains("nvptx") | |
48663c56 | 32 | { |
0531ce1d | 33 | println!("cargo:rustc-cfg=feature=\"mem\""); |
041b39d2 XL |
34 | } |
35 | ||
0531ce1d XL |
36 | // NOTE we are going to assume that llvm-target, what determines our codegen option, matches the |
37 | // target triple. This is usually correct for our built-in targets but can break in presence of | |
38 | // custom targets, which can have arbitrary names. | |
39 | let llvm_target = target.split('-').collect::<Vec<_>>(); | |
abe05a73 | 40 | |
0531ce1d XL |
41 | // Build missing intrinsics from compiler-rt C source code. If we're |
42 | // mangling names though we assume that we're also in test mode so we don't | |
43 | // build anything and we rely on the upstream implementation of compiler-rt | |
44 | // functions | |
45 | if !cfg!(feature = "mangled-names") && cfg!(feature = "c") { | |
48663c56 XL |
46 | // Don't use a C compiler for these targets: |
47 | // | |
48 | // * wasm32 - clang 8 for wasm is somewhat hard to come by and it's | |
49 | // unlikely that the C is really that much better than our own Rust. | |
50 | // * nvptx - everything is bitcode, not compatible with mixed C/Rust | |
51 | // * riscv - the rust-lang/rust distribution container doesn't have a C | |
52 | // compiler nor is cc-rs ready for compilation to riscv (at this | |
53 | // time). This can probably be removed in the future | |
54 | if !target.contains("wasm32") && !target.contains("nvptx") && !target.starts_with("riscv") { | |
0531ce1d | 55 | #[cfg(feature = "c")] |
ba9703b0 | 56 | c::compile(&llvm_target, &target); |
abe05a73 XL |
57 | } |
58 | } | |
59 | ||
0531ce1d XL |
60 | // To compile intrinsics.rs for thumb targets, where there is no libc |
61 | if llvm_target[0].starts_with("thumb") { | |
62 | println!("cargo:rustc-cfg=thumb") | |
041b39d2 XL |
63 | } |
64 | ||
532ac7d7 XL |
65 | // compiler-rt `cfg`s away some intrinsics for thumbv6m and thumbv8m.base because |
66 | // these targets do not have full Thumb-2 support but only original Thumb-1. | |
67 | // We have to cfg our code accordingly. | |
68 | if llvm_target[0] == "thumbv6m" || llvm_target[0] == "thumbv8m.base" { | |
69 | println!("cargo:rustc-cfg=thumb_1") | |
041b39d2 XL |
70 | } |
71 | ||
0531ce1d XL |
72 | // Only emit the ARM Linux atomic emulation on pre-ARMv6 architectures. |
73 | if llvm_target[0] == "armv4t" || llvm_target[0] == "armv5te" { | |
74 | println!("cargo:rustc-cfg=kernel_user_helpers") | |
041b39d2 XL |
75 | } |
76 | } | |
77 | ||
78 | #[cfg(feature = "c")] | |
79 | mod c { | |
ea8adc8c | 80 | extern crate cc; |
041b39d2 XL |
81 | |
82 | use std::collections::BTreeMap; | |
83 | use std::env; | |
dc9dc135 | 84 | use std::path::PathBuf; |
041b39d2 XL |
85 | |
86 | struct Sources { | |
87 | // SYMBOL -> PATH TO SOURCE | |
88 | map: BTreeMap<&'static str, &'static str>, | |
89 | } | |
90 | ||
91 | impl Sources { | |
92 | fn new() -> Sources { | |
48663c56 XL |
93 | Sources { |
94 | map: BTreeMap::new(), | |
95 | } | |
041b39d2 XL |
96 | } |
97 | ||
48663c56 | 98 | fn extend(&mut self, sources: &[(&'static str, &'static str)]) { |
041b39d2 XL |
99 | // NOTE Some intrinsics have both a generic implementation (e.g. |
100 | // `floatdidf.c`) and an arch optimized implementation | |
101 | // (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized | |
102 | // implementation and discard the generic implementation. If we don't | |
103 | // and keep both implementations, the linker will yell at us about | |
104 | // duplicate symbols! | |
48663c56 | 105 | for (symbol, src) in sources { |
041b39d2 XL |
106 | if src.contains("/") { |
107 | // Arch-optimized implementation (preferred) | |
108 | self.map.insert(symbol, src); | |
109 | } else { | |
110 | // Generic implementation | |
111 | if !self.map.contains_key(symbol) { | |
112 | self.map.insert(symbol, src); | |
113 | } | |
114 | } | |
115 | } | |
116 | } | |
117 | ||
118 | fn remove(&mut self, symbols: &[&str]) { | |
119 | for symbol in symbols { | |
120 | self.map.remove(*symbol).unwrap(); | |
121 | } | |
122 | } | |
123 | } | |
8bb4bdeb | 124 | |
041b39d2 | 125 | /// Compile intrinsics from the compiler-rt C source code |
ba9703b0 | 126 | pub fn compile(llvm_target: &[&str], target: &String) { |
041b39d2 XL |
127 | let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); |
128 | let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap(); | |
129 | let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); | |
130 | let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap(); | |
ba9703b0 | 131 | let mut consider_float_intrinsics = true; |
ea8adc8c XL |
132 | let cfg = &mut cc::Build::new(); |
133 | ||
ba9703b0 XL |
134 | // AArch64 GCCs exit with an error condition when they encounter any kind of floating point |
135 | // code if the `nofp` and/or `nosimd` compiler flags have been set. | |
136 | // | |
137 | // Therefore, evaluate if those flags are present and set a boolean that causes any | |
138 | // compiler-rt intrinsics that contain floating point source to be excluded for this target. | |
139 | if target_arch == "aarch64" { | |
140 | let cflags_key = String::from("CFLAGS_") + &(target.to_owned().replace("-", "_")); | |
141 | if let Ok(cflags_value) = env::var(cflags_key) { | |
142 | if cflags_value.contains("+nofp") || cflags_value.contains("+nosimd") { | |
143 | consider_float_intrinsics = false; | |
144 | } | |
145 | } | |
146 | } | |
147 | ||
ea8adc8c | 148 | cfg.warnings(false); |
041b39d2 XL |
149 | |
150 | if target_env == "msvc" { | |
151 | // Don't pull in extra libraries on MSVC | |
152 | cfg.flag("/Zl"); | |
153 | ||
154 | // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP | |
155 | cfg.define("__func__", Some("__FUNCTION__")); | |
156 | } else { | |
157 | // Turn off various features of gcc and such, mostly copying | |
158 | // compiler-rt's build system already | |
159 | cfg.flag("-fno-builtin"); | |
160 | cfg.flag("-fvisibility=hidden"); | |
041b39d2 | 161 | cfg.flag("-ffreestanding"); |
ff7c6d11 XL |
162 | // Avoid the following warning appearing once **per file**: |
163 | // clang: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7' [-Wignored-optimization-argument] | |
164 | // | |
165 | // Note that compiler-rt's build system also checks | |
166 | // | |
167 | // `check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)` | |
168 | // | |
169 | // in https://github.com/rust-lang/compiler-rt/blob/c8fbcb3/cmake/config-ix.cmake#L19. | |
170 | cfg.flag_if_supported("-fomit-frame-pointer"); | |
041b39d2 XL |
171 | cfg.define("VISIBILITY_HIDDEN", None); |
172 | } | |
173 | ||
041b39d2 | 174 | let mut sources = Sources::new(); |
48663c56 XL |
175 | sources.extend(&[ |
176 | ("__absvdi2", "absvdi2.c"), | |
177 | ("__absvsi2", "absvsi2.c"), | |
178 | ("__addvdi3", "addvdi3.c"), | |
179 | ("__addvsi3", "addvsi3.c"), | |
180 | ("apple_versioning", "apple_versioning.c"), | |
181 | ("__clzdi2", "clzdi2.c"), | |
182 | ("__clzsi2", "clzsi2.c"), | |
183 | ("__cmpdi2", "cmpdi2.c"), | |
184 | ("__ctzdi2", "ctzdi2.c"), | |
185 | ("__ctzsi2", "ctzsi2.c"), | |
48663c56 | 186 | ("__int_util", "int_util.c"), |
48663c56 XL |
187 | ("__mulvdi3", "mulvdi3.c"), |
188 | ("__mulvsi3", "mulvsi3.c"), | |
48663c56 | 189 | ("__negdi2", "negdi2.c"), |
48663c56 XL |
190 | ("__negvdi2", "negvdi2.c"), |
191 | ("__negvsi2", "negvsi2.c"), | |
192 | ("__paritydi2", "paritydi2.c"), | |
193 | ("__paritysi2", "paritysi2.c"), | |
194 | ("__popcountdi2", "popcountdi2.c"), | |
195 | ("__popcountsi2", "popcountsi2.c"), | |
48663c56 XL |
196 | ("__subvdi3", "subvdi3.c"), |
197 | ("__subvsi3", "subvsi3.c"), | |
48663c56 XL |
198 | ("__ucmpdi2", "ucmpdi2.c"), |
199 | ]); | |
041b39d2 | 200 | |
ba9703b0 XL |
201 | if consider_float_intrinsics { |
202 | sources.extend(&[ | |
203 | ("__divdc3", "divdc3.c"), | |
204 | ("__divsc3", "divsc3.c"), | |
205 | ("__divxc3", "divxc3.c"), | |
206 | ("__extendhfsf2", "extendhfsf2.c"), | |
207 | ("__muldc3", "muldc3.c"), | |
208 | ("__mulsc3", "mulsc3.c"), | |
209 | ("__mulxc3", "mulxc3.c"), | |
210 | ("__negdf2", "negdf2.c"), | |
211 | ("__negsf2", "negsf2.c"), | |
212 | ("__powixf2", "powixf2.c"), | |
213 | ("__truncdfhf2", "truncdfhf2.c"), | |
214 | ("__truncdfsf2", "truncdfsf2.c"), | |
215 | ("__truncsfhf2", "truncsfhf2.c"), | |
216 | ]); | |
217 | } | |
218 | ||
041b39d2 XL |
219 | // When compiling in rustbuild (the rust-lang/rust repo) this library |
220 | // also needs to satisfy intrinsics that jemalloc or C in general may | |
221 | // need, so include a few more that aren't typically needed by | |
222 | // LLVM/Rust. | |
ea8adc8c | 223 | if cfg!(feature = "rustbuild") { |
48663c56 | 224 | sources.extend(&[("__ffsdi2", "ffsdi2.c")]); |
ea8adc8c | 225 | } |
041b39d2 | 226 | |
ea8adc8c XL |
227 | // On iOS and 32-bit OSX these are all just empty intrinsics, no need to |
228 | // include them. | |
229 | if target_os != "ios" && (target_vendor != "apple" || target_arch != "x86") { | |
48663c56 XL |
230 | sources.extend(&[ |
231 | ("__absvti2", "absvti2.c"), | |
232 | ("__addvti3", "addvti3.c"), | |
233 | ("__clzti2", "clzti2.c"), | |
234 | ("__cmpti2", "cmpti2.c"), | |
235 | ("__ctzti2", "ctzti2.c"), | |
236 | ("__ffsti2", "ffsti2.c"), | |
237 | ("__mulvti3", "mulvti3.c"), | |
238 | ("__negti2", "negti2.c"), | |
48663c56 XL |
239 | ("__parityti2", "parityti2.c"), |
240 | ("__popcountti2", "popcountti2.c"), | |
241 | ("__subvti3", "subvti3.c"), | |
242 | ("__ucmpti2", "ucmpti2.c"), | |
243 | ]); | |
ba9703b0 XL |
244 | |
245 | if consider_float_intrinsics { | |
246 | sources.extend(&[("__negvti2", "negvti2.c")]); | |
247 | } | |
041b39d2 XL |
248 | } |
249 | ||
250 | if target_vendor == "apple" { | |
48663c56 XL |
251 | sources.extend(&[ |
252 | ("atomic_flag_clear", "atomic_flag_clear.c"), | |
253 | ("atomic_flag_clear_explicit", "atomic_flag_clear_explicit.c"), | |
254 | ("atomic_flag_test_and_set", "atomic_flag_test_and_set.c"), | |
255 | ( | |
256 | "atomic_flag_test_and_set_explicit", | |
041b39d2 | 257 | "atomic_flag_test_and_set_explicit.c", |
48663c56 XL |
258 | ), |
259 | ("atomic_signal_fence", "atomic_signal_fence.c"), | |
260 | ("atomic_thread_fence", "atomic_thread_fence.c"), | |
261 | ]); | |
041b39d2 XL |
262 | } |
263 | ||
264 | if target_env == "msvc" { | |
265 | if target_arch == "x86_64" { | |
48663c56 XL |
266 | sources.extend(&[ |
267 | ("__floatdisf", "x86_64/floatdisf.c"), | |
268 | ("__floatdixf", "x86_64/floatdixf.c"), | |
269 | ]); | |
041b39d2 XL |
270 | } |
271 | } else { | |
272 | // None of these seem to be used on x86_64 windows, and they've all | |
273 | // got the wrong ABI anyway, so we want to avoid them. | |
274 | if target_os != "windows" { | |
275 | if target_arch == "x86_64" { | |
48663c56 XL |
276 | sources.extend(&[ |
277 | ("__floatdisf", "x86_64/floatdisf.c"), | |
278 | ("__floatdixf", "x86_64/floatdixf.c"), | |
279 | ("__floatundidf", "x86_64/floatundidf.S"), | |
280 | ("__floatundisf", "x86_64/floatundisf.S"), | |
281 | ("__floatundixf", "x86_64/floatundixf.S"), | |
282 | ]); | |
041b39d2 XL |
283 | } |
284 | } | |
285 | ||
286 | if target_arch == "x86" { | |
48663c56 XL |
287 | sources.extend(&[ |
288 | ("__ashldi3", "i386/ashldi3.S"), | |
289 | ("__ashrdi3", "i386/ashrdi3.S"), | |
290 | ("__divdi3", "i386/divdi3.S"), | |
291 | ("__floatdidf", "i386/floatdidf.S"), | |
292 | ("__floatdisf", "i386/floatdisf.S"), | |
293 | ("__floatdixf", "i386/floatdixf.S"), | |
294 | ("__floatundidf", "i386/floatundidf.S"), | |
295 | ("__floatundisf", "i386/floatundisf.S"), | |
296 | ("__floatundixf", "i386/floatundixf.S"), | |
297 | ("__lshrdi3", "i386/lshrdi3.S"), | |
298 | ("__moddi3", "i386/moddi3.S"), | |
299 | ("__muldi3", "i386/muldi3.S"), | |
300 | ("__udivdi3", "i386/udivdi3.S"), | |
301 | ("__umoddi3", "i386/umoddi3.S"), | |
302 | ]); | |
041b39d2 XL |
303 | } |
304 | } | |
305 | ||
a1dfa0c6 | 306 | if target_arch == "arm" && target_os != "ios" && target_env != "msvc" { |
48663c56 XL |
307 | sources.extend(&[ |
308 | ("__aeabi_div0", "arm/aeabi_div0.c"), | |
309 | ("__aeabi_drsub", "arm/aeabi_drsub.c"), | |
310 | ("__aeabi_frsub", "arm/aeabi_frsub.c"), | |
311 | ("__bswapdi2", "arm/bswapdi2.S"), | |
312 | ("__bswapsi2", "arm/bswapsi2.S"), | |
313 | ("__clzdi2", "arm/clzdi2.S"), | |
314 | ("__clzsi2", "arm/clzsi2.S"), | |
315 | ("__divmodsi4", "arm/divmodsi4.S"), | |
316 | ("__divsi3", "arm/divsi3.S"), | |
317 | ("__modsi3", "arm/modsi3.S"), | |
318 | ("__switch16", "arm/switch16.S"), | |
319 | ("__switch32", "arm/switch32.S"), | |
320 | ("__switch8", "arm/switch8.S"), | |
321 | ("__switchu8", "arm/switchu8.S"), | |
322 | ("__sync_synchronize", "arm/sync_synchronize.S"), | |
323 | ("__udivmodsi4", "arm/udivmodsi4.S"), | |
324 | ("__udivsi3", "arm/udivsi3.S"), | |
325 | ("__umodsi3", "arm/umodsi3.S"), | |
326 | ]); | |
2c00a5a8 | 327 | |
532ac7d7 | 328 | if target_os == "freebsd" { |
48663c56 | 329 | sources.extend(&[("__clear_cache", "clear_cache.c")]); |
532ac7d7 XL |
330 | } |
331 | ||
2c00a5a8 XL |
332 | // First of all aeabi_cdcmp and aeabi_cfcmp are never called by LLVM. |
333 | // Second are little-endian only, so build fail on big-endian targets. | |
334 | // Temporally workaround: exclude these files for big-endian targets. | |
48663c56 XL |
335 | if !llvm_target[0].starts_with("thumbeb") && !llvm_target[0].starts_with("armeb") { |
336 | sources.extend(&[ | |
337 | ("__aeabi_cdcmp", "arm/aeabi_cdcmp.S"), | |
338 | ("__aeabi_cdcmpeq_check_nan", "arm/aeabi_cdcmpeq_check_nan.c"), | |
339 | ("__aeabi_cfcmp", "arm/aeabi_cfcmp.S"), | |
340 | ("__aeabi_cfcmpeq_check_nan", "arm/aeabi_cfcmpeq_check_nan.c"), | |
341 | ]); | |
2c00a5a8 | 342 | } |
041b39d2 XL |
343 | } |
344 | ||
345 | if llvm_target[0] == "armv7" { | |
48663c56 XL |
346 | sources.extend(&[ |
347 | ("__sync_fetch_and_add_4", "arm/sync_fetch_and_add_4.S"), | |
348 | ("__sync_fetch_and_add_8", "arm/sync_fetch_and_add_8.S"), | |
349 | ("__sync_fetch_and_and_4", "arm/sync_fetch_and_and_4.S"), | |
350 | ("__sync_fetch_and_and_8", "arm/sync_fetch_and_and_8.S"), | |
351 | ("__sync_fetch_and_max_4", "arm/sync_fetch_and_max_4.S"), | |
352 | ("__sync_fetch_and_max_8", "arm/sync_fetch_and_max_8.S"), | |
353 | ("__sync_fetch_and_min_4", "arm/sync_fetch_and_min_4.S"), | |
354 | ("__sync_fetch_and_min_8", "arm/sync_fetch_and_min_8.S"), | |
355 | ("__sync_fetch_and_nand_4", "arm/sync_fetch_and_nand_4.S"), | |
356 | ("__sync_fetch_and_nand_8", "arm/sync_fetch_and_nand_8.S"), | |
357 | ("__sync_fetch_and_or_4", "arm/sync_fetch_and_or_4.S"), | |
358 | ("__sync_fetch_and_or_8", "arm/sync_fetch_and_or_8.S"), | |
359 | ("__sync_fetch_and_sub_4", "arm/sync_fetch_and_sub_4.S"), | |
360 | ("__sync_fetch_and_sub_8", "arm/sync_fetch_and_sub_8.S"), | |
361 | ("__sync_fetch_and_umax_4", "arm/sync_fetch_and_umax_4.S"), | |
362 | ("__sync_fetch_and_umax_8", "arm/sync_fetch_and_umax_8.S"), | |
363 | ("__sync_fetch_and_umin_4", "arm/sync_fetch_and_umin_4.S"), | |
364 | ("__sync_fetch_and_umin_8", "arm/sync_fetch_and_umin_8.S"), | |
365 | ("__sync_fetch_and_xor_4", "arm/sync_fetch_and_xor_4.S"), | |
366 | ("__sync_fetch_and_xor_8", "arm/sync_fetch_and_xor_8.S"), | |
367 | ]); | |
041b39d2 XL |
368 | } |
369 | ||
370 | if llvm_target.last().unwrap().ends_with("eabihf") { | |
48663c56 XL |
371 | if !llvm_target[0].starts_with("thumbv7em") |
372 | && !llvm_target[0].starts_with("thumbv8m.main") | |
373 | { | |
532ac7d7 XL |
374 | // The FPU option chosen for these architectures in cc-rs, ie: |
375 | // -mfpu=fpv4-sp-d16 for thumbv7em | |
376 | // -mfpu=fpv5-sp-d16 for thumbv8m.main | |
377 | // do not support double precision floating points conversions so the files | |
378 | // that include such instructions are not included for these targets. | |
48663c56 XL |
379 | sources.extend(&[ |
380 | ("__fixdfsivfp", "arm/fixdfsivfp.S"), | |
381 | ("__fixunsdfsivfp", "arm/fixunsdfsivfp.S"), | |
382 | ("__floatsidfvfp", "arm/floatsidfvfp.S"), | |
383 | ("__floatunssidfvfp", "arm/floatunssidfvfp.S"), | |
384 | ]); | |
041b39d2 XL |
385 | } |
386 | ||
48663c56 XL |
387 | sources.extend(&[ |
388 | ("__fixsfsivfp", "arm/fixsfsivfp.S"), | |
389 | ("__fixunssfsivfp", "arm/fixunssfsivfp.S"), | |
390 | ("__floatsisfvfp", "arm/floatsisfvfp.S"), | |
391 | ("__floatunssisfvfp", "arm/floatunssisfvfp.S"), | |
392 | ("__floatunssisfvfp", "arm/floatunssisfvfp.S"), | |
393 | ("__restore_vfp_d8_d15_regs", "arm/restore_vfp_d8_d15_regs.S"), | |
394 | ("__save_vfp_d8_d15_regs", "arm/save_vfp_d8_d15_regs.S"), | |
395 | ("__negdf2vfp", "arm/negdf2vfp.S"), | |
396 | ("__negsf2vfp", "arm/negsf2vfp.S"), | |
397 | ]); | |
041b39d2 XL |
398 | } |
399 | ||
ba9703b0 | 400 | if target_arch == "aarch64" && consider_float_intrinsics { |
48663c56 XL |
401 | sources.extend(&[ |
402 | ("__comparetf2", "comparetf2.c"), | |
403 | ("__extenddftf2", "extenddftf2.c"), | |
404 | ("__extendsftf2", "extendsftf2.c"), | |
405 | ("__fixtfdi", "fixtfdi.c"), | |
406 | ("__fixtfsi", "fixtfsi.c"), | |
407 | ("__fixtfti", "fixtfti.c"), | |
408 | ("__fixunstfdi", "fixunstfdi.c"), | |
409 | ("__fixunstfsi", "fixunstfsi.c"), | |
410 | ("__fixunstfti", "fixunstfti.c"), | |
411 | ("__floatditf", "floatditf.c"), | |
412 | ("__floatsitf", "floatsitf.c"), | |
413 | ("__floatunditf", "floatunditf.c"), | |
414 | ("__floatunsitf", "floatunsitf.c"), | |
415 | ("__trunctfdf2", "trunctfdf2.c"), | |
416 | ("__trunctfsf2", "trunctfsf2.c"), | |
417 | ]); | |
8faf50e0 XL |
418 | |
419 | if target_os != "windows" { | |
48663c56 | 420 | sources.extend(&[("__multc3", "multc3.c")]); |
8faf50e0 | 421 | } |
1b1a35ee XL |
422 | |
423 | if target_env == "musl" { | |
424 | sources.extend(&[ | |
425 | ("__addtf3", "addtf3.c"), | |
426 | ("__multf3", "multf3.c"), | |
427 | ("__subtf3", "subtf3.c"), | |
428 | ("__divtf3", "divtf3.c"), | |
429 | ("__powitf2", "powitf2.c"), | |
430 | ("__fe_getround", "fp_mode.c"), | |
431 | ("__fe_raise_inexact", "fp_mode.c"), | |
432 | ]); | |
433 | } | |
434 | } | |
435 | ||
436 | if target_arch == "mips" { | |
437 | sources.extend(&[("__bswapsi2", "bswapsi2.c")]); | |
438 | } | |
439 | ||
440 | if target_arch == "mips64" { | |
441 | sources.extend(&[ | |
442 | ("__extenddftf2", "extenddftf2.c"), | |
443 | ("__netf2", "comparetf2.c"), | |
444 | ("__addtf3", "addtf3.c"), | |
445 | ("__multf3", "multf3.c"), | |
446 | ("__subtf3", "subtf3.c"), | |
447 | ("__fixtfsi", "fixtfsi.c"), | |
448 | ("__floatsitf", "floatsitf.c"), | |
449 | ("__fixunstfsi", "fixunstfsi.c"), | |
450 | ("__floatunsitf", "floatunsitf.c"), | |
451 | ("__fe_getround", "fp_mode.c"), | |
452 | ]); | |
041b39d2 XL |
453 | } |
454 | ||
455 | // Remove the assembly implementations that won't compile for the target | |
532ac7d7 | 456 | if llvm_target[0] == "thumbv6m" || llvm_target[0] == "thumbv8m.base" { |
48663c56 XL |
457 | let mut to_remove = Vec::new(); |
458 | for (k, v) in sources.map.iter() { | |
459 | if v.ends_with(".S") { | |
460 | to_remove.push(*k); | |
461 | } | |
462 | } | |
463 | sources.remove(&to_remove); | |
041b39d2 XL |
464 | |
465 | // But use some generic implementations where possible | |
48663c56 | 466 | sources.extend(&[("__clzdi2", "clzdi2.c"), ("__clzsi2", "clzsi2.c")]) |
041b39d2 XL |
467 | } |
468 | ||
469 | if llvm_target[0] == "thumbv7m" || llvm_target[0] == "thumbv7em" { | |
48663c56 | 470 | sources.remove(&["__aeabi_cdcmp", "__aeabi_cfcmp"]); |
041b39d2 XL |
471 | } |
472 | ||
dc9dc135 XL |
473 | // When compiling the C code we require the user to tell us where the |
474 | // source code is, and this is largely done so when we're compiling as | |
475 | // part of rust-lang/rust we can use the same llvm-project repository as | |
476 | // rust-lang/rust. | |
477 | let root = match env::var_os("RUST_COMPILER_RT_ROOT") { | |
478 | Some(s) => PathBuf::from(s), | |
479 | None => panic!("RUST_COMPILER_RT_ROOT is not set"), | |
041b39d2 | 480 | }; |
dc9dc135 XL |
481 | if !root.exists() { |
482 | panic!("RUST_COMPILER_RT_ROOT={} does not exist", root.display()); | |
483 | } | |
041b39d2 | 484 | |
60c5eb7d XL |
485 | // Support deterministic builds by remapping the __FILE__ prefix if the |
486 | // compiler supports it. This fixes the nondeterminism caused by the | |
487 | // use of that macro in lib/builtins/int_util.h in compiler-rt. | |
488 | cfg.flag_if_supported(&format!("-ffile-prefix-map={}=.", root.display())); | |
489 | ||
dc9dc135 | 490 | let src_dir = root.join("lib/builtins"); |
48663c56 | 491 | for (sym, src) in sources.map.iter() { |
041b39d2 XL |
492 | let src = src_dir.join(src); |
493 | cfg.file(&src); | |
494 | println!("cargo:rerun-if-changed={}", src.display()); | |
48663c56 | 495 | println!("cargo:rustc-cfg={}=\"optimized-c\"", sym); |
8bb4bdeb | 496 | } |
041b39d2 XL |
497 | |
498 | cfg.compile("libcompiler-rt.a"); | |
499 | } | |
9e0c209e | 500 | } |