From 69bd06107b2141789ae63edc81f776f2ae4955a0 Mon Sep 17 00:00:00 2001
From: Mads Marquart <mads@marquart.dk>
Date: Sun, 27 Oct 2024 14:26:16 +0100
Subject: [PATCH 1/2] Add available! macro

This includes internal methods for looking up the OS version at runtime,
and for looking up the deployment target at compile time.
---
 Cargo.lock                                    |   7 +
 crates/objc2/CHANGELOG.md                     |   2 +
 crates/objc2/src/__macro_helpers/mod.rs       |   3 +
 .../objc2/src/__macro_helpers/os_version.rs   | 405 ++++++++++++++++++
 .../src/__macro_helpers/os_version/apple.rs   | 288 +++++++++++++
 crates/objc2/src/ffi/mod.rs                   |  15 -
 crates/objc2/src/lib.rs                       |   2 +-
 crates/objc2/src/macros/available.rs          | 193 +++++++++
 crates/objc2/src/macros/mod.rs                |   1 +
 crates/objc2/src/runtime/nsobject.rs          |  32 +-
 .../crates/test_available/Cargo.toml          |  25 ++
 .../test_available/expected/apple-aarch64.s   | 190 ++++++++
 .../test_available/expected/apple-armv7s.s    | 206 +++++++++
 .../test_available/expected/apple-old-x86.s   | 218 ++++++++++
 .../test_available/expected/apple-x86.s       | 218 ++++++++++
 .../test_available/expected/apple-x86_64.s    | 186 ++++++++
 .../test_available/expected/gnustep-x86.s     |  63 +++
 .../test_available/expected/gnustep-x86_64.s  |  63 +++
 .../crates/test_available/lib.rs              |  69 +++
 crates/test-ui/ui/available_invalid.rs        |  13 +
 crates/test-ui/ui/available_invalid.stderr    |  50 +++
 crates/test-ui/ui/available_same_os.rs        |   6 +
 crates/test-ui/ui/available_same_os.stderr    |   8 +
 crates/test-ui/ui/available_unknown_os.rs     |   6 +
 crates/test-ui/ui/available_unknown_os.stderr |   7 +
 25 files changed, 2233 insertions(+), 43 deletions(-)
 create mode 100644 crates/objc2/src/__macro_helpers/os_version.rs
 create mode 100644 crates/objc2/src/__macro_helpers/os_version/apple.rs
 create mode 100644 crates/objc2/src/macros/available.rs
 create mode 100644 crates/test-assembly/crates/test_available/Cargo.toml
 create mode 100644 crates/test-assembly/crates/test_available/expected/apple-aarch64.s
 create mode 100644 crates/test-assembly/crates/test_available/expected/apple-armv7s.s
 create mode 100644 crates/test-assembly/crates/test_available/expected/apple-old-x86.s
 create mode 100644 crates/test-assembly/crates/test_available/expected/apple-x86.s
 create mode 100644 crates/test-assembly/crates/test_available/expected/apple-x86_64.s
 create mode 100644 crates/test-assembly/crates/test_available/expected/gnustep-x86.s
 create mode 100644 crates/test-assembly/crates/test_available/expected/gnustep-x86_64.s
 create mode 100644 crates/test-assembly/crates/test_available/lib.rs
 create mode 100644 crates/test-ui/ui/available_invalid.rs
 create mode 100644 crates/test-ui/ui/available_invalid.stderr
 create mode 100644 crates/test-ui/ui/available_same_os.rs
 create mode 100644 crates/test-ui/ui/available_same_os.stderr
 create mode 100644 crates/test-ui/ui/available_unknown_os.rs
 create mode 100644 crates/test-ui/ui/available_unknown_os.stderr

diff --git a/Cargo.lock b/Cargo.lock
index 4070e5d23..5126399ee 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1387,6 +1387,13 @@ dependencies = [
  "objc2",
 ]
 
+[[package]]
+name = "test_available"
+version = "0.1.0"
+dependencies = [
+ "objc2",
+]
+
 [[package]]
 name = "test_block"
 version = "0.1.0"
diff --git a/crates/objc2/CHANGELOG.md b/crates/objc2/CHANGELOG.md
index 0cda0214e..61724a1ef 100644
--- a/crates/objc2/CHANGELOG.md
+++ b/crates/objc2/CHANGELOG.md
@@ -24,6 +24,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 * Allow using `Into` to convert to retained objects.
 * Make `Retained::into_super` an inherent method instead of an associated
   method. This means that you can now use it as `.into_super()`.
+* Added the `available!()` macro for determining whether code is running on
+  a given operating system.
 
 ### Changed
 * **BREAKING**: Changed how you specify a class to only be available on the
diff --git a/crates/objc2/src/__macro_helpers/mod.rs b/crates/objc2/src/__macro_helpers/mod.rs
index 51562c19c..8156def08 100644
--- a/crates/objc2/src/__macro_helpers/mod.rs
+++ b/crates/objc2/src/__macro_helpers/mod.rs
@@ -1,6 +1,7 @@
 pub use core::borrow::Borrow;
 pub use core::cell::UnsafeCell;
 pub use core::convert::AsRef;
+pub use core::default::Default;
 pub use core::marker::{PhantomData, Sized};
 pub use core::mem::{size_of, ManuallyDrop, MaybeUninit};
 pub use core::ops::Deref;
@@ -21,6 +22,7 @@ mod method_family;
 mod module_info;
 mod msg_send;
 mod msg_send_retained;
+mod os_version;
 mod writeback;
 
 pub use self::cache::{CachedClass, CachedSel};
