Eliminate build.rs-generated Aarch64 atomic macros (#951)
Replace `build.rs` Rust generation with macros, using the unstable
`${concat(...)}`.
Fixes: https://github.com/rust-lang/compiler-builtins/issues/947
This commit is contained in:
parent
b5fafd9816
commit
013e06c5ff
4 changed files with 75 additions and 65 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#![feature(decl_macro)] // so we can use pub(super)
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
#![cfg(all(target_arch = "aarch64", target_os = "linux", not(feature = "no-asm")))]
|
||||
|
||||
/// Translate a byte size to a Rust type.
|
||||
|
|
@ -87,7 +88,7 @@ test_op!(add, |left, right| left.wrapping_add(right));
|
|||
test_op!(clr, |left, right| left & !right);
|
||||
test_op!(xor, std::ops::BitXor::bitxor);
|
||||
test_op!(or, std::ops::BitOr::bitor);
|
||||
|
||||
use compiler_builtins::{foreach_bytes, foreach_ordering};
|
||||
compiler_builtins::foreach_cas!(cas::test);
|
||||
compiler_builtins::foreach_cas16!(test_cas16);
|
||||
compiler_builtins::foreach_swp!(swap::test);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
mod configure;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use configure::{Target, configure_aliases, configure_f16_f128};
|
||||
|
||||
|
|
@ -85,10 +82,6 @@ fn main() {
|
|||
{
|
||||
println!("cargo:rustc-cfg=kernel_user_helpers")
|
||||
}
|
||||
|
||||
if llvm_target[0].starts_with("aarch64") {
|
||||
generate_aarch64_outlined_atomics();
|
||||
}
|
||||
}
|
||||
|
||||
/// Run configuration for `libm` since it is included directly.
|
||||
|
|
@ -131,61 +124,6 @@ fn configure_libm(target: &Target) {
|
|||
println!("cargo:rustc-cfg=feature=\"unstable-intrinsics\"");
|
||||
}
|
||||
|
||||
fn aarch64_symbol(ordering: Ordering) -> &'static str {
|
||||
match ordering {
|
||||
Ordering::Relaxed => "relax",
|
||||
Ordering::Acquire => "acq",
|
||||
Ordering::Release => "rel",
|
||||
Ordering::AcqRel => "acq_rel",
|
||||
_ => panic!("unknown symbol for {ordering:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
/// The `concat_idents` macro is extremely annoying and doesn't allow us to define new items.
|
||||
/// Define them from the build script instead.
|
||||
/// Note that the majority of the code is still defined in `aarch64.rs` through inline macros.
|
||||
fn generate_aarch64_outlined_atomics() {
|
||||
use std::fmt::Write;
|
||||
// #[macro_export] so that we can use this in tests
|
||||
let gen_macro =
|
||||
|name| format!("#[macro_export] macro_rules! foreach_{name} {{ ($macro:path) => {{\n");
|
||||
|
||||
// Generate different macros for add/clr/eor/set so that we can test them separately.
|
||||
let sym_names = ["cas", "ldadd", "ldclr", "ldeor", "ldset", "swp"];
|
||||
let mut macros = BTreeMap::new();
|
||||
for sym in sym_names {
|
||||
macros.insert(sym, gen_macro(sym));
|
||||
}
|
||||
|
||||
// Only CAS supports 16 bytes, and it has a different implementation that uses a different macro.
|
||||
let mut cas16 = gen_macro("cas16");
|
||||
|
||||
for ordering in [
|
||||
Ordering::Relaxed,
|
||||
Ordering::Acquire,
|
||||
Ordering::Release,
|
||||
Ordering::AcqRel,
|
||||
] {
|
||||
let sym_ordering = aarch64_symbol(ordering);
|
||||
for size in [1, 2, 4, 8] {
|
||||
for (sym, macro_) in &mut macros {
|
||||
let name = format!("__aarch64_{sym}{size}_{sym_ordering}");
|
||||
writeln!(macro_, "$macro!( {ordering:?}, {size}, {name} );").unwrap();
|
||||
}
|
||||
}
|
||||
let name = format!("__aarch64_cas16_{sym_ordering}");
|
||||
writeln!(cas16, "$macro!( {ordering:?}, {name} );").unwrap();
|
||||
}
|
||||
|
||||
let mut buf = String::new();
|
||||
for macro_def in macros.values().chain(std::iter::once(&cas16)) {
|
||||
buf += macro_def;
|
||||
buf += "}; }\n";
|
||||
}
|
||||
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
|
||||
std::fs::write(out_dir.join("outlined_atomics.rs"), buf).unwrap();
|
||||
}
|
||||
|
||||
/// Emit directives for features we expect to support that aren't in `Cargo.toml`.
|
||||
///
|
||||
/// These are mostly cfg elements emitted by this `build.rs`.
|
||||
|
|
|
|||
|
|
@ -262,8 +262,78 @@ macro_rules! or {
|
|||
};
|
||||
}
|
||||
|
||||
// See `generate_aarch64_outlined_atomics` in build.rs.
|
||||
include!(concat!(env!("OUT_DIR"), "/outlined_atomics.rs"));
|
||||
#[macro_export]
|
||||
macro_rules! foreach_ordering {
|
||||
($macro:path, $bytes:tt, $name:ident) => {
|
||||
$macro!( Relaxed, $bytes, ${concat($name, _relax)} );
|
||||
$macro!( Acquire, $bytes, ${concat($name, _acq)} );
|
||||
$macro!( Release, $bytes, ${concat($name, _rel)} );
|
||||
$macro!( AcqRel, $bytes, ${concat($name, _acq_rel)} );
|
||||
};
|
||||
($macro:path, $name:ident) => {
|
||||
$macro!( Relaxed, ${concat($name, _relax)} );
|
||||
$macro!( Acquire, ${concat($name, _acq)} );
|
||||
$macro!( Release, ${concat($name, _rel)} );
|
||||
$macro!( AcqRel, ${concat($name, _acq_rel)} );
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! foreach_bytes {
|
||||
($macro:path, $name:ident) => {
|
||||
foreach_ordering!( $macro, 1, ${concat(__aarch64_, $name, "1")} );
|
||||
foreach_ordering!( $macro, 2, ${concat(__aarch64_, $name, "2")} );
|
||||
foreach_ordering!( $macro, 4, ${concat(__aarch64_, $name, "4")} );
|
||||
foreach_ordering!( $macro, 8, ${concat(__aarch64_, $name, "8")} );
|
||||
};
|
||||
}
|
||||
|
||||
/// Generate different macros for cas/swp/add/clr/eor/set so that we can test them separately.
|
||||
#[macro_export]
|
||||
macro_rules! foreach_cas {
|
||||
($macro:path) => {
|
||||
foreach_bytes!($macro, cas);
|
||||
};
|
||||
}
|
||||
|
||||
/// Only CAS supports 16 bytes, and it has a different implementation that uses a different macro.
|
||||
#[macro_export]
|
||||
macro_rules! foreach_cas16 {
|
||||
($macro:path) => {
|
||||
foreach_ordering!($macro, __aarch64_cas16);
|
||||
};
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! foreach_swp {
|
||||
($macro:path) => {
|
||||
foreach_bytes!($macro, swp);
|
||||
};
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! foreach_ldadd {
|
||||
($macro:path) => {
|
||||
foreach_bytes!($macro, ldadd);
|
||||
};
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! foreach_ldclr {
|
||||
($macro:path) => {
|
||||
foreach_bytes!($macro, ldclr);
|
||||
};
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! foreach_ldeor {
|
||||
($macro:path) => {
|
||||
foreach_bytes!($macro, ldeor);
|
||||
};
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! foreach_ldset {
|
||||
($macro:path) => {
|
||||
foreach_bytes!($macro, ldset);
|
||||
};
|
||||
}
|
||||
|
||||
foreach_cas!(compare_and_swap);
|
||||
foreach_cas16!(compare_and_swap_i128);
|
||||
foreach_swp!(swap);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#![feature(linkage)]
|
||||
#![feature(naked_functions)]
|
||||
#![feature(repr_simd)]
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
#![cfg_attr(f16_enabled, feature(f16))]
|
||||
#![cfg_attr(f128_enabled, feature(f128))]
|
||||
#![no_builtins]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue