Skip to main content

atomic_maybe_uninit/gen/
utils.rs

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(dead_code, 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/2025Q1/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 RV64ILP32* ABI, but in any case, this
21// should be a safe default for such ABIs).
22//
23// Known architectures that have such ABI are x86_64 (X32), AArch64 (ILP32),
24// mips64 (N32), and riscv64 (RV64ILP32*). (As of 2025-01-23, only the former
25// two are supported by rustc.) However, we list all known 64-bit architectures
26// because similar ABIs may exist or future added for other architectures.
27#[cfg(all(
28    target_pointer_width = "32",
29    any(
30        target_arch = "aarch64",
31        target_arch = "amdgpu",
32        target_arch = "arm64ec",
33        target_arch = "bpf",
34        target_arch = "loongarch64",
35        target_arch = "mips64",
36        target_arch = "mips64r6",
37        target_arch = "nvptx64",
38        target_arch = "powerpc64",
39        target_arch = "riscv64",
40        target_arch = "s390x",
41        target_arch = "sparc64",
42        target_arch = "wasm64",
43        target_arch = "x86_64",
44    ),
45))]
46#[macro_use]
47mod imp {
48    #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
49    macro_rules! ptr_reg {
50        ($ptr:ident) => {{
51            let _: *const _ = $ptr; // ensure $ptr is a pointer (*mut _ or *const _)
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        }};
59    }
60    pub(crate) type RegSize = u64;
61}
62#[cfg(not(all(
63    target_pointer_width = "32",
64    any(
65        target_arch = "aarch64",
66        target_arch = "amdgpu",
67        target_arch = "arm64ec",
68        target_arch = "bpf",
69        target_arch = "loongarch64",
70        target_arch = "mips64",
71        target_arch = "mips64r6",
72        target_arch = "nvptx64",
73        target_arch = "powerpc64",
74        target_arch = "riscv64",
75        target_arch = "s390x",
76        target_arch = "sparc64",
77        target_arch = "wasm64",
78        target_arch = "x86_64",
79    ),
80)))]
81#[macro_use]
82mod imp {
83    #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
84    macro_rules! ptr_reg {
85        ($ptr:ident) => {{
86            let _: *const _ = $ptr; // ensure $ptr is a pointer (*mut _ or *const _)
87            $ptr // cast is unnecessary here.
88        }};
89    }
90    #[cfg(target_pointer_width = "16")]
91    pub(crate) type RegSize = u16;
92    #[cfg(target_pointer_width = "32")]
93    pub(crate) type RegSize = u32;
94    #[cfg(target_pointer_width = "64")]
95    pub(crate) type RegSize = u64;
96    #[cfg(target_pointer_width = "128")]
97    pub(crate) type RegSize = u128;
98}
99pub(crate) use self::imp::RegSize;