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