Skip to content

Commit

Permalink
Fix ABI for f16 builtins on Intel Apple targets
Browse files Browse the repository at this point in the history
  • Loading branch information
beetrees authored and tgross35 committed Aug 25, 2024
1 parent d78cc8e commit a113c7c
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/float/extend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ intrinsics! {
intrinsics! {
#[avr_skip]
#[aapcs_on_arm]
#[apple_f16_arg_abi]
#[arm_aeabi_alias = __aeabi_h2f]
#[cfg(f16_enabled)]
pub extern "C" fn __extendhfsf2(a: f16) -> f32 {
Expand All @@ -94,6 +95,7 @@ intrinsics! {

#[avr_skip]
#[aapcs_on_arm]
#[apple_f16_arg_abi]
#[cfg(f16_enabled)]
pub extern "C" fn __gnu_h2f_ieee(a: f16) -> f32 {
extend(a)
Expand Down
3 changes: 3 additions & 0 deletions src/float/trunc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ intrinsics! {
intrinsics! {
#[avr_skip]
#[aapcs_on_arm]
#[apple_f16_ret_abi]
#[arm_aeabi_alias = __aeabi_f2h]
#[cfg(f16_enabled)]
pub extern "C" fn __truncsfhf2(a: f32) -> f16 {
Expand All @@ -142,13 +143,15 @@ intrinsics! {

#[avr_skip]
#[aapcs_on_arm]
#[apple_f16_ret_abi]
#[cfg(f16_enabled)]
pub extern "C" fn __gnu_f2h_ieee(a: f32) -> f16 {
trunc(a)
}

#[avr_skip]
#[aapcs_on_arm]
#[apple_f16_ret_abi]
#[arm_aeabi_alias = __aeabi_d2h]
#[cfg(f16_enabled)]
pub extern "C" fn __truncdfhf2(a: f64) -> f16 {
Expand Down
100 changes: 100 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,106 @@ macro_rules! intrinsics {
intrinsics!($($rest)*);
);

// `arm_aeabi_alias` would conflict with `f16_apple_{arg,ret}_abi` not handled here. Avoid macro ambiguity by combining in a
// single `#[]`.
(
#[apple_f16_arg_abi]
#[arm_aeabi_alias = $alias:ident]
$($t:tt)*
) => {
intrinsics! {
#[apple_f16_arg_abi, arm_aeabi_alias = $alias]
$($t)*
}
};
(
#[apple_f16_ret_abi]
#[arm_aeabi_alias = $alias:ident]
$($t:tt)*
) => {
intrinsics! {
#[apple_f16_ret_abi, arm_aeabi_alias = $alias]
$($t)*
}
};

// On x86 (32-bit and 64-bit) Apple platforms, `f16` is passed and returned like a `u16` unless
// the builtin involves `f128`.
(
// `arm_aeabi_alias` would conflict if not handled here. Avoid macro ambiguity by combining
// in a single `#[]`.
#[apple_f16_arg_abi $(, arm_aeabi_alias = $alias:ident)?]
$(#[$($attr:tt)*])*
pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) $(-> $ret:ty)? {
$($body:tt)*
}

$($rest:tt)*
) => (
#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64")))]
$(#[$($attr)*])*
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
$($body)*
}

#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"), not(feature = "mangled-names")))]
mod $name {
#[no_mangle]
#[cfg_attr(not(all(windows, target_env = "gnu")), linkage = "weak")]
$(#[$($attr)*])*
extern $abi fn $name( $($argname: u16),* ) $(-> $ret)? {
super::$name($(f16::from_bits($argname)),*)
}
}

#[cfg(not(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"))))]
intrinsics! {
$(#[arm_aeabi_alias = $alias])?
$(#[$($attr)*])*
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
$($body)*
}
}

intrinsics!($($rest)*);
);
(
#[apple_f16_ret_abi $(, arm_aeabi_alias = $alias:ident)?]
$(#[$($attr:tt)*])*
pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) $(-> $ret:ty)? {
$($body:tt)*
}

$($rest:tt)*
) => (
#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64")))]
$(#[$($attr)*])*
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
$($body)*
}

#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"), not(feature = "mangled-names")))]
mod $name {
#[no_mangle]
#[cfg_attr(not(all(windows, target_env = "gnu")), linkage = "weak")]
$(#[$($attr)*])*
extern $abi fn $name( $($argname: $ty),* ) -> u16 {
super::$name($($argname),*).to_bits()
}
}

#[cfg(not(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"))))]
intrinsics! {
$(#[arm_aeabi_alias = $alias])?
$(#[$($attr)*])*
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
$($body)*
}
}

intrinsics!($($rest)*);
);

// A bunch of intrinsics on ARM are aliased in the standard compiler-rt
// build under `__aeabi_*` aliases, and LLVM will call these instead of the
// original function. The aliasing here is used to generate these symbols in
Expand Down

0 comments on commit a113c7c

Please sign in to comment.