@@ -38,6 +40,7 @@ pub use self::method_family::{
 pub use self::module_info::ModuleInfo;
 pub use self::msg_send::MsgSend;
 pub use self::msg_send_retained::{MaybeUnwrap, MsgSendId, MsgSendSuperId};
+pub use self::os_version::{is_available, AvailableVersion, OSVersion};
 
 /// Disallow using this passed in value in const and statics for forwards
 /// compatibility (this function is not a `const` function).
diff --git a/crates/objc2/src/__macro_helpers/os_version.rs b/crates/objc2/src/__macro_helpers/os_version.rs
new file mode 100644
index 000000000..0b1655f06
--- /dev/null
+++ b/crates/objc2/src/__macro_helpers/os_version.rs
@@ -0,0 +1,405 @@
+//! Utilities for checking the runtime availability of APIs.
+//!
+//! TODO: Upstream some of this to `std`?
+use core::cmp::Ordering;
+use core::fmt;
+
+#[cfg(target_vendor = "apple")]
+mod apple;
+
+/// The size of the fields here are limited by Mach-O's `LC_BUILD_VERSION`.
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct OSVersion {
+    // Shuffle the versions around a little so that OSVersion has the same bit
+    // representation as the `u32` returned from `to_u32`, allowing
+    // comparisons to compile down to just between two `u32`s.
+    #[cfg(target_endian = "little")]
+    pub patch: u8,
+    #[cfg(target_endian = "little")]
+    pub minor: u8,
+    #[cfg(target_endian = "little")]
+    pub major: u16,
+
+    #[cfg(target_endian = "big")]
+    pub major: u16,
+    #[cfg(target_endian = "big")]
+    pub minor: u8,
+    #[cfg(target_endian = "big")]
+    pub patch: u8,
+}
+
+#[track_caller]
+const fn parse_usize(mut bytes: &[u8]) -> (usize, &[u8]) {
+    // Ensure we have at least one digit (that is not just a period).
+    let mut ret: usize = if let Some((&ascii, rest)) = bytes.split_first() {
+        bytes = rest;
+
+        match ascii {
+            b'0'..=b'9' => (ascii - b'0') as usize,
+            _ => panic!("found invalid digit when parsing version"),
+        }
+    } else {
+        panic!("found empty version number part")
+    };
+
+    // Parse the remaining digits.
+    while let Some((&ascii, rest)) = bytes.split_first() {
+        let digit = match ascii {
+            b'0'..=b'9' => ascii - b'0',
+            _ => break,
+        };
+
+        bytes = rest;
+
+        // This handles leading zeroes as well.
+        match ret.checked_mul(10) {
+            Some(val) => match val.checked_add(digit as _) {
+                Some(val) => ret = val,
+                None => panic!("version is too large"),
+            },
+            None => panic!("version is too large"),
+        };
+    }
+
+    (ret, bytes)
+}
+
+impl OSVersion {
+    const MIN: Self = Self {
+        major: 0,
+        minor: 0,
+        patch: 0,
+    };
+
+    const MAX: Self = Self {
+        major: u16::MAX,
+        minor: u8::MAX,
+        patch: u8::MAX,
+    };
+
+    /// Parse the version from a string at `const` time.
+    #[track_caller]
+    pub const fn from_str(version: &str) -> Self {
+        Self::from_bytes(version.as_bytes())
+    }
+
+    #[track_caller]
+    pub(crate) const fn from_bytes(bytes: &[u8]) -> Self {
+        let (major, bytes) = parse_usize(bytes);
+        if major > u16::MAX as usize {
+            panic!("major version is too large");
+        }
+        let major = major as u16;
+
+        let bytes = if let Some((period, bytes)) = bytes.split_first() {
+            if *period != b'.' {
+                panic!("expected period between major and minor version")
+            }
+            bytes
+        } else {
+            return Self {
+                major,
+                minor: 0,
+                patch: 0,
+            };
+        };
+
+        let (minor, bytes) = parse_usize(bytes);
+        if minor > u8::MAX as usize {
+            panic!("minor version is too large");
+        }
+        let minor = minor as u8;
+
+        let bytes = if let Some((period, bytes)) = bytes.split_first() {
+            if *period != b'.' {
+                panic!("expected period after minor version")
+            }
+            bytes
+        } else {
+            return Self {
+                major,
+                minor,
+                patch: 0,
+            };
+        };
+
+        let (patch, bytes) = parse_usize(bytes);
+        if patch > u8::MAX as usize {
+            panic!("patch version is too large");
+        }
+        let patch = patch as u8;
+
+        if !bytes.is_empty() {
+            panic!("too many parts to version");
+        }
+
+        Self {
+            major,
+            minor,
+            patch,
+        }
+    }
+
+    /// Pack the version into a `u32`.
+    ///
+    /// This is used for faster comparisons.
+    #[inline]
+    pub const fn to_u32(self) -> u32 {
+        // See comments in `OSVersion`, this should compile down to nothing.
+        let (major, minor, patch) = (self.major as u32, self.minor as u32, self.patch as u32);
+        (major << 16) | (minor << 8) | patch
+    }
+}
+
+impl PartialEq for OSVersion {
+    #[inline]
+    fn eq(&self, other: &Self) -> bool {
+        self.to_u32() == other.to_u32()
+    }
+}
+
+impl PartialOrd for OSVersion {
+    #[inline]
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        self.to_u32().partial_cmp(&other.to_u32())
+    }
+}
+
+impl fmt::Debug for OSVersion {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // Same ordering on little and big endian.
+        f.debug_struct("OSVersion")
+            .field("major", &self.major)
+            .field("minor", &self.minor)
+            .field("patch", &self.patch)
+            .finish()
+    }
+}
+
+/// The combined availability.
+///
+/// This generally works closely together with the `available!` macro to make
+/// syntax checking inside that easier.
+#[derive(Clone, Copy, Debug)]
+pub struct AvailableVersion {
+    pub macos: OSVersion,
+    pub ios: OSVersion,
+    pub tvos: OSVersion,
+    pub watchos: OSVersion,
+    pub visionos: OSVersion,
+    #[doc(hidden)]
+    pub __others: OSVersion,
+}
+
+impl AvailableVersion {
+    pub const MIN: Self = Self {
+        macos: OSVersion::MIN,
+        ios: OSVersion::MIN,
+        tvos: OSVersion::MIN,
+        watchos: OSVersion::MIN,
+        visionos: OSVersion::MIN,
+        __others: OSVersion::MIN,
+    };
+
+    pub const MAX: Self = Self {
+        macos: OSVersion::MAX,
+        ios: OSVersion::MAX,
+        tvos: OSVersion::MAX,
+        watchos: OSVersion::MAX,
+        visionos: OSVersion::MAX,
+        __others: OSVersion::MAX,
+    };
+}
+
+#[inline]
+pub fn is_available(version: AvailableVersion) -> bool {
+    let version = if cfg!(target_os = "macos") {
+        version.macos
+    } else if cfg!(target_os = "ios") {
+        version.ios
+    } else if cfg!(target_os = "tvos") {
+        version.tvos
+    } else if cfg!(target_os = "watchos") {
+        version.watchos
+    } else if cfg!(target_os = "visionos") {
+        version.visionos
+    } else {
+        version.__others
+    };
+
+    // In the special case that `version` was set to `OSVersion::MAX`, we
+    // assume that there can never be an OS version that large, and hence we
+    // want to avoid checking at all.
+    //
+    // This is useful for platforms where the version hasn't been specified.
+    if version == OSVersion::MAX {
+        return false;
+    }
+
+    #[cfg(target_vendor = "apple")]
+    {
+        // If the deployment target is high enough, the API is always available.
+        //
+        // This check should be optimized away at compile time.
+        if version <= apple::DEPLOYMENT_TARGET {
+            return true;
+        }
+
+        // Otherwise, compare against the version at runtime.
+        version <= apple::current_version()
+    }
+
+    #[cfg(not(target_vendor = "apple"))]
+    return true;
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    use crate::{__available_version, available};
+
+    #[test]
+    fn test_parse() {
+        #[track_caller]
+        fn check(expected: (u16, u8, u8), actual: OSVersion) {
+            assert_eq!(
+                OSVersion {
+                    major: expected.0,
+                    minor: expected.1,
+                    patch: expected.2,
+                },
+                actual,
+            )
+        }
+
+        check((1, 0, 0), __available_version!(1));
+        check((1, 2, 0), __available_version!(1.2));
+        check((1, 2, 3), __available_version!(1.2.3));
+        check((9999, 99, 99), __available_version!(9999.99.99));
+
+        // Ensure that the macro handles leading zeroes correctly
+        check((10, 0, 0), __available_version!(010));
+        check((10, 20, 0), __available_version!(010.020));
+        check((10, 20, 30), __available_version!(010.020.030));
+        check(
+            (10000, 100, 100),
+            __available_version!(000010000.00100.00100),
+        );
+    }
+
+    #[test]
+    fn test_compare() {
+        #[track_caller]
+        fn check_lt(expected: (u16, u8, u8), actual: (u16, u8, u8)) {
+            assert!(
+                OSVersion {
+                    major: expected.0,
+                    minor: expected.1,
+                    patch: expected.2,
+                } < OSVersion {
+                    major: actual.0,
+                    minor: actual.1,
+                    patch: actual.2,
+                },
+            )
+        }
+
+        check_lt((4, 99, 99), (5, 5, 5));
+        check_lt((5, 4, 99), (5, 5, 5));
+        check_lt((5, 5, 4), (5, 5, 5));
+
+        check_lt((10, 7, 0), (10, 10, 0));
+    }
+
+    #[test]
+    #[should_panic = "too many parts to version"]
+    fn test_too_many_version_parts() {
+        let _ = __available_version!(1.2.3 .4);
+    }
+
+    #[test]
+    #[should_panic = "found invalid digit when parsing version"]
+    fn test_macro_with_identifiers() {
+        let _ = __available_version!(A.B);
+    }
+
+    #[test]
+    #[should_panic = "found empty version number part"]
+    fn test_empty_version() {
+        let _ = __available_version!();
+    }
+
+    #[test]
+    #[should_panic = "found invalid digit when parsing version"]
+    fn test_only_period() {
+        let _ = __available_version!(.);
+    }
+
+    #[test]
+    #[should_panic = "found invalid digit when parsing version"]
+    fn test_has_leading_period() {
+        let _ = __available_version!(.1);
+    }
+
+    #[test]
+    #[should_panic = "found empty version number part"]
+    fn test_has_trailing_period() {
+        let _ = __available_version!(1.);
+    }
+
+    #[test]
+    #[should_panic = "major version is too large"]
+    fn test_major_too_large() {
+        let _ = __available_version!(100000);
+    }
+
+    #[test]
+    #[should_panic = "minor version is too large"]
+    fn test_minor_too_large() {
+        let _ = __available_version!(1.1000);
+    }
+
+    #[test]
+    #[should_panic = "patch version is too large"]
+    fn test_patch_too_large() {
+        let _ = __available_version!(1.1.1000);
+    }
+
+    #[test]
+    fn test_general_available() {
+        // Always available
+        assert!(available!(..));
+
+        // Never available
+        assert!(!available!());
+
+        // Low versions, always available
+        assert!(available!(
+            macos = 10.0,
+            ios = 1.0,
+            tvos = 1.0,
+            watchos = 1.0,
+            visionos = 1.0,
+            ..
+        ));
+
+        // High versions, never available
+        assert!(!available!(
+            macos = 99,
+            ios = 99,
+            tvos = 99,
+            watchos = 99,
+            visionos = 99
+        ));
+
+        if !cfg!(target_os = "tvos") {
+            // Available nowhere except tvOS
+            assert!(!available!(tvos = 1.2));
+
+            // Available everywhere, except low tvOS versions
+            assert!(available!(tvos = 1.2, ..));
+        }
+    }
+}
diff --git a/crates/objc2/src/__macro_helpers/os_version/apple.rs b/crates/objc2/src/__macro_helpers/os_version/apple.rs
new file mode 100644
index 000000000..f57ef07ed
--- /dev/null
+++ b/crates/objc2/src/__macro_helpers/os_version/apple.rs
@@ -0,0 +1,288 @@
+use core::ffi::{c_char, c_uint, c_void};
+use core::ptr;
+use std::os::unix::ffi::OsStrExt;
+use std::path::PathBuf;
+use std::sync::OnceLock;
+
+use super::OSVersion;
+use crate::rc::{autoreleasepool, Allocated, Retained};
+use crate::runtime::__nsstring::{nsstring_to_str, UTF8_ENCODING};
+use crate::runtime::{NSObject, NSObjectProtocol};
+use crate::{class, msg_send_id};
+
+/// The deployment target for the current OS.
+pub(crate) const DEPLOYMENT_TARGET: OSVersion = {
+    // Intentionally use `#[cfg]` guards instead of `cfg!` here, to avoid
+    // recompiling when unrelated environment variables change.
+    #[cfg(target_os = "macos")]
+    let var = option_env!("MACOSX_DEPLOYMENT_TARGET");
+    #[cfg(target_os = "ios")] // Also used on Mac Catalyst.
+    let var = option_env!("IPHONEOS_DEPLOYMENT_TARGET");
+    #[cfg(target_os = "tvos")]
+    let var = option_env!("TVOS_DEPLOYMENT_TARGET");
+    #[cfg(target_os = "watchos")]
+    let var = option_env!("WATCHOS_DEPLOYMENT_TARGET");
+    #[cfg(target_os = "visionos")]
+    let var = option_env!("XROS_DEPLOYMENT_TARGET");
+
+    if let Some(var) = var {
+        OSVersion::from_str(var)
+    } else {
+        // Default operating system version.
+        // See <https://github.com/rust-lang/rust/blob/1e5719bdc40bb553089ce83525f07dfe0b2e71e9/compiler/rustc_target/src/spec/base/apple/mod.rs#L207-L215>
+        //
+        // Note that we cannot do as they suggest, and use
+        // `rustc --print=deployment-target`, as this has to work at `const`
+        // time.
+        #[allow(clippy::if_same_then_else)]
+        let os_min = if cfg!(target_os = "macos") {
+            (10, 12, 0)
+        } else if cfg!(target_os = "ios") {
+            (10, 0, 0)
+        } else if cfg!(target_os = "tvos") {
+            (10, 0, 0)
+        } else if cfg!(target_os = "watchos") {
+            (5, 0, 0)
+        } else if cfg!(target_os = "visionos") {
+            (1, 0, 0)
+        } else {
+            panic!("unknown Apple OS")
+        };
+
+        // On certain targets it makes sense to raise the minimum OS version.
+        //
+        // See <https://github.com/rust-lang/rust/blob/1e5719bdc40bb553089ce83525f07dfe0b2e71e9/compiler/rustc_target/src/spec/base/apple/mod.rs#L217-L231>
+        //
+        // Note that we cannot do all the same checks as `rustc` does, because
+        // we have no way of knowing if the architecture is `arm64e` without
+        // reading the target triple itself (and we want to get rid of build
+        // scripts).
+        #[allow(clippy::if_same_then_else)]
+        let min = if cfg!(all(target_os = "macos", target_arch = "aarch64")) {
+            (11, 0, 0)
+        } else if cfg!(all(
+            target_os = "ios",
+            target_arch = "aarch64",
+            target_abi_macabi
+        )) {
+            (14, 0, 0)
+        } else if cfg!(all(
+            target_os = "ios",
+            target_arch = "aarch64",
+            target_simulator
+        )) {
+            (14, 0, 0)
+        } else if cfg!(all(target_os = "tvos", target_arch = "aarch64")) {
+            (14, 0, 0)
+        } else if cfg!(all(target_os = "watchos", target_arch = "aarch64")) {
+            (7, 0, 0)
+        } else {
+            os_min
+        };
+
+        OSVersion {
+            major: min.0,
+            minor: min.1,
+            patch: min.2,
+        }
+    }
+};
+
+/// Look up the current version at runtime.
+///
+/// Note that this doesn't work with "zippered" `dylib`s yet, though
+/// that's probably fine, `rustc` doesn't support those either:
+/// <https://github.com/rust-lang/rust/issues/131216>
+#[inline]
+pub(crate) fn current_version() -> OSVersion {
+    // Cache the lookup for performance.
+    //
+    // TODO: Maybe just use atomics, a `Once` seems like overkill, it doesn't
+    // matter if two threads end up racing to read the version?
+    static CURRENT_VERSION: OnceLock<OSVersion> = OnceLock::new();
+
+    *CURRENT_VERSION.get_or_init(lookup_version)
+}
+
+fn lookup_version() -> OSVersion {
+    // Since macOS 10.15, libSystem has provided the undocumented
+    // `_availability_version_check` via `libxpc` for doing this version
+    // lookup, though it's usage may be a bit dangerous, see:
+    // - https://reviews.llvm.org/D150397
+    // - https://github.com/llvm/llvm-project/issues/64227
+    //
+    // So instead, we use the safer approach of reading from `sysctl`, and
+    // if that fails, we fall back to the property list (this is what
+    // `_availability_version_check` does internally).
+    version_from_sysctl().unwrap_or_else(version_from_plist)
+}
+
+/// Read the version from `kern.osproductversion` or `kern.iossupportversion`.
+fn version_from_sysctl() -> Option<OSVersion> {
+    // This won't work in the simulator, `kern.osproductversion` will return
+    // the host macOS version.
+    if cfg!(target_simulator) {
+        return None;
+    }
+
+    // SAFETY: Same signature as in `libc`
+    extern "C" {
+        fn sysctlbyname(
+            name: *const c_char,
+            oldp: *mut c_void,
+            oldlenp: *mut usize,
+            newp: *mut c_void,
+            newlen: usize,
+        ) -> c_uint;
+    }
+
+    let name = if cfg!(target_abi_macabi) {
+        b"kern.iossupportversion\0".as_ptr().cast()
+    } else {
+        // Introduced in macOS 10.13.4.
+        b"kern.osproductversion\0".as_ptr().cast()
+    };
+
+    let mut buf: [u8; 32] = [0; 32];
+    let mut size = buf.len();
+    let ret = unsafe { sysctlbyname(name, buf.as_mut_ptr().cast(), &mut size, ptr::null_mut(), 0) };
+    if ret != 0 {
+        // `sysctlbyname` is not available.
+        return None;
+    }
+
+    Some(OSVersion::from_bytes(&buf[..(size - 1)]))
+}
+
+/// Look up the current OS version from the `ProductVersion` or
+/// `iOSSupportVersion` in `/System/Library/CoreServices/SystemVersion.plist`.
+/// This file was introduced in macOS 10.3.0.
+///
+/// This is also what is done in `compiler-rt`:
+/// <https://github.com/llvm/llvm-project/blob/llvmorg-19.1.1/compiler-rt/lib/builtins/os_version_check.c>
+///
+/// NOTE: I don't _think_ we need to do a similar thing as what Zig does to
+/// handle the fake 10.16 versions returned when the SDK version of the binary
+/// is less than 11.0:
+/// <https://github.com/ziglang/zig/blob/0.13.0/lib/std/zig/system/darwin/macos.zig>
+///
+/// My reasoning is that we _want_ to follow Apple's behaviour here, and
+/// return 10.16 when compiled with an older SDK; the user should upgrade
+/// their tooling.
+///
+/// NOTE: `rustc` currently doesn't set the right SDK version when linking
+/// with ld64, so this will usually have the wrong behaviour on x86_64. But
+/// that's a `rustc` bug, and is tracked in:
+/// <https://github.com/rust-lang/rust/issues/129432>
+///
+///
+/// # Panics
+///
+/// Panics if reading or parsing the PList fails (or if the system was out of
+/// memory).
+///
+/// We deliberately choose to panic, as having this lookup silently return
+/// an empty OS version would be impossible for a user to debug.
+fn version_from_plist() -> OSVersion {
+    // Use Foundation's mechanisms for reading the PList.
+    autoreleasepool(|pool| {
+        let path: Retained<NSObject> = if cfg!(target_simulator) {
+            let root = std::env::var_os("IPHONE_SIMULATOR_ROOT")
+                    .expect("environment variable `IPHONE_SIMULATOR_ROOT` must be set when executing under simulator");
+            let path = PathBuf::from(root).join("System/Library/CoreServices/SystemVersion.plist");
+            let path = path.as_os_str().as_bytes();
+
+            // SAFETY: Allocating a string is valid.
+            let alloc: Allocated<NSObject> = unsafe { msg_send_id![class!(NSString), alloc] };
+            // SAFETY: The bytes are valid, and the length is correct.
+            unsafe {
+                let bytes_ptr: *const c_void = path.as_ptr().cast();
+                msg_send_id![
+                    alloc,
+                    initWithBytes: bytes_ptr,
+                    length: path.len(),
+                    // OsStr is a superset of UTF-8 on unix platforms
+                    encoding: UTF8_ENCODING,
+                ]
+            }
+        } else {
+            let path: *const c_char = b"/System/Library/CoreServices/SystemVersion.plist\0"
+                .as_ptr()
+                .cast();
+            // SAFETY: The path is NULL terminated.
+            unsafe { msg_send_id![class!(NSString), stringWithUTF8String: path] }
+        };
+
+        // SAFETY: dictionaryWithContentsOfFile: is safe to call.
+        let data: Option<Retained<NSObject>> =
+            unsafe { msg_send_id![class!(NSDictionary), dictionaryWithContentsOfFile: &*path] };
+
+        let data = data.expect(
+            "`/System/Library/CoreServices/SystemVersion.plist` must be readable, and contain a valid PList",
+        );
+
+        // Read `ProductVersion`, except when running on Mac Catalyst, then we
+        // read `iOSSupportVersion` instead.
+        let lookup_key: *const c_char = if cfg!(target_abi_macabi) {
+            b"iOSSupportVersion\0".as_ptr().cast()
+        } else {
+            b"ProductVersion\0".as_ptr().cast()
+        };
+        // SAFETY: The lookup key is NULL terminated.
+        let lookup_key: Retained<NSObject> =
+            unsafe { msg_send_id![class!(NSString), stringWithUTF8String: lookup_key] };
+
+        let version: Retained<NSObject> =
+            unsafe { msg_send_id![&data, objectForKey: &*lookup_key] };
+
+        assert!(
+            version.isKindOfClass(class!(NSString)),
+            "`ProductVersion` key in `/System/Library/CoreServices/SystemVersion.plist` must be a string"
+        );
+
+        // SAFETY: The given object is an NSString, and the returned string
+        // slice is not used outside of the current pool.
+        let version = unsafe { nsstring_to_str(&version, pool) };
+
+        OSVersion::from_str(version)
+    })
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    use alloc::string::String;
+    use std::process::Command;
+
+    #[test]
+    fn sysctl_same_as_in_plist() {
+        if let Some(version) = version_from_sysctl() {
+            assert_eq!(version, version_from_plist());
+        }
+    }
+
+    #[test]
+    fn read_version() {
+        assert!(OSVersion::MIN < current_version(), "version cannot be min");
+        assert!(current_version() < OSVersion::MAX, "version cannot be max");
+    }
+
+    #[test]
+    #[cfg_attr(
+        not(target_os = "macos"),
+        ignore = "`sw_vers` is only available on macOS"
+    )]
+    fn compare_against_sw_vers() {
+        let expected = Command::new("sw_vers")
+            .arg("-productVersion")
+            .output()
+            .unwrap()
+            .stdout;
+        let expected = String::from_utf8(expected).unwrap();
+        let expected = OSVersion::from_str(expected.trim());
+
+        let actual = current_version();
+        assert_eq!(expected, actual);
+    }
+}
diff --git a/crates/objc2/src/ffi/mod.rs b/crates/objc2/src/ffi/mod.rs
index 9295ba045..c04d4da7e 100644
--- a/crates/objc2/src/ffi/mod.rs
+++ b/crates/objc2/src/ffi/mod.rs
@@ -32,21 +32,6 @@
 //! This is used by default, and has the highest support priority (all of
 //! `objc2` will work with this runtime).
 //!
-//! The supported runtime version (higher versions lets the compiler enable
-//! newer optimizations, at the cost of not supporting older operating
-//! systems) can be chosen using the standard `X_DEPLOYMENT_TARGET`
-//! environment variables:
-//!
-//! - macOS: `MACOSX_DEPLOYMENT_TARGET`, default `10.12`, `11.0` on Aarch64.
-//! - iOS / iPadOS: `IPHONEOS_DEPLOYMENT_TARGET`, default `10.0`.
-//! - tvOS: `TVOS_DEPLOYMENT_TARGET`, default `10.0`.
-//! - watchOS: `WATCHOS_DEPLOYMENT_TARGET`, default `5.0`.
-//!
-//! The default (and minimum) versions are the [same as those Rust itself
-//! has][rust-apple-spec].
-//!
-//! [rust-apple-spec]: https://github.com/rust-lang/rust/blob/1.74.0/compiler/rustc_target/src/spec/apple_base.rs
-//!
 //!
 //! ### GNUStep's [`libobjc2`](https://github.com/gnustep/libobjc2)
 //!
diff --git a/crates/objc2/src/lib.rs b/crates/objc2/src/lib.rs
index 557b23ef4..3a969c112 100644
--- a/crates/objc2/src/lib.rs
+++ b/crates/objc2/src/lib.rs
@@ -255,7 +255,7 @@ compile_error!("ObjFW is not yet supported");
 #[cfg_attr(feature = "unstable-objfw", link(name = "objfw-rt", kind = "dylib"))]
 extern "C" {}
 
