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