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