Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 19 additions & 16 deletions builtins-test/tests/lse.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![feature(decl_macro)] // so we can use pub(super)
#![feature(macro_metavar_expr_concat)]
#![cfg(all(target_arch = "aarch64", target_os = "linux"))]
#![cfg(target_arch = "aarch64")]

/// Translate a byte size to a Rust type.
macro int_ty {
Expand All @@ -17,14 +17,15 @@ mod cas {
fn $name() {
builtins_test::fuzz_2(10000, |expected: super::int_ty!($bytes), new| {
let mut target = expected.wrapping_add(10);
let ret: super::int_ty!($bytes) = unsafe {
compiler_builtins::aarch64_outline_atomics::$name::$name(
expected,
new,
&mut target,
)
};
assert_eq!(
unsafe {
compiler_builtins::aarch64_outline_atomics::$name::$name(
expected,
new,
&mut target,
)
},
ret,
expected.wrapping_add(10),
"return value should always be the previous value",
);
Expand All @@ -35,15 +36,17 @@ mod cas {
);

target = expected;
let ret: super::int_ty!($bytes) = unsafe {
compiler_builtins::aarch64_outline_atomics::$name::$name(
expected,
new,
&mut target,
)
};
assert_eq!(
unsafe {
compiler_builtins::aarch64_outline_atomics::$name::$name(
expected,
new,
&mut target,
)
},
expected
ret,
expected,
"the new return value should always be the previous value (i.e. the first parameter passed to the function)",
);
assert_eq!(target, new, "should have updated target");
});
Expand Down
69 changes: 62 additions & 7 deletions compiler-builtins/src/aarch64_outline_atomics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,18 +135,73 @@ macro_rules! stxp {
};
}

// The AArch64 assembly syntax for relocation specifiers
// when accessing symbols changes depending on the target executable format.
// In ELF (used in Linux), we have a prefix notation surrounded by colons (:specifier:sym),
// while in Mach-O object files (used in MacOS), a postfix notation is used (sym@specifier).

/// AArch64 ELF position-independent addressing:
///
/// adrp xN, symbol
/// add xN, xN, :lo12:symbol
///
/// The :lo12: modifier selects the low 12 bits of the symbol address
/// and emits an ELF relocation such as R_AARCH64_ADD_ABS_LO12_NC.
///
/// Defined by the AArch64 ELF psABI.
/// See: <https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst#static-miscellaneous-relocations>.
#[cfg(not(target_vendor = "apple"))]
macro_rules! sym {
($sym:literal) => {
$sym
};
}

#[cfg(not(target_vendor = "apple"))]
macro_rules! sym_off {
($sym:literal) => {
concat!(":lo12:", $sym)
};
}

/// Mach-O ARM64 relocation types:
/// ARM64_RELOC_PAGE21
/// ARM64_RELOC_PAGEOFF12
///
/// These relocations implement the @PAGE / @PAGEOFF split used by
/// adrp + add sequences on Apple platforms.
///
/// adrp xN, symbol@PAGE -> ARM64_RELOC_PAGE21
/// add xN, xN, symbol@PAGEOFF -> ARM64_RELOC_PAGEOFF12
///
/// Relocation types defined by Apple in XNU: <mach-o/arm64/reloc.h>.
/// See: <https://github.com/apple-oss-distributions/xnu/blob/f6217f891ac0bb64f3d375211650a4c1ff8ca1ea/EXTERNAL_HEADERS/mach-o/arm64/reloc.h>.
#[cfg(target_vendor = "apple")]
macro_rules! sym {
($sym:literal) => {
concat!($sym, "@PAGE")
};
}

#[cfg(target_vendor = "apple")]
macro_rules! sym_off {
($sym:literal) => {
concat!($sym, "@PAGEOFF")
};
}
Comment on lines +180 to +204
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This matches my understanding, but @madsmtm mind taking a second look here?


// If supported, perform the requested LSE op and return, or fallthrough.
macro_rules! try_lse_op {
($op: literal, $ordering:ident, $bytes:tt, $($reg:literal,)* [ $mem:ident ] ) => {
concat!(
".arch_extension lse; ",
"adrp x16, {have_lse}; ",
"ldrb w16, [x16, :lo12:{have_lse}]; ",
"cbz w16, 8f; ",
".arch_extension lse\n",
concat!("adrp x16, ", sym!("{have_lse}"), "\n"),
concat!("ldrb w16, [x16, ", sym_off!("{have_lse}"), "]\n"),
"cbz w16, 8f\n",
// LSE_OP s(reg),* [$mem]
concat!(lse!($op, $ordering, $bytes), $( " ", reg!($bytes, $reg), ", " ,)* "[", stringify!($mem), "]; ",),
"ret; ",
"8:"
concat!(lse!($op, $ordering, $bytes), $( " ", reg!($bytes, $reg), ", " ,)* "[", stringify!($mem), "]\n",),
"ret
8:"
)
};
}
Expand Down
7 changes: 6 additions & 1 deletion compiler-builtins/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ pub mod arm;
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
pub mod aarch64;

#[cfg(all(target_arch = "aarch64", target_feature = "outline-atomics"))]
// Note that we enable the module on "mangled-names" because that is the default feature
// in the builtins-test tests. So this is a way of enabling the module during testing.
#[cfg(all(
target_arch = "aarch64",
any(target_feature = "outline-atomics", feature = "mangled-names")
))]
pub mod aarch64_outline_atomics;

#[cfg(all(
Expand Down
Loading