12add0d91Sopenharmony_ci//! This module contains type aliases for C's fixed-width integer types .
22add0d91Sopenharmony_ci//!
32add0d91Sopenharmony_ci//! These aliases are deprecated: use the Rust types instead.
42add0d91Sopenharmony_ci
52add0d91Sopenharmony_ci#[deprecated(since = "0.2.55", note = "Use i8 instead.")]
62add0d91Sopenharmony_cipub type int8_t = i8;
72add0d91Sopenharmony_ci#[deprecated(since = "0.2.55", note = "Use i16 instead.")]
82add0d91Sopenharmony_cipub type int16_t = i16;
92add0d91Sopenharmony_ci#[deprecated(since = "0.2.55", note = "Use i32 instead.")]
102add0d91Sopenharmony_cipub type int32_t = i32;
112add0d91Sopenharmony_ci#[deprecated(since = "0.2.55", note = "Use i64 instead.")]
122add0d91Sopenharmony_cipub type int64_t = i64;
132add0d91Sopenharmony_ci#[deprecated(since = "0.2.55", note = "Use u8 instead.")]
142add0d91Sopenharmony_cipub type uint8_t = u8;
152add0d91Sopenharmony_ci#[deprecated(since = "0.2.55", note = "Use u16 instead.")]
162add0d91Sopenharmony_cipub type uint16_t = u16;
172add0d91Sopenharmony_ci#[deprecated(since = "0.2.55", note = "Use u32 instead.")]
182add0d91Sopenharmony_cipub type uint32_t = u32;
192add0d91Sopenharmony_ci#[deprecated(since = "0.2.55", note = "Use u64 instead.")]
202add0d91Sopenharmony_cipub type uint64_t = u64;
212add0d91Sopenharmony_ci
222add0d91Sopenharmony_cicfg_if! {
232add0d91Sopenharmony_ci    if #[cfg(all(libc_int128, target_arch = "aarch64", not(target_os = "windows")))] {
242add0d91Sopenharmony_ci        // This introduces partial support for FFI with __int128 and
252add0d91Sopenharmony_ci        // equivalent types on platforms where Rust's definition is validated
262add0d91Sopenharmony_ci        // to match the standard C ABI of that platform.
272add0d91Sopenharmony_ci        //
282add0d91Sopenharmony_ci        // Rust does not guarantee u128/i128 are sound for FFI, and its
292add0d91Sopenharmony_ci        // definitions are in fact known to be incompatible. [0]
302add0d91Sopenharmony_ci        //
312add0d91Sopenharmony_ci        // However these problems aren't fundamental, and are just platform
322add0d91Sopenharmony_ci        // inconsistencies. Specifically at the time of this writing:
332add0d91Sopenharmony_ci        //
342add0d91Sopenharmony_ci        // * For x64 SysV ABIs (everything but Windows), the types are underaligned.
352add0d91Sopenharmony_ci        // * For all Windows ABIs, Microsoft doesn't actually officially define __int128,
362add0d91Sopenharmony_ci        //   and as a result different implementations don't actually agree on its ABI.
372add0d91Sopenharmony_ci        //
382add0d91Sopenharmony_ci        // But on the other major aarch64 platforms (android, linux, ios, macos) we have
392add0d91Sopenharmony_ci        // validated that rustc has the right ABI for these types. This is important because
402add0d91Sopenharmony_ci        // aarch64 uses these types in some fundamental OS types like user_fpsimd_struct,
412add0d91Sopenharmony_ci        // which represents saved simd registers.
422add0d91Sopenharmony_ci        //
432add0d91Sopenharmony_ci        // Any API which uses these types will need to `#[ignore(improper_ctypes)]`
442add0d91Sopenharmony_ci        // until the upstream rust issue is resolved, but this at least lets us make
452add0d91Sopenharmony_ci        // progress on platforms where this type is important.
462add0d91Sopenharmony_ci        //
472add0d91Sopenharmony_ci        // The list of supported architectures and OSes is intentionally very restricted,
482add0d91Sopenharmony_ci        // as careful work needs to be done to verify that a particular platform
492add0d91Sopenharmony_ci        // has a conformant ABI.
502add0d91Sopenharmony_ci        //
512add0d91Sopenharmony_ci        // [0]: https://github.com/rust-lang/rust/issues/54341
522add0d91Sopenharmony_ci
532add0d91Sopenharmony_ci        /// C `__int128` (a GCC extension that's part of many ABIs)
542add0d91Sopenharmony_ci        pub type __int128 = i128;
552add0d91Sopenharmony_ci        /// C `unsigned __int128` (a GCC extension that's part of many ABIs)
562add0d91Sopenharmony_ci        pub type __uint128 = u128;
572add0d91Sopenharmony_ci        /// C __int128_t (alternate name for [__int128][])
582add0d91Sopenharmony_ci        pub type __int128_t = i128;
592add0d91Sopenharmony_ci        /// C __uint128_t (alternate name for [__uint128][])
602add0d91Sopenharmony_ci        pub type __uint128_t = u128;
612add0d91Sopenharmony_ci
622add0d91Sopenharmony_ci        cfg_if! {
632add0d91Sopenharmony_ci            if #[cfg(libc_underscore_const_names)] {
642add0d91Sopenharmony_ci                macro_rules! static_assert_eq {
652add0d91Sopenharmony_ci                    ($a:expr, $b:expr) => {
662add0d91Sopenharmony_ci                        const _: [(); $a] = [(); $b];
672add0d91Sopenharmony_ci                    };
682add0d91Sopenharmony_ci                }
692add0d91Sopenharmony_ci
702add0d91Sopenharmony_ci                // NOTE: if you add more platforms to here, you may need to cfg
712add0d91Sopenharmony_ci                // these consts. They should always match the platform's values
722add0d91Sopenharmony_ci                // for `sizeof(__int128)` and `_Alignof(__int128)`.
732add0d91Sopenharmony_ci                const _SIZE_128: usize = 16;
742add0d91Sopenharmony_ci                const _ALIGN_128: usize = 16;
752add0d91Sopenharmony_ci
762add0d91Sopenharmony_ci                // Since Rust doesn't officially guarantee that these types
772add0d91Sopenharmony_ci                // have compatible ABIs, we const assert that these values have the
782add0d91Sopenharmony_ci                // known size/align of the target platform's libc. If rustc ever
792add0d91Sopenharmony_ci                // tries to regress things, it will cause a compilation error.
802add0d91Sopenharmony_ci                //
812add0d91Sopenharmony_ci                // This isn't a bullet-proof solution because e.g. it doesn't
822add0d91Sopenharmony_ci                // catch the fact that llvm and gcc disagree on how x64 __int128
832add0d91Sopenharmony_ci                // is actually *passed* on the stack (clang underaligns it for
842add0d91Sopenharmony_ci                // the same reason that rustc *never* properly aligns it).
852add0d91Sopenharmony_ci                static_assert_eq!(core::mem::size_of::<__int128>(), _SIZE_128);
862add0d91Sopenharmony_ci                static_assert_eq!(core::mem::align_of::<__int128>(), _ALIGN_128);
872add0d91Sopenharmony_ci
882add0d91Sopenharmony_ci                static_assert_eq!(core::mem::size_of::<__uint128>(), _SIZE_128);
892add0d91Sopenharmony_ci                static_assert_eq!(core::mem::align_of::<__uint128>(), _ALIGN_128);
902add0d91Sopenharmony_ci
912add0d91Sopenharmony_ci                static_assert_eq!(core::mem::size_of::<__int128_t>(), _SIZE_128);
922add0d91Sopenharmony_ci                static_assert_eq!(core::mem::align_of::<__int128_t>(), _ALIGN_128);
932add0d91Sopenharmony_ci
942add0d91Sopenharmony_ci                static_assert_eq!(core::mem::size_of::<__uint128_t>(), _SIZE_128);
952add0d91Sopenharmony_ci                static_assert_eq!(core::mem::align_of::<__uint128_t>(), _ALIGN_128);
962add0d91Sopenharmony_ci            }
972add0d91Sopenharmony_ci        }
982add0d91Sopenharmony_ci    }
992add0d91Sopenharmony_ci}
100