-// Link to Foundation to make NSObject work
+// Link to Foundation to make NSObject and OS version lookup work.
 #[cfg_attr(target_vendor = "apple", link(name = "Foundation", kind = "framework"))]
 #[cfg_attr(
     all(feature = "gnustep-1-7", not(feature = "unstable-compiler-rt")),
diff --git a/crates/objc2/src/macros/available.rs b/crates/objc2/src/macros/available.rs
new file mode 100644
index 000000000..d0573d330
--- /dev/null
+++ b/crates/objc2/src/macros/available.rs
@@ -0,0 +1,193 @@
+/// Check if APIs from the given operating system versions are available.
+///
+/// Apple adds new APIs with new OS releases, and as a developer, you often
+/// want to use those to give your users the best behaviour, while still
+/// supporting older OS versions that don't have those APIs (instead of
+/// crashing e.g. because of an undefined selector).
+///
+/// This macro allows you to conditionally execute code depending on if the
+/// current OS version is higher than or equal to the version given in the
+/// macro.
+///
+/// If no version is specified for a certain OS, the API will be assumed to be
+/// unavailable there. This default can be changed by adding a trailing `..`
+/// to the macro invocation.
+///
+/// This is very similar to `@available` in Objective-C and `#available` in
+/// Swift, see [Apple's documentation][apple-doc]. Another great introduction
+/// to availability can be found in [here][epir-availability].
+///
+/// [apple-doc]: https://developer.apple.com/documentation/xcode/running-code-on-a-specific-version#Require-a-minimum-operating-system-version-for-a-feature
+/// [epir-availability]: https://epir.at/2019/10/30/api-availability-and-target-conditionals/
+///
+///
+/// # Operating systems
+///
+/// The operating system names this macro accepts, the standard environment
+/// variables that you use to raise the deployment target (the minimum
+/// supported OS version) and the current default versions are all summarized
+/// in the table below.
+///
+/// | OS Value   | Name                    | Environment Variable         | Default |
+/// | ---------- | ----------------------- | ---------------------------- | ------- |
+/// | `ios`      | iOS/iPadOS/Mac Catalyst | `IPHONEOS_DEPLOYMENT_TARGET` | 10.0    |
+/// | `macos`    | macOS                   | `MACOSX_DEPLOYMENT_TARGET`   | 10.12   |
+/// | `tvos`     | tvOS                    | `TVOS_DEPLOYMENT_TARGET`     | 10.0    |
+/// | `visionos` | visionOS                | `XROS_DEPLOYMENT_TARGET`     | 1.0     |
+/// | `watchos`  | watchOS                 | `WATCHOS_DEPLOYMENT_TARGET`  | 5.0     |
+///
+/// The default version is the same as that of `rustc` itself.
+///
+///
+/// # Optimizations
+///
+/// This macro will statically be set to `true` when the deployment target is
+/// high enough.
+///
+/// If a runtime check is deemed necessary, the version lookup will be cached.
+///
+///
+/// # Alternatives
+///
+/// Instead of checking the version at runtime, you could do one of the
+/// following instead:
+///
+/// 1. Check statically that you're compiling for a version where the API is
+///    available, e.g. by checking the `*_DEPLOYMENT_TARGET` variables in a
+///    build script or at `const` time.
+///
+/// 2. Check at runtime that a class, method or symbol is available, using
+///    e.g. [`AnyClass::get`], [`respondsToSelector`] or [weak linking].
+///
+/// [`AnyClass::get`]: crate::runtime::AnyClass::get
+/// [`respondsToSelector`]: crate::runtime::NSObjectProtocol::respondsToSelector
+/// [weak linking]: https://github.com/rust-lang/rust/issues/29603
+///
+///
+/// # Examples
+///
+/// Use the [`effectiveAppearance`] API that was added in macOS 10.14.
+///
+/// ```
+/// # #[cfg(available_in_frameworks)]
+/// use objc2_app_kit::{NSApplication, NSAppearance, NSAppearanceNameAqua};
+/// use objc2::available;
+///
+/// let appearance = if available!(macos = 10.14) {
+///     // Dark mode and `effectiveAppearance` was added in macOS 10.14.
+///     # #[cfg(available_in_frameworks)]
+///     NSApplication::sharedApplication(mtm).effectiveAppearance()
+/// } else {
+///     // Fall back to `NSAppearanceNameAqua` on macOS 10.13 and below.
+///     # #[cfg(available_in_frameworks)]
+///     NSAppearance::appearanceNamed(NSAppearanceNameAqua).unwrap()
+/// };
+/// ```
+///
+/// Use an API added in Xcode 16.0 SDKs.
+///
+/// We use `..` here in case Apple adds a new operating system in the future,
+/// then we probably also want the branch to be taken there.
+///
+/// ```
+/// use objc2::available;
+///
+/// if available!(ios = 18.0, macos = 15.0, tvos = 18.0, visionos = 2.0, watchos = 11.0, ..) {
+///     // Use some recent API here.
+/// }
+/// ```
+///
+/// Set the [`wantsExtendedDynamicRangeContent`] property, which is available
+/// since iOS 16.0, macOS 10.11 and visionOS 1.0, but is not available on tvOS
+/// and watchOS.
+///
+/// ```
+/// use objc2::available;
+///
+/// if available!(ios = 16.0, macos = 10.11, visionos = 1.0) {
+///     # #[cfg(available_in_frameworks)]
+///     layer.setWantsExtendedDynamicRangeContent(true);
+/// }
+/// ```
+///
+/// [`effectiveAppearance`]: https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance?language=objc
+/// [`wantsExtendedDynamicRangeContent`]: https://developer.apple.com/documentation/quartzcore/cametallayer/1478161-wantsextendeddynamicrangecontent
+#[doc(alias = "@available")] // Objective-C
+#[doc(alias = "#available")] // Swift
+#[macro_export]
+macro_rules! available {
+    (
+        // Returns `false` on unspecified platforms.
+        $(
+            $os:ident $(= $major:literal $(. $minor:literal $(. $patch:literal)?)?)?
+        ),* $(,)?
+    ) => {
+        $crate::__macro_helpers::is_available({
+            // TODO: Use inline const once in MSRV
+            #[allow(clippy::needless_update)]
+            const VERSION: $crate::__macro_helpers::AvailableVersion = $crate::__macro_helpers::AvailableVersion {
+                $(
+                    // Doesn't actually parse versions this way, but is
+                    // helpful to write it like this for documentation.
+                    //
+                    // We use optionality for the version here, to allow
+                    // rust-analyzer to work with partially filled macros.
+                    $os: $($crate::__available_version!($major $(. $minor $(. $patch)?)?))?,
+                )*
+                // A version this high will never be lower than the deployment
+                // target, and hence will always return `false` from
+                // `is_available`.
+                .. $crate::__macro_helpers::AvailableVersion::MAX
+            };
+            VERSION
+        })
+    };
+    (
+        // Returns `true` on unspecified platforms because of the trailing `..`.
+        $(
+            $os:ident $(= $major:literal $(. $minor:literal $(. $patch:literal)?)?)?,
+        )*
+        ..
+    ) => {
+        $crate::__macro_helpers::is_available({
+            #[allow(clippy::needless_update)]
+            const VERSION: $crate::__macro_helpers::AvailableVersion = $crate::__macro_helpers::AvailableVersion {
+                $(
+                    $os: $($crate::__available_version!($major $(. $minor $(. $patch)?)?))?,
+                )*
+                // A version of 0.0.0 will always be lower than the deployment
+                // target, and hence will always return `true` from
+                // `is_available`.
+                //
+                // We do this when `..` is specified.
+                .. $crate::__macro_helpers::AvailableVersion::MIN
+            };
+            VERSION
+        })
+    };
+}
+
+/// Both `tt` and `literal` matches either `$major` as an integer, or
+/// `$major.$minor` as a float.
+///
+/// As such, we cannot just take `$major:tt . $minor:tt . $patch:tt` and
+/// convert that to `OSVersion` directly, we must convert it to a string
+/// first, and then parse that.
+///
+/// We also _have_ to do string parsing, floating point parsing wouldn't be
+/// enough (because e.g. `10.10` would result in the float `10.1` and parse
+/// wrongly).
+///
+/// Note that we intentionally `stringify!` before passing to `concat!`, as
+/// that seems to properly preserve all zeros in the literal.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __available_version {
+    // Just in case rustc's parsing changes in the future, let's handle this
+    // generically, instead of trying to split each part into separate `tt`.
+    ($($version_part_or_period:tt)*) => {
+        $crate::__macro_helpers::OSVersion::from_str($crate::__macro_helpers::concat!($(
+            $crate::__macro_helpers::stringify!($version_part_or_period),
+        )*))
+    };
+}
diff --git a/crates/objc2/src/macros/mod.rs b/crates/objc2/src/macros/mod.rs
index e0225d5ed..a871ccffe 100644
--- a/crates/objc2/src/macros/mod.rs
+++ b/crates/objc2/src/macros/mod.rs
@@ -2,6 +2,7 @@ mod __attribute_helpers;
 mod __method_msg_send;
 mod __msg_send_parse;
 mod __rewrite_self_param;
+mod available;
 mod declare_class;
 mod extern_category;
 mod extern_class;
diff --git a/crates/objc2/src/runtime/nsobject.rs b/crates/objc2/src/runtime/nsobject.rs
index 4f028ba3b..3de277be0 100644
--- a/crates/objc2/src/runtime/nsobject.rs
+++ b/crates/objc2/src/runtime/nsobject.rs
@@ -163,34 +163,12 @@ pub unsafe trait NSObjectProtocol {
     ///
     /// See [Apple's documentation][apple-doc] for more details.
     ///
-    /// [apple-doc]: https://developer.apple.com/documentation/objectivec/1418956-nsobject/1418583-respondstoselector?language=objc
-    ///
-    ///
-    /// # Example
-    ///
-    /// Check whether `NSApplication` has the [`effectiveAppearance`] method
-    /// before calling it, to support systems older than macOS 10.14 where the
-    /// method was added.
+    /// If using this for availability checking, you might want to consider
+    /// using the [`available!`] macro instead, as it is often more
+    /// performant than this runtime check.
     ///
-    /// ```
-    /// # #[cfg(available_in_frameworks)]
-    /// use objc2_app_kit::{NSApplication, NSAppearance, NSAppearanceNameAqua};
-    /// use objc2::runtime::NSObjectProtocol;
-    /// use objc2::sel;
-    ///
-    /// # let obj = objc2::runtime::NSObject::new();
-    /// # assert!(!obj.respondsToSelector(sel!(effectiveAppearance)));
-    /// #
-    /// # #[cfg(available_in_frameworks)] {
-    /// let appearance = if obj.respondsToSelector(sel!(effectiveAppearance)) {
-    ///     NSApplication::sharedApplication(mtm).effectiveAppearance()
-    /// } else {
-    ///     unsafe { NSAppearance::appearanceNamed(NSAppearanceNameAqua).unwrap() }
-    /// };
-    /// # }
-    /// ```
-    ///
-    /// [`effectiveAppearance`]: https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance?language=objc
+    /// [apple-doc]: https://developer.apple.com/documentation/objectivec/1418956-nsobject/1418583-respondstoselector?language=objc
+    /// [`available!`]: crate::available
     #[doc(alias = "respondsToSelector:")]
     fn respondsToSelector(&self, aSelector: Sel) -> bool
     where
diff --git a/crates/test-assembly/crates/test_available/Cargo.toml b/crates/test-assembly/crates/test_available/Cargo.toml
new file mode 100644
index 000000000..7cdc8786f
--- /dev/null
+++ b/crates/test-assembly/crates/test_available/Cargo.toml
@@ -0,0 +1,25 @@
+[package]
+name = "test_available"
+version = "0.1.0"
+edition.workspace = true
+publish = false
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+objc2 = { path = "../../../objc2" }
+
+[features]
+# Runtime
+gnustep-1-7 = ["objc2/gnustep-1-7"]
+gnustep-1-8 = ["gnustep-1-7", "objc2/gnustep-1-8"]
+gnustep-1-9 = ["gnustep-1-8", "objc2/gnustep-1-9"]
+gnustep-2-0 = ["gnustep-1-9", "objc2/gnustep-2-0"]
+gnustep-2-1 = ["gnustep-2-0", "objc2/gnustep-2-1"]
+
+# Hack
+assembly-features = []
+
+[package.metadata.release]
+release = false
diff --git a/crates/test-assembly/crates/test_available/expected/apple-aarch64.s b/crates/test-assembly/crates/test_available/expected/apple-aarch64.s
new file mode 100644
index 000000000..4f6719ec8
--- /dev/null
+++ b/crates/test-assembly/crates/test_available/expected/apple-aarch64.s
@@ -0,0 +1,190 @@
+	.section	__TEXT,__text,regular,pure_instructions
+	.p2align	2
+SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0):
+Lloh0:
+	adrp	x0, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGE
+Lloh1:
+	ldr	x0, [x0, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGEOFF]
+	ldapr	x8, [x0]
+	cmp	x8, #3
+	b.ne	LBB0_2
+	ret
+LBB0_2:
+	sub	sp, sp, #48
+	stp	x29, x30, [sp, #32]
+	add	x29, sp, #32
+	add	x8, x0, #8
+	sub	x9, x29, #1
+	stp	x8, x9, [sp]
+	mov	x8, sp
+	str	x8, [sp, #16]
+Lloh2:
+	adrp	x3, l_anon.[ID].0@PAGE
+Lloh3:
+	add	x3, x3, l_anon.[ID].0@PAGEOFF
+Lloh4:
+	adrp	x4, l_anon.[ID].2@PAGE
+Lloh5:
+	add	x4, x4, l_anon.[ID].2@PAGEOFF
+	add	x2, sp, #16
+	mov	w1, #1
+	bl	SYM(std::sys::sync::once::queue::Once::call::GENERATED_ID, 0)
+	ldp	x29, x30, [sp, #32]
+	add	sp, sp, #48
+	ret
+	.loh AdrpLdrGot	Lloh0, Lloh1
+	.loh AdrpAdd	Lloh4, Lloh5
+	.loh AdrpAdd	Lloh2, Lloh3
+
+	.p2align	2
+SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0):
+	stp	x20, x19, [sp, #-32]!
+	stp	x29, x30, [sp, #16]
+	add	x29, sp, #16
+	ldr	x8, [x0]
+	ldr	x19, [x8]
+	str	xzr, [x8]
+	cbz	x19, LBB1_2
+	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	str	w0, [x19]
+	ldp	x29, x30, [sp, #16]
+	ldp	x20, x19, [sp], #32
+	ret
+LBB1_2:
+Lloh6:
+	adrp	x0, l_anon.[ID].3@PAGE
+Lloh7:
+	add	x0, x0, l_anon.[ID].3@PAGEOFF
+	bl	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
+	.loh AdrpAdd	Lloh6, Lloh7
+
+	.p2align	2
+SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0):
+	stp	x20, x19, [sp, #-32]!
+	stp	x29, x30, [sp, #16]
+	add	x29, sp, #16
+	ldr	x8, [x0]
+	ldr	x19, [x8]
+	str	xzr, [x8]
+	cbz	x19, LBB2_2
+	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	str	w0, [x19]
+	ldp	x29, x30, [sp, #16]
+	ldp	x20, x19, [sp], #32
+	ret
+LBB2_2:
+Lloh8:
+	adrp	x0, l_anon.[ID].3@PAGE
+Lloh9:
+	add	x0, x0, l_anon.[ID].3@PAGEOFF
+	bl	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
+	.loh AdrpAdd	Lloh8, Lloh9
+
+	.globl	_always
+	.p2align	2
+_always:
+	mov	w0, #1
+	ret
+
+	.globl	_never
+	.p2align	2
+_never:
+	mov	w0, #0
+	ret
+
+	.globl	_low
+	.p2align	2
+_low:
+	mov	w0, #1
+	ret
+
+	.globl	_high
+	.p2align	2
+_high:
+	stp	x20, x19, [sp, #-32]!
+	stp	x29, x30, [sp, #16]
+	add	x29, sp, #16
+Lloh10:
+	adrp	x19, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGE
+Lloh11:
+	ldr	x19, [x19, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGEOFF]
+	ldapr	x8, [x19]
+	cmp	x8, #3
+	b.ne	LBB6_2
+LBB6_1:
+	ldrh	w8, [x19, #10]
+	cmp	w8, #14
+	cset	w0, hi
+	ldp	x29, x30, [sp, #16]
+	ldp	x20, x19, [sp], #32
+	ret
+LBB6_2:
+	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	b	LBB6_1
+	.loh AdrpLdrGot	Lloh10, Lloh11
+
+	.globl	_only_ios
+	.p2align	2
+_only_ios:
+	mov	w0, #0
+	ret
+
+	.globl	_two_checks
+	.p2align	2
+_two_checks:
+	stp	x20, x19, [sp, #-32]!
+	stp	x29, x30, [sp, #16]
+	add	x29, sp, #16
+Lloh12:
+	adrp	x19, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGE
+Lloh13:
+	ldr	x19, [x19, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGEOFF]
+	ldapr	x8, [x19]
+	cmp	x8, #3
+	b.ne	LBB8_3
+	ldrh	w20, [x19, #10]
+	ldapr	x8, [x19]
+	cmp	x8, #3
+	b.ne	LBB8_4
+LBB8_2:
+	cmp	w20, #13
+	ldrh	w8, [x19, #10]
+	ccmp	w8, #14, #0, hi
+	cset	w0, hi
+	ldp	x29, x30, [sp, #16]
+	ldp	x20, x19, [sp], #32
+	ret
+LBB8_3:
+	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	ldrh	w20, [x19, #10]
+	ldapr	x8, [x19]
+	cmp	x8, #3
+	b.eq	LBB8_2
+LBB8_4:
+	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	b	LBB8_2
+	.loh AdrpLdrGot	Lloh12, Lloh13
+
+	.section	__DATA,__const
+	.p2align	3, 0x0
+l_anon.[ID].0:
+	.asciz	"\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\b\000\000\000\000\000\000"
+	.quad	SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0)
+	.quad	SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0)
+
+	.section	__TEXT,__const
+l_anon.[ID].1:
+	.ascii	"$RUSTC/library/std/src/sync/once.rs"
+
+	.section	__DATA,__const
+	.p2align	3, 0x0
+l_anon.[ID].2:
+	.quad	l_anon.[ID].1
+	.asciz	"p\000\000\000\000\000\000\000\331\000\000\000\024\000\000"
+
+	.p2align	3, 0x0
+l_anon.[ID].3:
+	.quad	l_anon.[ID].1
+	.asciz	"p\000\000\000\000\000\000\000\331\000\000\0001\000\000"
+
+.subsections_via_symbols
diff --git a/crates/test-assembly/crates/test_available/expected/apple-armv7s.s b/crates/test-assembly/crates/test_available/expected/apple-armv7s.s
new file mode 100644
index 000000000..309aafe4f
--- /dev/null
+++ b/crates/test-assembly/crates/test_available/expected/apple-armv7s.s
@@ -0,0 +1,206 @@
+	.section	__TEXT,__text,regular,pure_instructions
+	.syntax unified
+	.p2align	2
+	.code	32
+SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0):
+	ldr	r0, LCPI0_0
+LPC0_0:
+	ldr	r0, [pc, r0]
+	ldr	r1, [r0]
+	dmb	ish
+	cmp	r1, #3
+	bxeq	lr
+LBB0_1:
+	push	{r2, r3, r4, r5, r6, r7, lr}
+	add	r7, sp, #20
+	add	r1, r0, #4
+	str	r1, [sp, #4]
+	sub	r1, r7, #1
+	str	r1, [sp, #8]
+	add	r1, sp, #4
+	str	r1, [r7, #-8]
+	ldr	r1, LCPI0_1
+LPC0_1:
+	add	r1, pc, r1
+	ldr	r3, LCPI0_2
+LPC0_2:
+	add	r3, pc, r3
+	str	r1, [sp]
+	sub	r2, r7, #8
+	mov	r1, #1
+	bl	SYM(std::sys::sync::once::queue::Once::call::GENERATED_ID, 0)
+	mov	sp, r7
+	pop	{r7, lr}
+	bx	lr
+	.p2align	2
+	.data_region
+LCPI0_0:
+	.long	LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC0_0+8)
+LCPI0_1:
+	.long	l_anon.[ID].2-(LPC0_1+8)
+LCPI0_2:
+	.long	l_anon.[ID].0-(LPC0_2+8)
+	.end_data_region
+
+	.p2align	2
+	.code	32
+SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0):
+	push	{r4, r7, lr}
+	add	r7, sp, #4
+	ldr	r0, [r0]
+	ldr	r4, [r0]
+	mov	r1, #0
+	str	r1, [r0]
+	cmp	r4, #0
+	beq	LBB1_2
+	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	str	r0, [r4]
+	pop	{r4, r7, pc}
+LBB1_2:
+	movw	r0, :lower16:(l_anon.[ID].3-(LPC1_0+8))
+	movt	r0, :upper16:(l_anon.[ID].3-(LPC1_0+8))
+LPC1_0:
+	add	r0, pc, r0
+	mov	lr, pc
+	b	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
+
+	.p2align	2
+	.code	32
+SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0):
+	push	{r4, r7, lr}
+	add	r7, sp, #4
+	ldr	r0, [r0]
+	ldr	r4, [r0]
+	mov	r1, #0
+	str	r1, [r0]
+	cmp	r4, #0
+	beq	LBB2_2
+	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	str	r0, [r4]
+	pop	{r4, r7, pc}
+LBB2_2:
+	movw	r0, :lower16:(l_anon.[ID].3-(LPC2_0+8))
+	movt	r0, :upper16:(l_anon.[ID].3-(LPC2_0+8))
+LPC2_0:
+	add	r0, pc, r0
+	mov	lr, pc
+	b	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
+
+	.globl	_always
+	.p2align	2
+	.code	32
+_always:
+	mov	r0, #1
+	bx	lr
+
+	.globl	_never
+	.p2align	2
+	.code	32
+_never:
+	mov	r0, #0
+	bx	lr
+
+	.globl	_low
+	.p2align	2
+	.code	32
+_low:
+	mov	r0, #1
+	bx	lr
+
+	.globl	_high
+	.p2align	2
+	.code	32
+_high:
+	push	{r4, r7, lr}
+	add	r7, sp, #4
+	movw	r4, :lower16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC6_0+8))
+	movt	r4, :upper16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC6_0+8))
+LPC6_0:
+	ldr	r4, [pc, r4]
+	ldr	r0, [r4]
+	dmb	ish
+	cmp	r0, #3
+	bne	LBB6_2
+LBB6_1:
+	ldrh	r1, [r4, #6]
+	mov	r0, #0
+	cmp	r1, #17
+	movwhi	r0, #1
+	pop	{r4, r7, pc}
+LBB6_2:
+	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	b	LBB6_1
+
+	.globl	_only_ios
+	.p2align	2
+	.code	32
+_only_ios:
+	mov	r0, #1
+	bx	lr
+
+	.globl	_two_checks
+	.p2align	2
+	.code	32
+_two_checks:
+	push	{r4, r5, r7, lr}
+	add	r7, sp, #8
+	movw	r4, :lower16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC8_0+8))
+	movt	r4, :upper16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC8_0+8))
+LPC8_0:
+	ldr	r4, [pc, r4]
+	ldr	r0, [r4]
+	dmb	ish
+	cmp	r0, #3
+	bne	LBB8_3
+LBB8_1:
+	ldrh	r5, [r4, #6]
+	ldr	r0, [r4]
+	dmb	ish
+	cmp	r0, #3
+	bne	LBB8_4
+LBB8_2:
+	mov	r0, #0
+	cmp	r5, #16
+	mov	r1, #0
+	movwhi	r1, #1
+	ldrh	r2, [r4, #6]
+	cmp	r2, #17
+	movwhi	r0, #1
+	and	r0, r1, r0
+	pop	{r4, r5, r7, pc}
+LBB8_3:
+	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	b	LBB8_1
+LBB8_4:
+	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	b	LBB8_2
+
+	.section	__DATA,__const
+	.p2align	2, 0x0
+l_anon.[ID].0:
+	.asciz	"\000\000\000\000\004\000\000\000\004\000\000"
+	.long	SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0)
+	.long	SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0)
+
+	.section	__TEXT,__const
+l_anon.[ID].1:
+	.ascii	"$RUSTC/library/std/src/sync/once.rs"
+
+	.section	__DATA,__const
+	.p2align	2, 0x0
+l_anon.[ID].2:
+	.long	l_anon.[ID].1
+	.asciz	"p\000\000\000\331\000\000\000\024\000\000"
+
+	.p2align	2, 0x0
+l_anon.[ID].3:
+	.long	l_anon.[ID].1
+	.asciz	"p\000\000\000\331\000\000\0001\000\000"
+
+	.section	__DATA,__nl_symbol_ptr,non_lazy_symbol_pointers
+	.p2align	2, 0x0
+LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr:
+	.indirect_symbol	SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)
+	.long	0
+
+.subsections_via_symbols
diff --git a/crates/test-assembly/crates/test_available/expected/apple-old-x86.s b/crates/test-assembly/crates/test_available/expected/apple-old-x86.s
new file mode 100644
index 000000000..b5cd3c8d3
--- /dev/null
+++ b/crates/test-assembly/crates/test_available/expected/apple-old-x86.s
@@ -0,0 +1,218 @@
+	.section	__TEXT,__text,regular,pure_instructions
+	.intel_syntax noprefix
+SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0):
+	push	ebp
+	mov	ebp, esp
+	push	esi
+	sub	esp, 20
+	call	L0$pb
+L0$pb:
+	pop	ecx
+	mov	eax, dword ptr [ecx + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L0$pb]
+	mov	edx, dword ptr [eax]
+	cmp	edx, 3
+	jne	LBB0_1
+LBB0_2:
+	add	esp, 20
+	pop	esi
+	pop	ebp
+	ret
+LBB0_1:
+	lea	edx, [eax + 4]
+	lea	esi, [ebp - 20]
+	mov	dword ptr [esi], edx
+	lea	edx, [ebp - 5]
+	mov	dword ptr [esi + 4], edx
+	lea	edx, [ebp - 12]
+	mov	dword ptr [edx], esi
+	sub	esp, 12
+	lea	esi, [ecx + l_anon.[ID].2-L0$pb]
+	lea	ecx, [ecx + l_anon.[ID].0-L0$pb]
+	push	esi
+	push	ecx
+	push	edx
+	push	1
+	push	eax
+	call	SYM(std::sys::sync::once::queue::Once::call::GENERATED_ID, 0)
+	add	esp, 32
+	jmp	LBB0_2
+
+	.p2align	4, 0x90
+SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0):
+	push	ebp
+	mov	ebp, esp
+	push	esi
+	push	eax
+	call	L1$pb
+L1$pb:
+	pop	eax
+	mov	ecx, dword ptr [ebp + 8]
+	mov	ecx, dword ptr [ecx]
+	mov	esi, dword ptr [ecx]
+	mov	dword ptr [ecx], 0
+	test	esi, esi
+	je	LBB1_2
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [esi], eax
+	add	esp, 4
+	pop	esi
+	pop	ebp
+	ret
+LBB1_2:
+	lea	eax, [eax + l_anon.[ID].3-L1$pb]
+	mov	dword ptr [esp], eax
+	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
+
+	.p2align	4, 0x90
+SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0):
+	push	ebp
+	mov	ebp, esp
+	push	esi
+	push	eax
+	call	L2$pb
+L2$pb:
+	pop	eax
+	mov	ecx, dword ptr [ebp + 8]
+	mov	ecx, dword ptr [ecx]
+	mov	esi, dword ptr [ecx]
+	mov	dword ptr [ecx], 0
+	test	esi, esi
+	je	LBB2_2
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [esi], eax
+	add	esp, 4
+	pop	esi
+	pop	ebp
+	ret
+LBB2_2:
+	lea	eax, [eax + l_anon.[ID].3-L2$pb]
+	mov	dword ptr [esp], eax
+	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
+
+	.globl	_always
+	.p2align	4, 0x90
+_always:
+	push	ebp
+	mov	ebp, esp
+	mov	al, 1
+	pop	ebp
+	ret
+
+	.globl	_never
+	.p2align	4, 0x90
+_never:
+	push	ebp
+	mov	ebp, esp
+	xor	eax, eax
+	pop	ebp
+	ret
+
+	.globl	_low
+	.p2align	4, 0x90
+_low:
+	push	ebp
+	mov	ebp, esp
+	mov	al, 1
+	pop	ebp
+	ret
+
+	.globl	_high
+	.p2align	4, 0x90
+_high:
+	push	ebp
+	mov	ebp, esp
+	push	esi
+	push	eax
+	call	L6$pb
+L6$pb:
+	pop	eax
+	mov	esi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L6$pb]
+	mov	eax, dword ptr [esi]
+	cmp	eax, 3
+	jne	LBB6_1
+LBB6_2:
+	cmp	word ptr [esi + 6], 15
+	setae	al
+	add	esp, 4
+	pop	esi
+	pop	ebp
+	ret
+LBB6_1:
+	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	jmp	LBB6_2
+
+	.globl	_only_ios
+	.p2align	4, 0x90
+_only_ios:
+	push	ebp
+	mov	ebp, esp
+	xor	eax, eax
+	pop	ebp
+	ret
+
+	.globl	_two_checks
+	.p2align	4, 0x90
+_two_checks:
+	push	ebp
+	mov	ebp, esp
+	push	edi
+	push	esi
+	call	L8$pb
+L8$pb:
+	pop	eax
+	mov	esi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L8$pb]
+	mov	eax, dword ptr [esi]
+	cmp	eax, 3
+	jne	LBB8_1
+	movzx	edi, word ptr [esi + 6]
+	mov	eax, dword ptr [esi]
+	cmp	eax, 3
+	jne	LBB8_3
+LBB8_4:
+	cmp	di, 14
+	setae	cl
+	cmp	word ptr [esi + 6], 15
+	setae	al
+	and	al, cl
+	pop	esi
+	pop	edi
+	pop	ebp
+	ret
+LBB8_1:
+	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	movzx	edi, word ptr [esi + 6]
+	mov	eax, dword ptr [esi]
+	cmp	eax, 3
+	je	LBB8_4
+LBB8_3:
+	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	jmp	LBB8_4
+
+	.section	__DATA,__const
+	.p2align	2, 0x0
+l_anon.[ID].0:
+	.asciz	"\000\000\000\000\004\000\000\000\004\000\000"
+	.long	SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0)
+	.long	SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0)
+
+	.section	__TEXT,__const
+l_anon.[ID].1:
+	.ascii	"$RUSTC/library/std/src/sync/once.rs"
+
+	.section	__DATA,__const
+	.p2align	2, 0x0
+l_anon.[ID].2:
+	.long	l_anon.[ID].1
+	.asciz	"p\000\000\000\331\000\000\000\024\000\000"
+
+	.p2align	2, 0x0
+l_anon.[ID].3:
+	.long	l_anon.[ID].1
+	.asciz	"p\000\000\000\331\000\000\0001\000\000"
+
+	.section	__IMPORT,__pointers,non_lazy_symbol_pointers
+LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr:
+	.indirect_symbol	SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)
+	.long	0
+
+.subsections_via_symbols
diff --git a/crates/test-assembly/crates/test_available/expected/apple-x86.s b/crates/test-assembly/crates/test_available/expected/apple-x86.s
new file mode 100644
index 000000000..eeb248c01
--- /dev/null
+++ b/crates/test-assembly/crates/test_available/expected/apple-x86.s
@@ -0,0 +1,218 @@
+	.section	__TEXT,__text,regular,pure_instructions
+	.intel_syntax noprefix
+SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0):
+	push	ebp
+	mov	ebp, esp
+	push	esi
+	sub	esp, 20
+	call	L0$pb
+L0$pb:
+	pop	ecx
+	mov	eax, dword ptr [ecx + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L0$pb]
+	mov	edx, dword ptr [eax]
+	cmp	edx, 3
+	jne	LBB0_1
+LBB0_2:
+	add	esp, 20
+	pop	esi
+	pop	ebp
+	ret
+LBB0_1:
+	lea	edx, [eax + 4]
+	lea	esi, [ebp - 20]
+	mov	dword ptr [esi], edx
+	lea	edx, [ebp - 5]
+	mov	dword ptr [esi + 4], edx
+	lea	edx, [ebp - 12]
+	mov	dword ptr [edx], esi
+	sub	esp, 12
+	lea	esi, [ecx + l_anon.[ID].2-L0$pb]
+	lea	ecx, [ecx + l_anon.[ID].0-L0$pb]
+	push	esi
+	push	ecx
+	push	edx
+	push	1
+	push	eax
+	call	SYM(std::sys::sync::once::queue::Once::call::GENERATED_ID, 0)
+	add	esp, 32
+	jmp	LBB0_2
+
+	.p2align	4, 0x90
+SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0):
+	push	ebp
+	mov	ebp, esp
+	push	esi
+	push	eax
+	call	L1$pb
+L1$pb:
+	pop	eax
+	mov	ecx, dword ptr [ebp + 8]
+	mov	ecx, dword ptr [ecx]
+	mov	esi, dword ptr [ecx]
+	mov	dword ptr [ecx], 0
+	test	esi, esi
+	je	LBB1_2
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [esi], eax
+	add	esp, 4
+	pop	esi
+	pop	ebp
+	ret
+LBB1_2:
+	lea	eax, [eax + l_anon.[ID].3-L1$pb]
+	mov	dword ptr [esp], eax
+	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
+
+	.p2align	4, 0x90
+SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0):
+	push	ebp
+	mov	ebp, esp
+	push	esi
+	push	eax
+	call	L2$pb
+L2$pb:
+	pop	eax
+	mov	ecx, dword ptr [ebp + 8]
+	mov	ecx, dword ptr [ecx]
+	mov	esi, dword ptr [ecx]
+	mov	dword ptr [ecx], 0
+	test	esi, esi
+	je	LBB2_2
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [esi], eax
+	add	esp, 4
+	pop	esi
+	pop	ebp
+	ret
+LBB2_2:
+	lea	eax, [eax + l_anon.[ID].3-L2$pb]
+	mov	dword ptr [esp], eax
+	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
+
+	.globl	_always
+	.p2align	4, 0x90
+_always:
+	push	ebp
+	mov	ebp, esp
+	mov	al, 1
+	pop	ebp
+	ret
+
+	.globl	_never
+	.p2align	4, 0x90
+_never:
+	push	ebp
+	mov	ebp, esp
+	xor	eax, eax
+	pop	ebp
+	ret
+
+	.globl	_low
+	.p2align	4, 0x90
+_low:
+	push	ebp
+	mov	ebp, esp
+	mov	al, 1
+	pop	ebp
+	ret
+
+	.globl	_high
+	.p2align	4, 0x90
+_high:
+	push	ebp
+	mov	ebp, esp
+	push	esi
+	push	eax
+	call	L6$pb
+L6$pb:
+	pop	eax
+	mov	esi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L6$pb]
+	mov	eax, dword ptr [esi]
+	cmp	eax, 3
+	jne	LBB6_1
+LBB6_2:
+	cmp	word ptr [esi + 6], 18
+	setae	al
+	add	esp, 4
+	pop	esi
+	pop	ebp
+	ret
+LBB6_1:
+	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	jmp	LBB6_2
+
+	.globl	_only_ios
+	.p2align	4, 0x90
+_only_ios:
+	push	ebp
+	mov	ebp, esp
+	mov	al, 1
+	pop	ebp
+	ret
+
+	.globl	_two_checks
+	.p2align	4, 0x90
+_two_checks:
+	push	ebp
+	mov	ebp, esp
+	push	edi
+	push	esi
+	call	L8$pb
+L8$pb:
+	pop	eax
+	mov	esi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L8$pb]
+	mov	eax, dword ptr [esi]
+	cmp	eax, 3
+	jne	LBB8_1
+	movzx	edi, word ptr [esi + 6]
+	mov	eax, dword ptr [esi]
+	cmp	eax, 3
+	jne	LBB8_3
+LBB8_4:
+	cmp	di, 17
+	setae	cl
+	cmp	word ptr [esi + 6], 18
+	setae	al
+	and	al, cl
+	pop	esi
+	pop	edi
+	pop	ebp
+	ret
+LBB8_1:
+	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	movzx	edi, word ptr [esi + 6]
+	mov	eax, dword ptr [esi]
+	cmp	eax, 3
+	je	LBB8_4
+LBB8_3:
+	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	jmp	LBB8_4
+
+	.section	__DATA,__const
+	.p2align	2, 0x0
+l_anon.[ID].0:
+	.asciz	"\000\000\000\000\004\000\000\000\004\000\000"
+	.long	SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0)
+	.long	SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0)
+
+	.section	__TEXT,__const
+l_anon.[ID].1:
+	.ascii	"$RUSTC/library/std/src/sync/once.rs"
+
+	.section	__DATA,__const
+	.p2align	2, 0x0
+l_anon.[ID].2:
+	.long	l_anon.[ID].1
+	.asciz	"p\000\000\000\331\000\000\000\024\000\000"
+
+	.p2align	2, 0x0
+l_anon.[ID].3:
+	.long	l_anon.[ID].1
+	.asciz	"p\000\000\000\331\000\000\0001\000\000"
+
+	.section	__IMPORT,__pointers,non_lazy_symbol_pointers
+LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr:
+	.indirect_symbol	SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)
+	.long	0
+
+.subsections_via_symbols
diff --git a/crates/test-assembly/crates/test_available/expected/apple-x86_64.s b/crates/test-assembly/crates/test_available/expected/apple-x86_64.s
new file mode 100644
index 000000000..a09c89aff
--- /dev/null
+++ b/crates/test-assembly/crates/test_available/expected/apple-x86_64.s
@@ -0,0 +1,186 @@
+	.section	__TEXT,__text,regular,pure_instructions
+	.intel_syntax noprefix
+SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0):
+	mov	rdi, qword ptr [rip + SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPCREL]
+	mov	rax, qword ptr [rdi]
+	cmp	rax, 3
+	jne	LBB0_1
+	ret
+LBB0_1:
+	push	rbp
+	mov	rbp, rsp
+	sub	rsp, 32
+	lea	rax, [rdi + 8]
+	lea	rcx, [rbp - 32]
+	mov	qword ptr [rcx], rax
+	lea	rax, [rbp - 1]
+	mov	qword ptr [rcx + 8], rax
+	lea	rdx, [rbp - 16]
+	mov	qword ptr [rdx], rcx
+	lea	rcx, [rip + l_anon.[ID].0]
+	lea	r8, [rip + l_anon.[ID].2]
+	push	1
+	pop	rsi
+	call	SYM(std::sys::sync::once::queue::Once::call::GENERATED_ID, 0)
+	add	rsp, 32
+	pop	rbp
+	ret
+
+	.p2align	4, 0x90
+SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0):
+	push	rbp
+	mov	rbp, rsp
+	push	rbx
+	push	rax
+	mov	rax, qword ptr [rdi]
+	mov	rbx, qword ptr [rax]
+	mov	qword ptr [rax], 0
+	test	rbx, rbx
+	je	LBB1_2
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [rbx], eax
+	add	rsp, 8
+	pop	rbx
+	pop	rbp
+	ret
+LBB1_2:
+	lea	rdi, [rip + l_anon.[ID].3]
+	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
+
+	.p2align	4, 0x90
+SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0):
+	push	rbp
+	mov	rbp, rsp
+	push	rbx
+	push	rax
+	mov	rax, qword ptr [rdi]
+	mov	rbx, qword ptr [rax]
+	mov	qword ptr [rax], 0
+	test	rbx, rbx
+	je	LBB2_2
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [rbx], eax
+	add	rsp, 8
+	pop	rbx
+	pop	rbp
+	ret
+LBB2_2:
+	lea	rdi, [rip + l_anon.[ID].3]
+	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
+
+	.globl	_always
+	.p2align	4, 0x90
+_always:
+	push	rbp
+	mov	rbp, rsp
+	mov	al, 1
+	pop	rbp
+	ret
+
+	.globl	_never
+	.p2align	4, 0x90
+_never:
+	push	rbp
+	mov	rbp, rsp
+	xor	eax, eax
+	pop	rbp
+	ret
+
+	.globl	_low
+	.p2align	4, 0x90
+_low:
+	push	rbp
+	mov	rbp, rsp
+	mov	al, 1
+	pop	rbp
+	ret
+
+	.globl	_high
+	.p2align	4, 0x90
+_high:
+	push	rbp
+	mov	rbp, rsp
+	push	rbx
+	push	rax
+	mov	rbx, qword ptr [rip + SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPCREL]
+	mov	rax, qword ptr [rbx]
+	cmp	rax, 3
+	jne	LBB6_1
+LBB6_2:
+	cmp	word ptr [rbx + 10], 15
+	setae	al
+	add	rsp, 8
+	pop	rbx
+	pop	rbp
+	ret
+LBB6_1:
+	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	jmp	LBB6_2
+
+	.globl	_only_ios
+	.p2align	4, 0x90
+_only_ios:
+	push	rbp
+	mov	rbp, rsp
+	xor	eax, eax
+	pop	rbp
+	ret
+
+	.globl	_two_checks
+	.p2align	4, 0x90
+_two_checks:
+	push	rbp
+	mov	rbp, rsp
+	push	r14
+	push	rbx
+	mov	rbx, qword ptr [rip + SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPCREL]
+	mov	rax, qword ptr [rbx]
+	cmp	rax, 3
+	jne	LBB8_1
+	movzx	r14d, word ptr [rbx + 10]
+	mov	rax, qword ptr [rbx]
+	cmp	rax, 3
+	jne	LBB8_3
+LBB8_4:
+	cmp	r14w, 14
+	setae	cl
+	cmp	word ptr [rbx + 10], 15
+	setae	al
+	and	al, cl
+	pop	rbx
+	pop	r14
+	pop	rbp
+	ret
+LBB8_1:
+	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	movzx	r14d, word ptr [rbx + 10]
+	mov	rax, qword ptr [rbx]
+	cmp	rax, 3
+	je	LBB8_4
+LBB8_3:
+	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
+	jmp	LBB8_4
+
+	.section	__DATA,__const
+	.p2align	3, 0x0
+l_anon.[ID].0:
+	.asciz	"\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\b\000\000\000\000\000\000"
+	.quad	SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0)
+	.quad	SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0)
+
+	.section	__TEXT,__const
+l_anon.[ID].1:
+	.ascii	"$RUSTC/library/std/src/sync/once.rs"
+
+	.section	__DATA,__const
+	.p2align	3, 0x0
+l_anon.[ID].2:
+	.quad	l_anon.[ID].1
+	.asciz	"p\000\000\000\000\000\000\000\331\000\000\000\024\000\000"
+
+	.p2align	3, 0x0
+l_anon.[ID].3:
+	.quad	l_anon.[ID].1
+	.asciz	"p\000\000\000\000\000\000\000\331\000\000\0001\000\000"
+
+.subsections_via_symbols
diff --git a/crates/test-assembly/crates/test_available/expected/gnustep-x86.s b/crates/test-assembly/crates/test_available/expected/gnustep-x86.s
new file mode 100644
index 000000000..8043d973f
--- /dev/null
+++ b/crates/test-assembly/crates/test_available/expected/gnustep-x86.s
@@ -0,0 +1,63 @@
+	.text
+	.intel_syntax noprefix
+	.section	.text.always,"ax",@progbits
+	.globl	always
+	.p2align	4, 0x90
+	.type	always,@function
+always:
+	mov	al, 1
+	ret
+.Lfunc_end0:
+	.size	always, .Lfunc_end0-always
+
+	.section	.text.never,"ax",@progbits
+	.globl	never
+	.p2align	4, 0x90
+	.type	never,@function
+never:
+	xor	eax, eax
+	ret
+.Lfunc_end1:
+	.size	never, .Lfunc_end1-never
+
+	.section	.text.low,"ax",@progbits
+	.globl	low
+	.p2align	4, 0x90
+	.type	low,@function
+low:
+	mov	al, 1
+	ret
+.Lfunc_end2:
+	.size	low, .Lfunc_end2-low
+
+	.section	.text.high,"ax",@progbits
+	.globl	high
+	.p2align	4, 0x90
+	.type	high,@function
+high:
+	mov	al, 1
+	ret
+.Lfunc_end3:
+	.size	high, .Lfunc_end3-high
+
+	.section	.text.only_ios,"ax",@progbits
+	.globl	only_ios
+	.p2align	4, 0x90
+	.type	only_ios,@function
+only_ios:
+	xor	eax, eax
+	ret
+.Lfunc_end4:
+	.size	only_ios, .Lfunc_end4-only_ios
+
+	.section	.text.two_checks,"ax",@progbits
+	.globl	two_checks
+	.p2align	4, 0x90
+	.type	two_checks,@function
+two_checks:
+	mov	al, 1
+	ret
+.Lfunc_end5:
+	.size	two_checks, .Lfunc_end5-two_checks
+
+	.section	".note.GNU-stack","",@progbits
diff --git a/crates/test-assembly/crates/test_available/expected/gnustep-x86_64.s b/crates/test-assembly/crates/test_available/expected/gnustep-x86_64.s
new file mode 100644
index 000000000..8043d973f
--- /dev/null
+++ b/crates/test-assembly/crates/test_available/expected/gnustep-x86_64.s
@@ -0,0 +1,63 @@
+	.text
+	.intel_syntax noprefix
+	.section	.text.always,"ax",@progbits
+	.globl	always
+	.p2align	4, 0x90
+	.type	always,@function
+always:
+	mov	al, 1
+	ret
+.Lfunc_end0:
+	.size	always, .Lfunc_end0-always
+
+	.section	.text.never,"ax",@progbits
+	.globl	never
+	.p2align	4, 0x90
+	.type	never,@function
+never:
+	xor	eax, eax
+	ret
+.Lfunc_end1:
+	.size	never, .Lfunc_end1-never
+
+	.section	.text.low,"ax",@progbits
+	.globl	low
+	.p2align	4, 0x90
+	.type	low,@function
+low:
+	mov	al, 1
+	ret
+.Lfunc_end2:
+	.size	low, .Lfunc_end2-low
+
+	.section	.text.high,"ax",@progbits
+	.globl	high
+	.p2align	4, 0x90
+	.type	high,@function
+high:
+	mov	al, 1
+	ret
+.Lfunc_end3:
+	.size	high, .Lfunc_end3-high
+
+	.section	.text.only_ios,"ax",@progbits
+	.globl	only_ios
+	.p2align	4, 0x90
+	.type	only_ios,@function
+only_ios:
+	xor	eax, eax
+	ret
+.Lfunc_end4:
+	.size	only_ios, .Lfunc_end4-only_ios
+
+	.section	.text.two_checks,"ax",@progbits
+	.globl	two_checks
+	.p2align	4, 0x90
+	.type	two_checks,@function
+two_checks:
+	mov	al, 1
+	ret
+.Lfunc_end5:
+	.size	two_checks, .Lfunc_end5-two_checks
+
+	.section	".note.GNU-stack","",@progbits
diff --git a/crates/test-assembly/crates/test_available/lib.rs b/crates/test-assembly/crates/test_available/lib.rs
new file mode 100644
index 000000000..1dc1e7420
--- /dev/null
+++ b/crates/test-assembly/crates/test_available/lib.rs
@@ -0,0 +1,69 @@
+//! Test that the `available!` macro is optimized as expected.
+use objc2::available;
+
+#[no_mangle]
+fn always() -> bool {
+    // Can elide the version check here
+    available!(..)
+}
+
+#[no_mangle]
+fn never() -> bool {
+    // Can elide the version check here
+    available!()
+}
+
+#[no_mangle]
+fn low() -> bool {
+    // Can elide the version check here
+    available!(
+        macos = 10.7,
+        ios = 5.0,
+        tvos = 5.0,
+        watchos = 3.0,
+        visionos = 1.0,
+        ..
+    )
+}
+
+#[no_mangle]
+fn high() -> bool {
+    // Has to insert a runtime check here
+    available!(
+        macos = 15.0,
+        ios = 18.0,
+        tvos = 18.0,
+        watchos = 11.0,
+        visionos = 2.0,
+        ..
+    )
+}
+
+#[no_mangle]
+fn only_ios() -> bool {
+    // Can elide the version check here on macOS
+    available!(ios = 5.0)
+}
+
+#[no_mangle]
+fn two_checks() -> bool {
+    // Ideally only has to insert one runtime check here, but currently does two.
+
+    let in_14 = available!(
+        macos = 14.0,
+        ios = 17.0,
+        tvos = 17.0,
+        watchos = 10.0,
+        visionos = 1.0,
+        ..
+    );
+    let in_15 = available!(
+        macos = 15.0,
+        ios = 18.0,
+        tvos = 18.0,
+        watchos = 11.0,
+        visionos = 2.0,
+        ..
+    );
+    in_14 && in_15
+}
diff --git a/crates/test-ui/ui/available_invalid.rs b/crates/test-ui/ui/available_invalid.rs
new file mode 100644
index 000000000..96ad120ed
--- /dev/null
+++ b/crates/test-ui/ui/available_invalid.rs
@@ -0,0 +1,13 @@
+//! Various invalid usage of the `available!` macro.
+use objc2::available;
+
+fn main() {
+    // Space between version
+    available!(macos = 1 1);
+
+    // Various invalid syntax
+    available!(macos = ABCD);
+    available!(macos = );
+    available!(macos: 1.2);
+    available!(macos);
+}
diff --git a/crates/test-ui/ui/available_invalid.stderr b/crates/test-ui/ui/available_invalid.stderr
new file mode 100644
index 000000000..9e9c08026
--- /dev/null
+++ b/crates/test-ui/ui/available_invalid.stderr
@@ -0,0 +1,50 @@
+error: no rules expected the token `1`
+ --> ui/available_invalid.rs
+  |
+  |     available!(macos = 1 1);
+  |                          ^ no rules expected this token in macro call
+  |
+  = note: while trying to match sequence start
+
+error: no rules expected the token `ABCD`
+ --> ui/available_invalid.rs
+  |
+  |     available!(macos = ABCD);
+  |                        ^^^^ no rules expected this token in macro call
+  |
+note: while trying to match meta-variable `$major:literal`
+ --> $WORKSPACE/crates/objc2/src/macros/available.rs
+  |
+  |             $os:ident $(= $major:literal $(. $minor:literal $(. $patch:literal)?)?)?
+  |                           ^^^^^^^^^^^^^^
+
+error: unexpected end of macro invocation
+ --> ui/available_invalid.rs
+  |
+  |     available!(macos = );
+  |                       ^ missing tokens in macro arguments
+  |
+note: while trying to match meta-variable `$major:literal`
+ --> $WORKSPACE/crates/objc2/src/macros/available.rs
+  |
+  |             $os:ident $(= $major:literal $(. $minor:literal $(. $patch:literal)?)?)?
+  |                           ^^^^^^^^^^^^^^
+
+error: no rules expected the token `:`
+ --> ui/available_invalid.rs
+  |
+  |     available!(macos: 1.2);
+  |                     ^ no rules expected this token in macro call
+  |
+  = note: while trying to match sequence start
+
+error: expected expression, found `,`
+ --> ui/available_invalid.rs
+  |
+  |     available!(macos);
+  |     ^^^^^^^^^^^^^^^^^
+  |     |
+  |     expected expression
+  |     while parsing this struct
+  |
+  = note: this error originates in the macro `available` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/crates/test-ui/ui/available_same_os.rs b/crates/test-ui/ui/available_same_os.rs
new file mode 100644
index 000000000..301dbcab9
--- /dev/null
+++ b/crates/test-ui/ui/available_same_os.rs
@@ -0,0 +1,6 @@
+//! Same OS name repeated in the `available!` macro.
+use objc2::available;
+
+fn main() {
+    available!(macos = 1.2, macos = 1.2);
+}
diff --git a/crates/test-ui/ui/available_same_os.stderr b/crates/test-ui/ui/available_same_os.stderr
new file mode 100644
index 000000000..b1cae28de
--- /dev/null
+++ b/crates/test-ui/ui/available_same_os.stderr
@@ -0,0 +1,8 @@
+error[E0062]: field `macos` specified more than once
+ --> ui/available_same_os.rs
+  |
+  |     available!(macos = 1.2, macos = 1.2);
+  |     ------------------------^^^^^-------
+  |     |                       |
+  |     |                       used more than once
+  |     first use of `macos`
diff --git a/crates/test-ui/ui/available_unknown_os.rs b/crates/test-ui/ui/available_unknown_os.rs
new file mode 100644
index 000000000..4c89111a7
--- /dev/null
+++ b/crates/test-ui/ui/available_unknown_os.rs
@@ -0,0 +1,6 @@
+//! Unknown OS name in `available!` macro.
+use objc2::available;
+
+fn main() {
+    available!(unknown = 1.2);
+}
diff --git a/crates/test-ui/ui/available_unknown_os.stderr b/crates/test-ui/ui/available_unknown_os.stderr
new file mode 100644
index 000000000..fae589d05
--- /dev/null
+++ b/crates/test-ui/ui/available_unknown_os.stderr
@@ -0,0 +1,7 @@
+error[E0560]: struct `AvailableVersion` has no field named `unknown`
+ --> ui/available_unknown_os.rs
+  |
+  |     available!(unknown = 1.2);
+  |                ^^^^^^^ `AvailableVersion` does not have this field
+  |
+  = note: all struct fields are already assigned

From 4485634d4e66d7ef5e1b9f54d616f8f78092700c Mon Sep 17 00:00:00 2001
From: Mads Marquart <mads@marquart.dk>
Date: Tue, 8 Oct 2024 20:32:06 +0200
Subject: [PATCH 2/2] Optimize OS version lookup

Use atomics directly instead of the heavy `OnceLock`.
---
 .../objc2/src/__macro_helpers/os_version.rs   |  24 +++
 .../src/__macro_helpers/os_version/apple.rs   |  29 ++-
 .../test_available/expected/apple-aarch64.s   | 175 ++++------------
 .../test_available/expected/apple-armv7s.s    | 190 ++++--------------
 .../test_available/expected/apple-old-x86.s   | 177 ++++------------
 .../test_available/expected/apple-x86.s       | 177 ++++------------
 .../test_available/expected/apple-x86_64.s    | 148 +++-----------
 7 files changed, 223 insertions(+), 697 deletions(-)

diff --git a/crates/objc2/src/__macro_helpers/os_version.rs b/crates/objc2/src/__macro_helpers/os_version.rs
index 0b1655f06..fa7e6474b 100644
--- a/crates/objc2/src/__macro_helpers/os_version.rs
+++ b/crates/objc2/src/__macro_helpers/os_version.rs
@@ -150,6 +150,20 @@ impl OSVersion {
         let (major, minor, patch) = (self.major as u32, self.minor as u32, self.patch as u32);
         (major << 16) | (minor << 8) | patch
     }
