1
- use core:: mem:: transmute;
2
-
3
1
use float:: Float ;
4
2
5
3
macro_rules! add {
6
4
( $intrinsic: ident: $ty: ty) => {
7
5
/// Returns `a + b`
6
+ #[ allow( unused_parens) ]
8
7
#[ cfg_attr( not( test) , no_mangle) ]
9
8
pub extern fn $intrinsic( a: $ty, b: $ty) -> $ty {
10
9
let bits = <$ty>:: bits( ) as <$ty as Float >:: Int ;
@@ -21,8 +20,8 @@ macro_rules! add {
21
20
let quiet_bit = implicit_bit >> 1 ;
22
21
let qnan_rep = exponent_mask | quiet_bit;
23
22
24
- let mut a_rep = unsafe { transmute :: <_ , <$ty as Float > :: Int > ( a ) } ;
25
- let mut b_rep = unsafe { transmute :: <_ , <$ty as Float > :: Int > ( b ) } ;
23
+ let mut a_rep = a . repr ( ) ;
24
+ let mut b_rep = b . repr ( ) ;
26
25
let a_abs = a_rep & abs_mask;
27
26
let b_abs = b_rep & abs_mask;
28
27
@@ -31,17 +30,17 @@ macro_rules! add {
31
30
b_abs - 1 >= inf_rep - 1 {
32
31
// NaN + anything = qNaN
33
32
if a_abs > inf_rep {
34
- return unsafe { transmute ( transmute :: <_ , < $ty as Float >:: Int > ( a ) | quiet_bit) } ;
33
+ return ( < $ty as Float >:: from_repr ( a_abs | quiet_bit) ) ;
35
34
}
36
35
// anything + NaN = qNaN
37
36
if b_abs > inf_rep {
38
- return unsafe { transmute ( transmute :: <_ , < $ty as Float >:: Int > ( b ) | quiet_bit) } ;
37
+ return ( < $ty as Float >:: from_repr ( b_abs | quiet_bit) ) ;
39
38
}
40
39
41
40
if a_abs == inf_rep {
42
41
// +/-infinity + -/+infinity = qNaN
43
- if unsafe { transmute :: <_ , <$ty as Float > :: Int > ( a ) ^ transmute :: <_ , <$ty as Float > :: Int > ( b ) == sign_bit } {
44
- return unsafe { transmute ( qnan_rep) } ;
42
+ if a . repr ( ) ^ b . repr ( ) == sign_bit {
43
+ return ( <$ty as Float > :: from_repr ( qnan_rep) ) ;
45
44
} else {
46
45
// +/-infinity + anything remaining = +/- infinity
47
46
return a;
@@ -57,7 +56,7 @@ macro_rules! add {
57
56
if a_abs == 0 {
58
57
// but we need to get the sign right for zero + zero
59
58
if b_abs == 0 {
60
- return unsafe { transmute ( transmute :: <_ , < $ty as Float >:: Int > ( a ) & transmute :: <_ , <$ty as Float > :: Int > ( b ) ) } ;
59
+ return ( < $ty as Float >:: from_repr ( a . repr ( ) & b . repr ( ) ) ) ;
61
60
} else {
62
61
return b;
63
62
}
@@ -120,14 +119,17 @@ macro_rules! add {
120
119
if subtraction {
121
120
a_significand -= b_significand;
122
121
// If a == -b, return +zero.
123
- if a_significand == 0 { return unsafe { transmute( 0 as <$ty as Float >:: Int ) } ; }
122
+ if a_significand == 0 {
123
+ return ( <$ty as Float >:: from_repr( 0 ) ) ;
124
+ }
124
125
125
126
// If partial cancellation occured, we need to left-shift the result
126
127
// and adjust the exponent:
127
128
if a_significand < implicit_bit << 3 {
128
- let shift = <<$ty as Float >:: Int >:: leading_zeros( a_significand) - <<$ty as Float >:: Int >:: leading_zeros( implicit_bit << 3 ) ;
129
+ let shift = ( a_significand. leading_zeros( )
130
+ - ( implicit_bit << 3 ) . leading_zeros( ) ) as <$ty as Float >:: Int ;
129
131
a_significand <<= shift;
130
- a_exponent -= shift as <$ty as Float > :: Int ;
132
+ a_exponent -= shift;
131
133
}
132
134
} else /* addition */ {
133
135
a_significand += b_significand;
@@ -142,7 +144,9 @@ macro_rules! add {
142
144
}
143
145
144
146
// If we have overflowed the type, return +/- infinity:
145
- if a_exponent >= max_exponent { return unsafe { transmute( inf_rep | result_sign) } ; }
147
+ if a_exponent >= max_exponent {
148
+ return ( <$ty>:: from_repr( inf_rep | result_sign) ) ;
149
+ }
146
150
147
151
if a_exponent <= 0 {
148
152
// Result is denormal before rounding; the exponent is zero and we
@@ -167,7 +171,7 @@ macro_rules! add {
167
171
// correct result in that case.
168
172
if round_guard_sticky > 0x4 { result += 1 ; }
169
173
if round_guard_sticky == 0x4 { result += result & 1 ; }
170
- return unsafe { transmute ( result) } ;
174
+ return ( <$ty> :: from_repr ( result) ) ;
171
175
}
172
176
}
173
177
}
0 commit comments