mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-19 02:57:33 +00:00

Replace `build.rs` Rust generation with macros, using the unstable `${concat(...)}`. Fixes: https://github.com/rust-lang/compiler-builtins/issues/947
99 lines
3.4 KiB
Rust
99 lines
3.4 KiB
Rust
#![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.
|
|
macro int_ty {
|
|
(1) => { i8 },
|
|
(2) => { i16 },
|
|
(4) => { i32 },
|
|
(8) => { i64 },
|
|
(16) => { i128 }
|
|
}
|
|
|
|
mod cas {
|
|
pub(super) macro test($_ordering:ident, $bytes:tt, $name:ident) {
|
|
#[test]
|
|
fn $name() {
|
|
builtins_test::fuzz_2(10000, |expected: super::int_ty!($bytes), new| {
|
|
let mut target = expected.wrapping_add(10);
|
|
assert_eq!(
|
|
unsafe {
|
|
compiler_builtins::aarch64_linux::$name::$name(expected, new, &mut target)
|
|
},
|
|
expected.wrapping_add(10),
|
|
"return value should always be the previous value",
|
|
);
|
|
assert_eq!(
|
|
target,
|
|
expected.wrapping_add(10),
|
|
"shouldn't have changed target"
|
|
);
|
|
|
|
target = expected;
|
|
assert_eq!(
|
|
unsafe {
|
|
compiler_builtins::aarch64_linux::$name::$name(expected, new, &mut target)
|
|
},
|
|
expected
|
|
);
|
|
assert_eq!(target, new, "should have updated target");
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
macro test_cas16($_ordering:ident, $name:ident) {
|
|
cas::test!($_ordering, 16, $name);
|
|
}
|
|
|
|
mod swap {
|
|
pub(super) macro test($_ordering:ident, $bytes:tt, $name:ident) {
|
|
#[test]
|
|
fn $name() {
|
|
builtins_test::fuzz_2(10000, |left: super::int_ty!($bytes), mut right| {
|
|
let orig_right = right;
|
|
assert_eq!(
|
|
unsafe { compiler_builtins::aarch64_linux::$name::$name(left, &mut right) },
|
|
orig_right
|
|
);
|
|
assert_eq!(left, right);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
macro_rules! test_op {
|
|
($mod:ident, $( $op:tt )* ) => {
|
|
mod $mod {
|
|
pub(super) macro test {
|
|
($_ordering:ident, $bytes:tt, $name:ident) => {
|
|
#[test]
|
|
fn $name() {
|
|
builtins_test::fuzz_2(10000, |old, val| {
|
|
let mut target = old;
|
|
let op: fn(super::int_ty!($bytes), super::int_ty!($bytes)) -> _ = $($op)*;
|
|
let expected = op(old, val);
|
|
assert_eq!(old, unsafe { compiler_builtins::aarch64_linux::$name::$name(val, &mut target) }, "{} should return original value", stringify!($name));
|
|
assert_eq!(expected, target, "{} should store to target", stringify!($name));
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
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);
|
|
compiler_builtins::foreach_ldadd!(add::test);
|
|
compiler_builtins::foreach_ldclr!(clr::test);
|
|
compiler_builtins::foreach_ldeor!(xor::test);
|
|
compiler_builtins::foreach_ldset!(or::test);
|