Fix ABI for f16 builtins on Intel Apple targets
This commit is contained in:
parent
569a93bc03
commit
a17a15b08a
3 changed files with 105 additions and 0 deletions
|
|
@ -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 {
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -142,6 +143,7 @@ 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)
|
||||
|
|
@ -149,6 +151,7 @@ intrinsics! {
|
|||
|
||||
#[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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue