1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
// SPDX-License-Identifier: Apache-2.0 OR MIT
// This file is @generated by target_spec.sh.
// It is not intended for manual editing.
#![allow(unused_macros)]
// On AArch64, the base register of memory-related instructions must be 64-bit.
// Passing a 32-bit value to `in(reg)` on AArch64 results in the upper bits
// having an undefined value, but to work correctly with ILP32 ABI, the upper
// bits must be zero, which is handled here by casting to u64. Another way to
// handle this is to pass it as a pointer and clear the upper bits inside asm,
// but it is easier to overlook than cast, which can catch overlooks by
// asm_sub_register lint.
// See also https://github.com/ARM-software/abi-aa/blob/2024Q3/aapcs64/aapcs64.rst#pointers
//
// Except for x86_64, which can use 32-bit registers in the destination operand
// (on x86_64, we use the ptr_modifier macro to handle this), we need to do the
// same for ILP32 ABI on other 64-bit architectures. (At least, as far as I can
// see from the assembly generated by LLVM, this is also required for MIPS64 N32
// ABI. I don't know about the RISC-V s64ilp32 ABI for which a patch was
// recently submitted to the kernel, but in any case, this should be a safe
// default for such ABIs).
//
// Known architectures that have such ABI are x86_64 (X32), AArch64 (ILP32),
// mips64 (N32), and riscv64 (s64ilp32, not merged yet though). (As of
// 2023-06-05, only the former two are supported by rustc.) However, we list all
// known 64-bit architectures because similar ABIs may exist or future added for
// other architectures.
#[cfg(all(
target_pointer_width = "32",
any(
target_arch = "aarch64",
target_arch = "arm64ec",
target_arch = "bpf",
target_arch = "loongarch64",
target_arch = "mips64",
target_arch = "mips64r6",
target_arch = "nvptx64",
target_arch = "powerpc64",
target_arch = "riscv64",
target_arch = "s390x",
target_arch = "sparc64",
target_arch = "wasm64",
target_arch = "x86_64",
),
))]
macro_rules! ptr_reg {
($ptr:ident) => {{
let _: *const _ = $ptr; // ensure $ptr is a pointer (*mut _ or *const _)
#[cfg(not(portable_atomic_no_asm_maybe_uninit))]
#[allow(clippy::ptr_as_ptr)]
{
// If we cast to u64 here, the provenance will be lost,
// so we convert to MaybeUninit<u64> via zero extend helper.
crate::utils::zero_extend64_ptr($ptr as *mut ())
}
#[cfg(portable_atomic_no_asm_maybe_uninit)]
{
// Use cast on old rustc because it does not support MaybeUninit
// registers. This is still permissive-provenance compatible and
// is sound.
$ptr as u64
}
}};
}
#[cfg(not(all(
target_pointer_width = "32",
any(
target_arch = "aarch64",
target_arch = "arm64ec",
target_arch = "bpf",
target_arch = "loongarch64",
target_arch = "mips64",
target_arch = "mips64r6",
target_arch = "nvptx64",
target_arch = "powerpc64",
target_arch = "riscv64",
target_arch = "s390x",
target_arch = "sparc64",
target_arch = "wasm64",
target_arch = "x86_64",
),
)))]
macro_rules! ptr_reg {
($ptr:ident) => {{
let _: *const _ = $ptr; // ensure $ptr is a pointer (*mut _ or *const _)
$ptr // cast is unnecessary here.
}};
}
// Some 64-bit architectures have ABI with 32-bit pointer width (e.g., x86_64 X32 ABI,
// AArch64 ILP32 ABI, MIPS64 N32 ABI). On those targets, AtomicU64 is available
// and fast, so use it to implement normal sequence lock.
//
// See ptr_reg macro for the reason why all known 64-bit architectures are listed.
#[cfg(any(
not(any(target_pointer_width = "16", target_pointer_width = "32")), // i.e., 64-bit or greater
target_arch = "aarch64",
target_arch = "arm64ec",
target_arch = "bpf",
target_arch = "loongarch64",
target_arch = "mips64",
target_arch = "mips64r6",
target_arch = "nvptx64",
target_arch = "powerpc64",
target_arch = "riscv64",
target_arch = "s390x",
target_arch = "sparc64",
target_arch = "wasm64",
target_arch = "x86_64",
))]
#[macro_use]
mod fast_atomic_64_macros {
macro_rules! cfg_has_fast_atomic_64 {
($($tt:tt)*) => {
$($tt)*
};
}
macro_rules! cfg_no_fast_atomic_64 {
($($tt:tt)*) => {};
}
}
#[cfg(not(any(
not(any(target_pointer_width = "16", target_pointer_width = "32")), // i.e., 64-bit or greater
target_arch = "aarch64",
target_arch = "arm64ec",
target_arch = "bpf",
target_arch = "loongarch64",
target_arch = "mips64",
target_arch = "mips64r6",
target_arch = "nvptx64",
target_arch = "powerpc64",
target_arch = "riscv64",
target_arch = "s390x",
target_arch = "sparc64",
target_arch = "wasm64",
target_arch = "x86_64",
)))]
#[macro_use]
mod fast_atomic_64_macros {
macro_rules! cfg_has_fast_atomic_64 {
($($tt:tt)*) => {};
}
macro_rules! cfg_no_fast_atomic_64 {
($($tt:tt)*) => {
$($tt)*
};
}
}