+
+    /// Construct the version from a `u32`.
+    #[inline]
+    pub const fn from_u32(version: u32) -> Self {
+        // See comments in `OSVersion`, this should compile down to nothing.
+        let major = (version >> 16) as u16;
+        let minor = (version >> 8) as u8;
+        let patch = version as u8;
+        Self {
+            major,
+            minor,
+            patch,
+        }
+    }
 }
 
 impl PartialEq for OSVersion {
@@ -402,4 +416,14 @@ mod tests {
             assert!(available!(tvos = 1.2, ..));
         }
     }
+
+    #[test]
+    fn test_u32_roundtrip() {
+        let version = OSVersion {
+            major: 1000,
+            minor: 100,
+            patch: 200,
+        };
+        assert_eq!(version, OSVersion::from_u32(version.to_u32()));
+    }
 }
diff --git a/crates/objc2/src/__macro_helpers/os_version/apple.rs b/crates/objc2/src/__macro_helpers/os_version/apple.rs
index f57ef07ed..ef88e7f23 100644
--- a/crates/objc2/src/__macro_helpers/os_version/apple.rs
+++ b/crates/objc2/src/__macro_helpers/os_version/apple.rs
@@ -1,8 +1,9 @@
 use core::ffi::{c_char, c_uint, c_void};
+use core::num::NonZeroU32;
 use core::ptr;
+use core::sync::atomic::{AtomicU32, Ordering};
 use std::os::unix::ffi::OsStrExt;
 use std::path::PathBuf;
-use std::sync::OnceLock;
 
 use super::OSVersion;
 use crate::rc::{autoreleasepool, Allocated, Retained};
@@ -97,14 +98,25 @@ pub(crate) const DEPLOYMENT_TARGET: OSVersion = {
 pub(crate) fn current_version() -> OSVersion {
     // Cache the lookup for performance.
     //
-    // TODO: Maybe just use atomics, a `Once` seems like overkill, it doesn't
-    // matter if two threads end up racing to read the version?
-    static CURRENT_VERSION: OnceLock<OSVersion> = OnceLock::new();
+    // We assume that 0.0.0 is never gonna be a valid version,
+    // and use that as our sentinel value.
+    static CURRENT_VERSION: AtomicU32 = AtomicU32::new(0);
 
-    *CURRENT_VERSION.get_or_init(lookup_version)
+    // We use relaxed atomics, it doesn't matter if two threads end up racing
+    // to read or write the version.
+    let version = CURRENT_VERSION.load(Ordering::Relaxed);
+    OSVersion::from_u32(if version == 0 {
+        // TODO: Consider using `std::panic::abort_unwind` here for code-size?
+        let version = lookup_version().get();
+        CURRENT_VERSION.store(version, Ordering::Relaxed);
+        version
+    } else {
+        version
+    })
 }
 
-fn lookup_version() -> OSVersion {
+#[cold]
+fn lookup_version() -> NonZeroU32 {
     // Since macOS 10.15, libSystem has provided the undocumented
     // `_availability_version_check` via `libxpc` for doing this version
     // lookup, though it's usage may be a bit dangerous, see:
@@ -114,7 +126,10 @@ fn lookup_version() -> OSVersion {
     // So instead, we use the safer approach of reading from `sysctl`, and
     // if that fails, we fall back to the property list (this is what
     // `_availability_version_check` does internally).
-    version_from_sysctl().unwrap_or_else(version_from_plist)
+    let version = version_from_sysctl().unwrap_or_else(version_from_plist);
+    // Use `NonZeroU32` to try to make it clearer to the optimizer that this
+    // will never return 0.
+    NonZeroU32::new(version.to_u32()).expect("version cannot be 0.0.0")
 }
 
 /// Read the version from `kern.osproductversion` or `kern.iossupportversion`.
diff --git a/crates/test-assembly/crates/test_available/expected/apple-aarch64.s b/crates/test-assembly/crates/test_available/expected/apple-aarch64.s
index 4f6719ec8..7491d52cb 100644
--- a/crates/test-assembly/crates/test_available/expected/apple-aarch64.s
+++ b/crates/test-assembly/crates/test_available/expected/apple-aarch64.s
@@ -1,85 +1,4 @@
 	.section	__TEXT,__text,regular,pure_instructions
-	.p2align	2
-SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0):
-Lloh0:
-	adrp	x0, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGE
-Lloh1:
-	ldr	x0, [x0, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGEOFF]
-	ldapr	x8, [x0]
-	cmp	x8, #3
-	b.ne	LBB0_2
-	ret
-LBB0_2:
-	sub	sp, sp, #48
-	stp	x29, x30, [sp, #32]
-	add	x29, sp, #32
-	add	x8, x0, #8
-	sub	x9, x29, #1
-	stp	x8, x9, [sp]
-	mov	x8, sp
-	str	x8, [sp, #16]
-Lloh2:
-	adrp	x3, l_anon.[ID].0@PAGE
-Lloh3:
-	add	x3, x3, l_anon.[ID].0@PAGEOFF
-Lloh4:
-	adrp	x4, l_anon.[ID].2@PAGE
-Lloh5:
-	add	x4, x4, l_anon.[ID].2@PAGEOFF
-	add	x2, sp, #16
-	mov	w1, #1
-	bl	SYM(std::sys::sync::once::queue::Once::call::GENERATED_ID, 0)
-	ldp	x29, x30, [sp, #32]
-	add	sp, sp, #48
-	ret
-	.loh AdrpLdrGot	Lloh0, Lloh1
-	.loh AdrpAdd	Lloh4, Lloh5
-	.loh AdrpAdd	Lloh2, Lloh3
-
-	.p2align	2
-SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0):
-	stp	x20, x19, [sp, #-32]!
-	stp	x29, x30, [sp, #16]
-	add	x29, sp, #16
-	ldr	x8, [x0]
-	ldr	x19, [x8]
-	str	xzr, [x8]
-	cbz	x19, LBB1_2
-	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
-	str	w0, [x19]
-	ldp	x29, x30, [sp, #16]
-	ldp	x20, x19, [sp], #32
-	ret
-LBB1_2:
-Lloh6:
-	adrp	x0, l_anon.[ID].3@PAGE
-Lloh7:
-	add	x0, x0, l_anon.[ID].3@PAGEOFF
-	bl	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
-	.loh AdrpAdd	Lloh6, Lloh7
-
-	.p2align	2
-SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0):
-	stp	x20, x19, [sp, #-32]!
-	stp	x29, x30, [sp, #16]
-	add	x29, sp, #16
-	ldr	x8, [x0]
-	ldr	x19, [x8]
-	str	xzr, [x8]
-	cbz	x19, LBB2_2
-	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
-	str	w0, [x19]
-	ldp	x29, x30, [sp, #16]
-	ldp	x20, x19, [sp], #32
-	ret
-LBB2_2:
-Lloh8:
-	adrp	x0, l_anon.[ID].3@PAGE
-Lloh9:
-	add	x0, x0, l_anon.[ID].3@PAGEOFF
-	bl	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
-	.loh AdrpAdd	Lloh8, Lloh9
-
 	.globl	_always
 	.p2align	2
 _always:
@@ -104,24 +23,24 @@ _high:
 	stp	x20, x19, [sp, #-32]!
 	stp	x29, x30, [sp, #16]
 	add	x29, sp, #16
-Lloh10:
+Lloh0:
 	adrp	x19, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGE
-Lloh11:
+Lloh1:
 	ldr	x19, [x19, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGEOFF]
-	ldapr	x8, [x19]
-	cmp	x8, #3
-	b.ne	LBB6_2
-LBB6_1:
-	ldrh	w8, [x19, #10]
+	ldr	w0, [x19]
+	cbz	w0, LBB3_2
+LBB3_1:
+	lsr	w8, w0, #16
 	cmp	w8, #14
 	cset	w0, hi
 	ldp	x29, x30, [sp, #16]
 	ldp	x20, x19, [sp], #32
 	ret
-LBB6_2:
-	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	b	LBB6_1
-	.loh AdrpLdrGot	Lloh10, Lloh11
+LBB3_2:
+	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	str	w0, [x19]
+	b	LBB3_1
+	.loh AdrpLdrGot	Lloh0, Lloh1
 
 	.globl	_only_ios
 	.p2align	2
@@ -135,56 +54,34 @@ _two_checks:
 	stp	x20, x19, [sp, #-32]!
 	stp	x29, x30, [sp, #16]
 	add	x29, sp, #16
-Lloh12:
-	adrp	x19, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGE
-Lloh13:
-	ldr	x19, [x19, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGEOFF]
-	ldapr	x8, [x19]
-	cmp	x8, #3
-	b.ne	LBB8_3
-	ldrh	w20, [x19, #10]
-	ldapr	x8, [x19]
-	cmp	x8, #3
-	b.ne	LBB8_4
-LBB8_2:
-	cmp	w20, #13
-	ldrh	w8, [x19, #10]
-	ccmp	w8, #14, #0, hi
+Lloh2:
+	adrp	x20, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGE
+Lloh3:
+	ldr	x20, [x20, SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPAGEOFF]
+	ldr	w19, [x20]
+	cbz	w19, LBB5_3
+	ldr	w0, [x20]
+	cbz	w0, LBB5_4
+LBB5_2:
+	lsr	w8, w19, #17
+	cmp	w8, #6
+	mov	w8, #917503
+	add	w8, w8, #16, lsl #12
+	ccmp	w0, w8, #0, hi
 	cset	w0, hi
 	ldp	x29, x30, [sp, #16]
 	ldp	x20, x19, [sp], #32
 	ret
-LBB8_3:
-	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	ldrh	w20, [x19, #10]
-	ldapr	x8, [x19]
-	cmp	x8, #3
-	b.eq	LBB8_2
-LBB8_4:
-	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	b	LBB8_2
-	.loh AdrpLdrGot	Lloh12, Lloh13
-
-	.section	__DATA,__const
-	.p2align	3, 0x0
-l_anon.[ID].0:
-	.asciz	"\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\b\000\000\000\000\000\000"
-	.quad	SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0)
-	.quad	SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0)
-
-	.section	__TEXT,__const
-l_anon.[ID].1:
-	.ascii	"$RUSTC/library/std/src/sync/once.rs"
-
-	.section	__DATA,__const
-	.p2align	3, 0x0
-l_anon.[ID].2:
-	.quad	l_anon.[ID].1
-	.asciz	"p\000\000\000\000\000\000\000\331\000\000\000\024\000\000"
-
-	.p2align	3, 0x0
-l_anon.[ID].3:
-	.quad	l_anon.[ID].1
-	.asciz	"p\000\000\000\000\000\000\000\331\000\000\0001\000\000"
+LBB5_3:
+	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	x19, x0
+	str	w0, [x20]
+	ldr	w0, [x20]
+	cbnz	w0, LBB5_2
+LBB5_4:
+	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	str	w0, [x20]
+	b	LBB5_2
+	.loh AdrpLdrGot	Lloh2, Lloh3
 
 .subsections_via_symbols
diff --git a/crates/test-assembly/crates/test_available/expected/apple-armv7s.s b/crates/test-assembly/crates/test_available/expected/apple-armv7s.s
index 309aafe4f..12bdebc57 100644
--- a/crates/test-assembly/crates/test_available/expected/apple-armv7s.s
+++ b/crates/test-assembly/crates/test_available/expected/apple-armv7s.s
@@ -1,91 +1,5 @@
 	.section	__TEXT,__text,regular,pure_instructions
 	.syntax unified
-	.p2align	2
-	.code	32
-SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0):
-	ldr	r0, LCPI0_0
-LPC0_0:
-	ldr	r0, [pc, r0]
-	ldr	r1, [r0]
-	dmb	ish
-	cmp	r1, #3
-	bxeq	lr
-LBB0_1:
-	push	{r2, r3, r4, r5, r6, r7, lr}
-	add	r7, sp, #20
-	add	r1, r0, #4
-	str	r1, [sp, #4]
-	sub	r1, r7, #1
-	str	r1, [sp, #8]
-	add	r1, sp, #4
-	str	r1, [r7, #-8]
-	ldr	r1, LCPI0_1
-LPC0_1:
-	add	r1, pc, r1
-	ldr	r3, LCPI0_2
-LPC0_2:
-	add	r3, pc, r3
-	str	r1, [sp]
-	sub	r2, r7, #8
-	mov	r1, #1
-	bl	SYM(std::sys::sync::once::queue::Once::call::GENERATED_ID, 0)
-	mov	sp, r7
-	pop	{r7, lr}
-	bx	lr
-	.p2align	2
-	.data_region
-LCPI0_0:
-	.long	LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC0_0+8)
-LCPI0_1:
-	.long	l_anon.[ID].2-(LPC0_1+8)
-LCPI0_2:
-	.long	l_anon.[ID].0-(LPC0_2+8)
-	.end_data_region
-
-	.p2align	2
-	.code	32
-SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0):
-	push	{r4, r7, lr}
-	add	r7, sp, #4
-	ldr	r0, [r0]
-	ldr	r4, [r0]
-	mov	r1, #0
-	str	r1, [r0]
-	cmp	r4, #0
-	beq	LBB1_2
-	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
-	str	r0, [r4]
-	pop	{r4, r7, pc}
-LBB1_2:
-	movw	r0, :lower16:(l_anon.[ID].3-(LPC1_0+8))
-	movt	r0, :upper16:(l_anon.[ID].3-(LPC1_0+8))
-LPC1_0:
-	add	r0, pc, r0
-	mov	lr, pc
-	b	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
-
-	.p2align	2
-	.code	32
-SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0):
-	push	{r4, r7, lr}
-	add	r7, sp, #4
-	ldr	r0, [r0]
-	ldr	r4, [r0]
-	mov	r1, #0
-	str	r1, [r0]
-	cmp	r4, #0
-	beq	LBB2_2
-	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
-	str	r0, [r4]
-	pop	{r4, r7, pc}
-LBB2_2:
-	movw	r0, :lower16:(l_anon.[ID].3-(LPC2_0+8))
-	movt	r0, :upper16:(l_anon.[ID].3-(LPC2_0+8))
-LPC2_0:
-	add	r0, pc, r0
-	mov	lr, pc
-	b	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
-
 	.globl	_always
 	.p2align	2
 	.code	32
@@ -113,23 +27,23 @@ _low:
 _high:
 	push	{r4, r7, lr}
 	add	r7, sp, #4
-	movw	r4, :lower16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC6_0+8))
-	movt	r4, :upper16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC6_0+8))
-LPC6_0:
+	movw	r4, :lower16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC3_0+8))
+	movt	r4, :upper16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC3_0+8))
+LPC3_0:
 	ldr	r4, [pc, r4]
 	ldr	r0, [r4]
-	dmb	ish
-	cmp	r0, #3
-	bne	LBB6_2
-LBB6_1:
-	ldrh	r1, [r4, #6]
+	cmp	r0, #0
+	beq	LBB3_2
+LBB3_1:
+	lsr	r1, r0, #17
 	mov	r0, #0
-	cmp	r1, #17
+	cmp	r1, #8
 	movwhi	r0, #1
 	pop	{r4, r7, pc}
-LBB6_2:
-	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	b	LBB6_1
+LBB3_2:
+	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	str	r0, [r4]
+	b	LBB3_1
 
 	.globl	_only_ios
 	.p2align	2
@@ -144,58 +58,40 @@ _only_ios:
 _two_checks:
 	push	{r4, r5, r7, lr}
 	add	r7, sp, #8
-	movw	r4, :lower16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC8_0+8))
-	movt	r4, :upper16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC8_0+8))
-LPC8_0:
-	ldr	r4, [pc, r4]
-	ldr	r0, [r4]
-	dmb	ish
-	cmp	r0, #3
-	bne	LBB8_3
-LBB8_1:
-	ldrh	r5, [r4, #6]
-	ldr	r0, [r4]
-	dmb	ish
-	cmp	r0, #3
-	bne	LBB8_4
-LBB8_2:
-	mov	r0, #0
-	cmp	r5, #16
+	movw	r5, :lower16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC5_0+8))
+	movt	r5, :upper16:(LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-(LPC5_0+8))
+LPC5_0:
+	ldr	r5, [pc, r5]
+	ldr	r4, [r5]
+	cmp	r4, #0
+	beq	LBB5_3
+	ldr	r0, [r5]
+	cmp	r0, #0
+	beq	LBB5_4
+LBB5_2:
+	lsr	r1, r4, #16
+	mov	r2, #0
+	cmp	r1, #16
 	mov	r1, #0
 	movwhi	r1, #1
-	ldrh	r2, [r4, #6]
-	cmp	r2, #17
-	movwhi	r0, #1
-	and	r0, r1, r0
+	movw	r3, #65535
+	movt	r3, #16
+	orr	r3, r3, #65536
+	cmp	r0, r3
+	movwhi	r2, #1
+	and	r0, r1, r2
 	pop	{r4, r5, r7, pc}
-LBB8_3:
-	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	b	LBB8_1
-LBB8_4:
-	bl	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	b	LBB8_2
-
-	.section	__DATA,__const
-	.p2align	2, 0x0
-l_anon.[ID].0:
-	.asciz	"\000\000\000\000\004\000\000\000\004\000\000"
-	.long	SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0)
-	.long	SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0)
-
-	.section	__TEXT,__const
-l_anon.[ID].1:
-	.ascii	"$RUSTC/library/std/src/sync/once.rs"
-
-	.section	__DATA,__const
-	.p2align	2, 0x0
-l_anon.[ID].2:
-	.long	l_anon.[ID].1
-	.asciz	"p\000\000\000\331\000\000\000\024\000\000"
-
-	.p2align	2, 0x0
-l_anon.[ID].3:
-	.long	l_anon.[ID].1
-	.asciz	"p\000\000\000\331\000\000\0001\000\000"
+LBB5_3:
+	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	r4, r0
+	str	r0, [r5]
+	ldr	r0, [r5]
+	cmp	r0, #0
+	bne	LBB5_2
+LBB5_4:
+	bl	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	str	r0, [r5]
+	b	LBB5_2
 
 	.section	__DATA,__nl_symbol_ptr,non_lazy_symbol_pointers
 	.p2align	2, 0x0
diff --git a/crates/test-assembly/crates/test_available/expected/apple-old-x86.s b/crates/test-assembly/crates/test_available/expected/apple-old-x86.s
index b5cd3c8d3..69fb84aaa 100644
--- a/crates/test-assembly/crates/test_available/expected/apple-old-x86.s
+++ b/crates/test-assembly/crates/test_available/expected/apple-old-x86.s
@@ -1,94 +1,5 @@
 	.section	__TEXT,__text,regular,pure_instructions
 	.intel_syntax noprefix
-SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0):
-	push	ebp
-	mov	ebp, esp
-	push	esi
-	sub	esp, 20
-	call	L0$pb
-L0$pb:
-	pop	ecx
-	mov	eax, dword ptr [ecx + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L0$pb]
-	mov	edx, dword ptr [eax]
-	cmp	edx, 3
-	jne	LBB0_1
-LBB0_2:
-	add	esp, 20
-	pop	esi
-	pop	ebp
-	ret
-LBB0_1:
-	lea	edx, [eax + 4]
-	lea	esi, [ebp - 20]
-	mov	dword ptr [esi], edx
-	lea	edx, [ebp - 5]
-	mov	dword ptr [esi + 4], edx
-	lea	edx, [ebp - 12]
-	mov	dword ptr [edx], esi
-	sub	esp, 12
-	lea	esi, [ecx + l_anon.[ID].2-L0$pb]
-	lea	ecx, [ecx + l_anon.[ID].0-L0$pb]
-	push	esi
-	push	ecx
-	push	edx
-	push	1
-	push	eax
-	call	SYM(std::sys::sync::once::queue::Once::call::GENERATED_ID, 0)
-	add	esp, 32
-	jmp	LBB0_2
-
-	.p2align	4, 0x90
-SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0):
-	push	ebp
-	mov	ebp, esp
-	push	esi
-	push	eax
-	call	L1$pb
-L1$pb:
-	pop	eax
-	mov	ecx, dword ptr [ebp + 8]
-	mov	ecx, dword ptr [ecx]
-	mov	esi, dword ptr [ecx]
-	mov	dword ptr [ecx], 0
-	test	esi, esi
-	je	LBB1_2
-	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
-	mov	dword ptr [esi], eax
-	add	esp, 4
-	pop	esi
-	pop	ebp
-	ret
-LBB1_2:
-	lea	eax, [eax + l_anon.[ID].3-L1$pb]
-	mov	dword ptr [esp], eax
-	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
-
-	.p2align	4, 0x90
-SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0):
-	push	ebp
-	mov	ebp, esp
-	push	esi
-	push	eax
-	call	L2$pb
-L2$pb:
-	pop	eax
-	mov	ecx, dword ptr [ebp + 8]
-	mov	ecx, dword ptr [ecx]
-	mov	esi, dword ptr [ecx]
-	mov	dword ptr [ecx], 0
-	test	esi, esi
-	je	LBB2_2
-	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
-	mov	dword ptr [esi], eax
-	add	esp, 4
-	pop	esi
-	pop	ebp
-	ret
-LBB2_2:
-	lea	eax, [eax + l_anon.[ID].3-L2$pb]
-	mov	dword ptr [esp], eax
-	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
-
 	.globl	_always
 	.p2align	4, 0x90
 _always:
@@ -123,23 +34,24 @@ _high:
 	mov	ebp, esp
 	push	esi
 	push	eax
-	call	L6$pb
-L6$pb:
+	call	L3$pb
+L3$pb:
 	pop	eax
-	mov	esi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L6$pb]
+	mov	esi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L3$pb]
 	mov	eax, dword ptr [esi]
-	cmp	eax, 3
-	jne	LBB6_1
-LBB6_2:
-	cmp	word ptr [esi + 6], 15
+	test	eax, eax
+	je	LBB3_1
+LBB3_2:
+	cmp	eax, 983040
 	setae	al
 	add	esp, 4
 	pop	esi
 	pop	ebp
 	ret
-LBB6_1:
-	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	jmp	LBB6_2
+LBB3_1:
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [esi], eax
+	jmp	LBB3_2
 
 	.globl	_only_ios
 	.p2align	4, 0x90
@@ -157,58 +69,37 @@ _two_checks:
 	mov	ebp, esp
 	push	edi
 	push	esi
