compiler_builtins/float/
extend.rs1use crate::float::Float;
2use crate::int::{CastInto, Int, MinInt};
3
4fn extend<F: Float, R: Float>(a: F) -> R
6where
7 F::Int: CastInto<u64>,
8 u64: CastInto<F::Int>,
9 u32: CastInto<R::Int>,
10 R::Int: CastInto<u32>,
11 R::Int: CastInto<u64>,
12 u64: CastInto<R::Int>,
13 F::Int: CastInto<R::Int>,
14{
15 let src_zero = F::Int::ZERO;
16 let src_one = F::Int::ONE;
17 let src_bits = F::BITS;
18 let src_sig_bits = F::SIG_BITS;
19 let src_exp_bias = F::EXP_BIAS;
20 let src_min_normal = F::IMPLICIT_BIT;
21 let src_infinity = F::EXP_MASK;
22 let src_sign_mask = F::SIGN_MASK;
23 let src_abs_mask = src_sign_mask - src_one;
24 let src_qnan = F::SIG_MASK;
25 let src_nan_code = src_qnan - src_one;
26
27 let dst_bits = R::BITS;
28 let dst_sig_bits = R::SIG_BITS;
29 let dst_inf_exp = R::EXP_SAT;
30 let dst_exp_bias = R::EXP_BIAS;
31 let dst_min_normal = R::IMPLICIT_BIT;
32
33 let sig_bits_delta = dst_sig_bits - src_sig_bits;
34 let exp_bias_delta = dst_exp_bias - src_exp_bias;
35 let a_abs = a.to_bits() & src_abs_mask;
36 let mut abs_result = R::Int::ZERO;
37
38 if a_abs.wrapping_sub(src_min_normal) < src_infinity.wrapping_sub(src_min_normal) {
39 let abs_dst: R::Int = a_abs.cast();
43 let bias_dst: R::Int = exp_bias_delta.cast();
44 abs_result = abs_dst.wrapping_shl(sig_bits_delta);
45 abs_result += bias_dst.wrapping_shl(dst_sig_bits);
46 } else if a_abs >= src_infinity {
47 let qnan_dst: R::Int = (a_abs & src_qnan).cast();
52 let nan_code_dst: R::Int = (a_abs & src_nan_code).cast();
53 let inf_exp_dst: R::Int = dst_inf_exp.cast();
54 abs_result = inf_exp_dst.wrapping_shl(dst_sig_bits);
55 abs_result |= qnan_dst.wrapping_shl(sig_bits_delta);
56 abs_result |= nan_code_dst.wrapping_shl(sig_bits_delta);
57 } else if a_abs != src_zero {
58 let scale = a_abs.leading_zeros() - src_min_normal.leading_zeros();
62 let abs_dst: R::Int = a_abs.cast();
63 let bias_dst: R::Int = (exp_bias_delta - scale + 1).cast();
64 abs_result = abs_dst.wrapping_shl(sig_bits_delta + scale);
65 abs_result = (abs_result ^ dst_min_normal) | (bias_dst.wrapping_shl(dst_sig_bits));
66 }
67
68 let sign_result: R::Int = (a.to_bits() & src_sign_mask).cast();
69 R::from_bits(abs_result | (sign_result.wrapping_shl(dst_bits - src_bits)))
70}
71
72intrinsics! {
73 #[aapcs_on_arm]
74 #[arm_aeabi_alias = __aeabi_f2d]
75 pub extern "C" fn __extendsfdf2(a: f32) -> f64 {
76 extend(a)
77 }
78}
79
80intrinsics! {
81 #[aapcs_on_arm]
82 #[apple_f16_arg_abi]
83 #[arm_aeabi_alias = __aeabi_h2f]
84 #[cfg(f16_enabled)]
85 pub extern "C" fn __extendhfsf2(a: f16) -> f32 {
86 extend(a)
87 }
88
89 #[aapcs_on_arm]
90 #[apple_f16_arg_abi]
91 #[cfg(f16_enabled)]
92 pub extern "C" fn __gnu_h2f_ieee(a: f16) -> f32 {
93 extend(a)
94 }
95
96 #[aapcs_on_arm]
97 #[apple_f16_arg_abi]
98 #[cfg(f16_enabled)]
99 pub extern "C" fn __extendhfdf2(a: f16) -> f64 {
100 extend(a)
101 }
102
103 #[aapcs_on_arm]
104 #[ppc_alias = __extendhfkf2]
105 #[cfg(all(f16_enabled, f128_enabled))]
106 pub extern "C" fn __extendhftf2(a: f16) -> f128 {
107 extend(a)
108 }
109
110 #[aapcs_on_arm]
111 #[ppc_alias = __extendsfkf2]
112 #[cfg(f128_enabled)]
113 pub extern "C" fn __extendsftf2(a: f32) -> f128 {
114 extend(a)
115 }
116
117 #[aapcs_on_arm]
118 #[ppc_alias = __extenddfkf2]
119 #[cfg(f128_enabled)]
120 pub extern "C" fn __extenddftf2(a: f64) -> f128 {
121 extend(a)
122 }
123}