]>
git.proxmox.com Git - rustc.git/blob - src/libcompiler_builtins/src/float/mul.rs
1 use int
::{CastInto, Int, WideInt}
;
4 fn mul
<F
: Float
>(a
: F
, b
: F
) -> F
12 let one
= F
::Int
::ONE
;
13 let zero
= F
::Int
::ZERO
;
16 let significand_bits
= F
::SIGNIFICAND_BITS
;
17 let max_exponent
= F
::EXPONENT_MAX
;
19 let exponent_bias
= F
::EXPONENT_BIAS
;
21 let implicit_bit
= F
::IMPLICIT_BIT
;
22 let significand_mask
= F
::SIGNIFICAND_MASK
;
23 let sign_bit
= F
::SIGN_MASK
as F
::Int
;
24 let abs_mask
= sign_bit
- one
;
25 let exponent_mask
= F
::EXPONENT_MASK
;
26 let inf_rep
= exponent_mask
;
27 let quiet_bit
= implicit_bit
>> 1;
28 let qnan_rep
= exponent_mask
| quiet_bit
;
29 let exponent_bits
= F
::EXPONENT_BITS
;
34 let a_exponent
= (a_rep
>> significand_bits
) & max_exponent
.cast();
35 let b_exponent
= (b_rep
>> significand_bits
) & max_exponent
.cast();
36 let product_sign
= (a_rep ^ b_rep
) & sign_bit
;
38 let mut a_significand
= a_rep
& significand_mask
;
39 let mut b_significand
= b_rep
& significand_mask
;
42 // Detect if a or b is zero, denormal, infinity, or NaN.
43 if a_exponent
.wrapping_sub(one
) >= (max_exponent
- 1).cast()
44 || b_exponent
.wrapping_sub(one
) >= (max_exponent
- 1).cast()
46 let a_abs
= a_rep
& abs_mask
;
47 let b_abs
= b_rep
& abs_mask
;
49 // NaN + anything = qNaN
51 return F
::from_repr(a_rep
| quiet_bit
);
53 // anything + NaN = qNaN
55 return F
::from_repr(b_rep
| quiet_bit
);
60 // infinity * non-zero = +/- infinity
61 return F
::from_repr(a_abs
| product_sign
);
63 // infinity * zero = NaN
64 return F
::from_repr(qnan_rep
);
70 // infinity * non-zero = +/- infinity
71 return F
::from_repr(b_abs
| product_sign
);
73 // infinity * zero = NaN
74 return F
::from_repr(qnan_rep
);
78 // zero * anything = +/- zero
80 return F
::from_repr(product_sign
);
83 // anything * zero = +/- zero
85 return F
::from_repr(product_sign
);
88 // one or both of a or b is denormal, the other (if applicable) is a
89 // normal number. Renormalize one or both of a and b, and set scale to
90 // include the necessary exponent adjustment.
91 if a_abs
< implicit_bit
{
92 let (exponent
, significand
) = F
::normalize(a_significand
);
94 a_significand
= significand
;
97 if b_abs
< implicit_bit
{
98 let (exponent
, significand
) = F
::normalize(b_significand
);
100 b_significand
= significand
;
104 // Or in the implicit significand bit. (If we fell through from the
105 // denormal path it was already set by normalize( ), but setting it twice
106 // won't hurt anything.)
107 a_significand
|= implicit_bit
;
108 b_significand
|= implicit_bit
;
110 // Get the significand of a*b. Before multiplying the significands, shift
111 // one of them left to left-align it in the field. Thus, the product will
112 // have (exponentBits + 2) integral digits, all but two of which must be
113 // zero. Normalizing this result is just a conditional left-shift by one
114 // and bumping the exponent accordingly.
115 let (mut product_high
, mut product_low
) =
116 <F
::Int
as WideInt
>::wide_mul(a_significand
, b_significand
<< exponent_bits
);
118 let a_exponent_i32
: i32 = a_exponent
.cast();
119 let b_exponent_i32
: i32 = b_exponent
.cast();
120 let mut product_exponent
: i32 = a_exponent_i32
121 .wrapping_add(b_exponent_i32
)
123 .wrapping_sub(exponent_bias
as i32);
125 // Normalize the significand, adjust exponent if needed.
126 if (product_high
& implicit_bit
) != zero
{
127 product_exponent
= product_exponent
.wrapping_add(1);
129 <F
::Int
as WideInt
>::wide_shift_left(&mut product_high
, &mut product_low
, 1);
132 // If we have overflowed the type, return +/- infinity.
133 if product_exponent
>= max_exponent
as i32 {
134 return F
::from_repr(inf_rep
| product_sign
);
137 if product_exponent
<= 0 {
138 // Result is denormal before rounding
140 // If the result is so small that it just underflows to zero, return
141 // a zero of the appropriate sign. Mathematically there is no need to
142 // handle this case separately, but we make it a special case to
143 // simplify the shift logic.
144 let shift
= one
.wrapping_sub(product_exponent
.cast()).cast();
145 if shift
>= bits
as i32 {
146 return F
::from_repr(product_sign
);
149 // Otherwise, shift the significand of the result so that the round
150 // bit is the high bit of productLo.
151 <F
::Int
as WideInt
>::wide_shift_right_with_sticky(
157 // Result is normal before rounding; insert the exponent.
158 product_high
&= significand_mask
;
159 product_high
|= product_exponent
.cast() << significand_bits
;
162 // Insert the sign of the result:
163 product_high
|= product_sign
;
165 // Final rounding. The final result may overflow to infinity, or underflow
166 // to zero, but those are the correct results in those cases. We use the
167 // default IEEE-754 round-to-nearest, ties-to-even rounding mode.
168 if product_low
> sign_bit
{
172 if product_low
== sign_bit
{
173 product_high
+= product_high
& one
;
176 return F
::from_repr(product_high
);
181 #[arm_aeabi_alias = __aeabi_fmul]
182 pub extern "C" fn __mulsf3(a
: f32, b
: f32) -> f32 {
187 #[arm_aeabi_alias = __aeabi_dmul]
188 pub extern "C" fn __muldf3(a
: f64, b
: f64) -> f64 {
192 #[cfg(target_arch = "arm")]
193 pub extern "C" fn __mulsf3vfp(a
: f32, b
: f32) -> f32 {
197 #[cfg(target_arch = "arm")]
198 pub extern "C" fn __muldf3vfp(a
: f64, b
: f64) -> f64 {