-	call	L8$pb
-L8$pb:
+	call	L5$pb
+L5$pb:
 	pop	eax
-	mov	esi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L8$pb]
-	mov	eax, dword ptr [esi]
-	cmp	eax, 3
-	jne	LBB8_1
-	movzx	edi, word ptr [esi + 6]
-	mov	eax, dword ptr [esi]
-	cmp	eax, 3
-	jne	LBB8_3
-LBB8_4:
-	cmp	di, 14
+	mov	edi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L5$pb]
+	mov	esi, dword ptr [edi]
+	test	esi, esi
+	je	LBB5_1
+	mov	eax, dword ptr [edi]
+	test	eax, eax
+	je	LBB5_3
+LBB5_4:
+	cmp	esi, 917504
 	setae	cl
-	cmp	word ptr [esi + 6], 15
+	cmp	eax, 983040
 	setae	al
 	and	al, cl
 	pop	esi
 	pop	edi
 	pop	ebp
 	ret
-LBB8_1:
-	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	movzx	edi, word ptr [esi + 6]
-	mov	eax, dword ptr [esi]
-	cmp	eax, 3
-	je	LBB8_4
-LBB8_3:
-	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	jmp	LBB8_4
-
-	.section	__DATA,__const
-	.p2align	2, 0x0
-l_anon.[ID].0:
-	.asciz	"\000\000\000\000\004\000\000\000\004\000\000"
-	.long	SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0)
-	.long	SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0)
-
-	.section	__TEXT,__const
-l_anon.[ID].1:
-	.ascii	"$RUSTC/library/std/src/sync/once.rs"
-
-	.section	__DATA,__const
-	.p2align	2, 0x0
-l_anon.[ID].2:
-	.long	l_anon.[ID].1
-	.asciz	"p\000\000\000\331\000\000\000\024\000\000"
-
-	.p2align	2, 0x0
-l_anon.[ID].3:
-	.long	l_anon.[ID].1
-	.asciz	"p\000\000\000\331\000\000\0001\000\000"
+LBB5_1:
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	esi, eax
+	mov	dword ptr [edi], eax
+	mov	eax, dword ptr [edi]
+	test	eax, eax
+	jne	LBB5_4
+LBB5_3:
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [edi], eax
+	jmp	LBB5_4
 
 	.section	__IMPORT,__pointers,non_lazy_symbol_pointers
 LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr:
diff --git a/crates/test-assembly/crates/test_available/expected/apple-x86.s b/crates/test-assembly/crates/test_available/expected/apple-x86.s
index eeb248c01..d275f2378 100644
--- a/crates/test-assembly/crates/test_available/expected/apple-x86.s
+++ b/crates/test-assembly/crates/test_available/expected/apple-x86.s
@@ -1,94 +1,5 @@
 	.section	__TEXT,__text,regular,pure_instructions
 	.intel_syntax noprefix
-SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0):
-	push	ebp
-	mov	ebp, esp
-	push	esi
-	sub	esp, 20
-	call	L0$pb
-L0$pb:
-	pop	ecx
-	mov	eax, dword ptr [ecx + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L0$pb]
-	mov	edx, dword ptr [eax]
-	cmp	edx, 3
-	jne	LBB0_1
-LBB0_2:
-	add	esp, 20
-	pop	esi
-	pop	ebp
-	ret
-LBB0_1:
-	lea	edx, [eax + 4]
-	lea	esi, [ebp - 20]
-	mov	dword ptr [esi], edx
-	lea	edx, [ebp - 5]
-	mov	dword ptr [esi + 4], edx
-	lea	edx, [ebp - 12]
-	mov	dword ptr [edx], esi
-	sub	esp, 12
-	lea	esi, [ecx + l_anon.[ID].2-L0$pb]
-	lea	ecx, [ecx + l_anon.[ID].0-L0$pb]
-	push	esi
-	push	ecx
-	push	edx
-	push	1
-	push	eax
-	call	SYM(std::sys::sync::once::queue::Once::call::GENERATED_ID, 0)
-	add	esp, 32
-	jmp	LBB0_2
-
-	.p2align	4, 0x90
-SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0):
-	push	ebp
-	mov	ebp, esp
-	push	esi
-	push	eax
-	call	L1$pb
-L1$pb:
-	pop	eax
-	mov	ecx, dword ptr [ebp + 8]
-	mov	ecx, dword ptr [ecx]
-	mov	esi, dword ptr [ecx]
-	mov	dword ptr [ecx], 0
-	test	esi, esi
-	je	LBB1_2
-	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
-	mov	dword ptr [esi], eax
-	add	esp, 4
-	pop	esi
-	pop	ebp
-	ret
-LBB1_2:
-	lea	eax, [eax + l_anon.[ID].3-L1$pb]
-	mov	dword ptr [esp], eax
-	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
-
-	.p2align	4, 0x90
-SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0):
-	push	ebp
-	mov	ebp, esp
-	push	esi
-	push	eax
-	call	L2$pb
-L2$pb:
-	pop	eax
-	mov	ecx, dword ptr [ebp + 8]
-	mov	ecx, dword ptr [ecx]
-	mov	esi, dword ptr [ecx]
-	mov	dword ptr [ecx], 0
-	test	esi, esi
-	je	LBB2_2
-	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
-	mov	dword ptr [esi], eax
-	add	esp, 4
-	pop	esi
-	pop	ebp
-	ret
-LBB2_2:
-	lea	eax, [eax + l_anon.[ID].3-L2$pb]
-	mov	dword ptr [esp], eax
-	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
-
 	.globl	_always
 	.p2align	4, 0x90
 _always:
@@ -123,23 +34,24 @@ _high:
 	mov	ebp, esp
 	push	esi
 	push	eax
-	call	L6$pb
-L6$pb:
+	call	L3$pb
+L3$pb:
 	pop	eax
-	mov	esi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L6$pb]
+	mov	esi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L3$pb]
 	mov	eax, dword ptr [esi]
-	cmp	eax, 3
-	jne	LBB6_1
-LBB6_2:
-	cmp	word ptr [esi + 6], 18
+	test	eax, eax
+	je	LBB3_1
+LBB3_2:
+	cmp	eax, 1179648
 	setae	al
 	add	esp, 4
 	pop	esi
 	pop	ebp
 	ret
-LBB6_1:
-	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	jmp	LBB6_2
+LBB3_1:
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [esi], eax
+	jmp	LBB3_2
 
 	.globl	_only_ios
 	.p2align	4, 0x90
@@ -157,58 +69,37 @@ _two_checks:
 	mov	ebp, esp
 	push	edi
 	push	esi
-	call	L8$pb
-L8$pb:
+	call	L5$pb
+L5$pb:
 	pop	eax
-	mov	esi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L8$pb]
-	mov	eax, dword ptr [esi]
-	cmp	eax, 3
-	jne	LBB8_1
-	movzx	edi, word ptr [esi + 6]
-	mov	eax, dword ptr [esi]
-	cmp	eax, 3
-	jne	LBB8_3
-LBB8_4:
-	cmp	di, 17
+	mov	edi, dword ptr [eax + LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr-L5$pb]
+	mov	esi, dword ptr [edi]
+	test	esi, esi
+	je	LBB5_1
+	mov	eax, dword ptr [edi]
+	test	eax, eax
+	je	LBB5_3
+LBB5_4:
+	cmp	esi, 1114112
 	setae	cl
-	cmp	word ptr [esi + 6], 18
+	cmp	eax, 1179648
 	setae	al
 	and	al, cl
 	pop	esi
 	pop	edi
 	pop	ebp
 	ret
-LBB8_1:
-	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	movzx	edi, word ptr [esi + 6]
-	mov	eax, dword ptr [esi]
-	cmp	eax, 3
-	je	LBB8_4
-LBB8_3:
-	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	jmp	LBB8_4
-
-	.section	__DATA,__const
-	.p2align	2, 0x0
-l_anon.[ID].0:
-	.asciz	"\000\000\000\000\004\000\000\000\004\000\000"
-	.long	SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0)
-	.long	SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0)
-
-	.section	__TEXT,__const
-l_anon.[ID].1:
-	.ascii	"$RUSTC/library/std/src/sync/once.rs"
-
-	.section	__DATA,__const
-	.p2align	2, 0x0
-l_anon.[ID].2:
-	.long	l_anon.[ID].1
-	.asciz	"p\000\000\000\331\000\000\000\024\000\000"
-
-	.p2align	2, 0x0
-l_anon.[ID].3:
-	.long	l_anon.[ID].1
-	.asciz	"p\000\000\000\331\000\000\0001\000\000"
+LBB5_1:
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	esi, eax
+	mov	dword ptr [edi], eax
+	mov	eax, dword ptr [edi]
+	test	eax, eax
+	jne	LBB5_4
+LBB5_3:
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [edi], eax
+	jmp	LBB5_4
 
 	.section	__IMPORT,__pointers,non_lazy_symbol_pointers
 LSYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)$non_lazy_ptr:
diff --git a/crates/test-assembly/crates/test_available/expected/apple-x86_64.s b/crates/test-assembly/crates/test_available/expected/apple-x86_64.s
index a09c89aff..36c4ee1fe 100644
--- a/crates/test-assembly/crates/test_available/expected/apple-x86_64.s
+++ b/crates/test-assembly/crates/test_available/expected/apple-x86_64.s
@@ -1,73 +1,5 @@
 	.section	__TEXT,__text,regular,pure_instructions
 	.intel_syntax noprefix
-SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0):
-	mov	rdi, qword ptr [rip + SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPCREL]
-	mov	rax, qword ptr [rdi]
-	cmp	rax, 3
-	jne	LBB0_1
-	ret
-LBB0_1:
-	push	rbp
-	mov	rbp, rsp
-	sub	rsp, 32
-	lea	rax, [rdi + 8]
-	lea	rcx, [rbp - 32]
-	mov	qword ptr [rcx], rax
-	lea	rax, [rbp - 1]
-	mov	qword ptr [rcx + 8], rax
-	lea	rdx, [rbp - 16]
-	mov	qword ptr [rdx], rcx
-	lea	rcx, [rip + l_anon.[ID].0]
-	lea	r8, [rip + l_anon.[ID].2]
-	push	1
-	pop	rsi
-	call	SYM(std::sys::sync::once::queue::Once::call::GENERATED_ID, 0)
-	add	rsp, 32
-	pop	rbp
-	ret
-
-	.p2align	4, 0x90
-SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0):
-	push	rbp
-	mov	rbp, rsp
-	push	rbx
-	push	rax
-	mov	rax, qword ptr [rdi]
-	mov	rbx, qword ptr [rax]
-	mov	qword ptr [rax], 0
-	test	rbx, rbx
-	je	LBB1_2
-	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
-	mov	dword ptr [rbx], eax
-	add	rsp, 8
-	pop	rbx
-	pop	rbp
-	ret
-LBB1_2:
-	lea	rdi, [rip + l_anon.[ID].3]
-	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
-
-	.p2align	4, 0x90
-SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0):
-	push	rbp
-	mov	rbp, rsp
-	push	rbx
-	push	rax
-	mov	rax, qword ptr [rdi]
-	mov	rbx, qword ptr [rax]
-	mov	qword ptr [rax], 0
-	test	rbx, rbx
-	je	LBB2_2
-	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
-	mov	dword ptr [rbx], eax
-	add	rsp, 8
-	pop	rbx
-	pop	rbp
-	ret
-LBB2_2:
-	lea	rdi, [rip + l_anon.[ID].3]
-	call	SYM(core::option::unwrap_failed::GENERATED_ID, 0)
-
 	.globl	_always
 	.p2align	4, 0x90
 _always:
@@ -103,19 +35,20 @@ _high:
 	push	rbx
 	push	rax
 	mov	rbx, qword ptr [rip + SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPCREL]
-	mov	rax, qword ptr [rbx]
-	cmp	rax, 3
-	jne	LBB6_1
-LBB6_2:
-	cmp	word ptr [rbx + 10], 15
+	mov	eax, dword ptr [rbx]
+	test	eax, eax
+	je	LBB3_1
+LBB3_2:
+	cmp	eax, 983040
 	setae	al
 	add	rsp, 8
 	pop	rbx
 	pop	rbp
 	ret
-LBB6_1:
-	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	jmp	LBB6_2
+LBB3_1:
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [rbx], eax
+	jmp	LBB3_2
 
 	.globl	_only_ios
 	.p2align	4, 0x90
@@ -133,54 +66,33 @@ _two_checks:
 	mov	rbp, rsp
 	push	r14
 	push	rbx
-	mov	rbx, qword ptr [rip + SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPCREL]
-	mov	rax, qword ptr [rbx]
-	cmp	rax, 3
-	jne	LBB8_1
-	movzx	r14d, word ptr [rbx + 10]
-	mov	rax, qword ptr [rbx]
-	cmp	rax, 3
-	jne	LBB8_3
-LBB8_4:
-	cmp	r14w, 14
+	mov	r14, qword ptr [rip + SYM(objc2::__macro_helpers::os_version::apple::current_version::CURRENT_VERSION::GENERATED_ID, 0)@GOTPCREL]
+	mov	ebx, dword ptr [r14]
+	test	ebx, ebx
+	je	LBB5_1
+	mov	eax, dword ptr [r14]
+	test	eax, eax
+	je	LBB5_3
+LBB5_4:
+	cmp	ebx, 917504
 	setae	cl
-	cmp	word ptr [rbx + 10], 15
+	cmp	eax, 983040
 	setae	al
 	and	al, cl
 	pop	rbx
 	pop	r14
 	pop	rbp
 	ret
-LBB8_1:
-	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	movzx	r14d, word ptr [rbx + 10]
-	mov	rax, qword ptr [rbx]
-	cmp	rax, 3
-	je	LBB8_4
-LBB8_3:
-	call	SYM(<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>, 0)
-	jmp	LBB8_4
-
-	.section	__DATA,__const
-	.p2align	3, 0x0
-l_anon.[ID].0:
-	.asciz	"\000\000\000\000\000\000\000\000\b\000\000\000\000\000\000\000\b\000\000\000\000\000\000"
-	.quad	SYM(<<std[CRATE_ID]::sync::once::Once>::call_once_force<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0)
-	.quad	SYM(<std[CRATE_ID]::sync::once::Once>::call_once_force::<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::initialize<<std[CRATE_ID]::sync::once_lock::OnceLock<objc2[CRATE_ID]::__macro_helpers::os_version::OSVersion>>::get_or_init<objc2[CRATE_ID]::__macro_helpers::os_version::apple::lookup_version>::{closure#0}, !>::{closure#0}>::{closure#0}, 0)
-
-	.section	__TEXT,__const
-l_anon.[ID].1:
-	.ascii	"$RUSTC/library/std/src/sync/once.rs"
-
-	.section	__DATA,__const
-	.p2align	3, 0x0
-l_anon.[ID].2:
-	.quad	l_anon.[ID].1
-	.asciz	"p\000\000\000\000\000\000\000\331\000\000\000\024\000\000"
-
-	.p2align	3, 0x0
-l_anon.[ID].3:
-	.quad	l_anon.[ID].1
-	.asciz	"p\000\000\000\000\000\000\000\331\000\000\0001\000\000"
+LBB5_1:
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	ebx, eax
+	mov	dword ptr [r14], eax
+	mov	eax, dword ptr [r14]
+	test	eax, eax
+	jne	LBB5_4
+LBB5_3:
+	call	SYM(objc2::__macro_helpers::os_version::apple::lookup_version::GENERATED_ID, 0)
+	mov	dword ptr [r14], eax
+	jmp	LBB5_4
 
 .subsections_via_symbols