Skip to content

Commit 3460ed6

Browse files
committed
Use float conversion operations from floatconv.
1 parent f4c7940 commit 3460ed6

File tree

3 files changed

+25
-198
lines changed

3 files changed

+25
-198
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ test = false
3030
# For more information on this dependency see rust-lang/rust's
3131
# `src/tools/rustc-std-workspace` folder
3232
core = { version = "1.0.0", optional = true, package = 'rustc-std-workspace-core' }
33+
floatconv = "0.2.8"
3334

3435
[build-dependencies]
3536
cc = { optional = true, version = "1.0" }

build.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,6 @@ mod c {
264264
if target_env == "msvc" {
265265
if target_arch == "x86_64" {
266266
sources.extend(&[
267-
("__floatdisf", "x86_64/floatdisf.c"),
268267
("__floatdixf", "x86_64/floatdixf.c"),
269268
]);
270269
}
@@ -274,10 +273,7 @@ mod c {
274273
if target_os != "windows" {
275274
if target_arch == "x86_64" {
276275
sources.extend(&[
277-
("__floatdisf", "x86_64/floatdisf.c"),
278276
("__floatdixf", "x86_64/floatdixf.c"),
279-
("__floatundidf", "x86_64/floatundidf.S"),
280-
("__floatundisf", "x86_64/floatundisf.S"),
281277
("__floatundixf", "x86_64/floatundixf.S"),
282278
]);
283279
}
@@ -288,11 +284,7 @@ mod c {
288284
("__ashldi3", "i386/ashldi3.S"),
289285
("__ashrdi3", "i386/ashrdi3.S"),
290286
("__divdi3", "i386/divdi3.S"),
291-
("__floatdidf", "i386/floatdidf.S"),
292-
("__floatdisf", "i386/floatdisf.S"),
293287
("__floatdixf", "i386/floatdixf.S"),
294-
("__floatundidf", "i386/floatundidf.S"),
295-
("__floatundisf", "i386/floatundisf.S"),
296288
("__floatundixf", "i386/floatundixf.S"),
297289
("__lshrdi3", "i386/lshrdi3.S"),
298290
("__moddi3", "i386/moddi3.S"),

src/float/conv.rs

Lines changed: 24 additions & 190 deletions
Original file line numberDiff line numberDiff line change
@@ -1,287 +1,121 @@
1-
use float::Float;
2-
use int::Int;
3-
4-
macro_rules! int_to_float {
5-
($i:expr, $ity:ty, $fty:ty) => {{
6-
let i = $i;
7-
if i == 0 {
8-
return 0.0;
9-
}
10-
11-
let mant_dig = <$fty>::SIGNIFICAND_BITS + 1;
12-
let exponent_bias = <$fty>::EXPONENT_BIAS;
13-
14-
let n = <$ity>::BITS;
15-
let (s, a) = i.extract_sign();
16-
let mut a = a;
17-
18-
// number of significant digits
19-
let sd = n - a.leading_zeros();
20-
21-
// exponent
22-
let mut e = sd - 1;
23-
24-
if <$ity>::BITS < mant_dig {
25-
return <$fty>::from_parts(
26-
s,
27-
(e + exponent_bias) as <$fty as Float>::Int,
28-
(a as <$fty as Float>::Int) << (mant_dig - e - 1),
29-
);
30-
}
31-
32-
a = if sd > mant_dig {
33-
/* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
34-
* finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
35-
* 12345678901234567890123456
36-
* 1 = msb 1 bit
37-
* P = bit MANT_DIG-1 bits to the right of 1
38-
* Q = bit MANT_DIG bits to the right of 1
39-
* R = "or" of all bits to the right of Q
40-
*/
41-
let mant_dig_plus_one = mant_dig + 1;
42-
let mant_dig_plus_two = mant_dig + 2;
43-
a = if sd == mant_dig_plus_one {
44-
a << 1
45-
} else if sd == mant_dig_plus_two {
46-
a
47-
} else {
48-
(a >> (sd - mant_dig_plus_two)) as <$ity as Int>::UnsignedInt
49-
| ((a & <$ity as Int>::UnsignedInt::max_value())
50-
.wrapping_shl((n + mant_dig_plus_two) - sd)
51-
!= 0) as <$ity as Int>::UnsignedInt
52-
};
53-
54-
/* finish: */
55-
a |= ((a & 4) != 0) as <$ity as Int>::UnsignedInt; /* Or P into R */
56-
a += 1; /* round - this step may add a significant bit */
57-
a >>= 2; /* dump Q and R */
58-
59-
/* a is now rounded to mant_dig or mant_dig+1 bits */
60-
if (a & (1 << mant_dig)) != 0 {
61-
a >>= 1;
62-
e += 1;
63-
}
64-
a
65-
/* a is now rounded to mant_dig bits */
66-
} else {
67-
a.wrapping_shl(mant_dig - sd)
68-
/* a is now rounded to mant_dig bits */
69-
};
70-
71-
<$fty>::from_parts(
72-
s,
73-
(e + exponent_bias) as <$fty as Float>::Int,
74-
a as <$fty as Float>::Int,
75-
)
76-
}};
77-
}
78-
791
intrinsics! {
802
#[arm_aeabi_alias = __aeabi_i2f]
813
pub extern "C" fn __floatsisf(i: i32) -> f32 {
82-
int_to_float!(i, i32, f32)
4+
floatconv::fast::i32_to_f32_round(i)
835
}
846

857
#[arm_aeabi_alias = __aeabi_i2d]
868
pub extern "C" fn __floatsidf(i: i32) -> f64 {
87-
int_to_float!(i, i32, f64)
9+
floatconv::fast::i32_to_f64(i)
8810
}
8911

90-
#[maybe_use_optimized_c_shim]
9112
#[arm_aeabi_alias = __aeabi_l2f]
9213
pub extern "C" fn __floatdisf(i: i64) -> f32 {
93-
// On x86_64 LLVM will use native instructions for this conversion, we
94-
// can just do it directly
95-
if cfg!(target_arch = "x86_64") {
96-
i as f32
97-
} else {
98-
int_to_float!(i, i64, f32)
99-
}
14+
floatconv::fast::i64_to_f32_round(i)
10015
}
10116

102-
#[maybe_use_optimized_c_shim]
10317
#[arm_aeabi_alias = __aeabi_l2d]
10418
pub extern "C" fn __floatdidf(i: i64) -> f64 {
105-
// On x86_64 LLVM will use native instructions for this conversion, we
106-
// can just do it directly
107-
if cfg!(target_arch = "x86_64") {
108-
i as f64
109-
} else {
110-
int_to_float!(i, i64, f64)
111-
}
19+
floatconv::fast::i64_to_f64_round(i)
11220
}
11321

11422
#[unadjusted_on_win64]
11523
pub extern "C" fn __floattisf(i: i128) -> f32 {
116-
int_to_float!(i, i128, f32)
24+
floatconv::fast::i128_to_f32_round(i)
11725
}
11826

11927
#[unadjusted_on_win64]
12028
pub extern "C" fn __floattidf(i: i128) -> f64 {
121-
int_to_float!(i, i128, f64)
29+
floatconv::fast::i128_to_f64_round(i)
12230
}
12331

12432
#[arm_aeabi_alias = __aeabi_ui2f]
12533
pub extern "C" fn __floatunsisf(i: u32) -> f32 {
126-
int_to_float!(i, u32, f32)
34+
floatconv::fast::u32_to_f32_round(i)
12735
}
12836

12937
#[arm_aeabi_alias = __aeabi_ui2d]
13038
pub extern "C" fn __floatunsidf(i: u32) -> f64 {
131-
int_to_float!(i, u32, f64)
39+
floatconv::fast::u32_to_f64(i)
13240
}
13341

134-
#[maybe_use_optimized_c_shim]
13542
#[arm_aeabi_alias = __aeabi_ul2f]
13643
pub extern "C" fn __floatundisf(i: u64) -> f32 {
137-
int_to_float!(i, u64, f32)
44+
floatconv::fast::u64_to_f32_round(i)
13845
}
13946

140-
#[maybe_use_optimized_c_shim]
14147
#[arm_aeabi_alias = __aeabi_ul2d]
14248
pub extern "C" fn __floatundidf(i: u64) -> f64 {
143-
int_to_float!(i, u64, f64)
49+
floatconv::fast::u64_to_f64_round(i)
14450
}
14551

14652
#[unadjusted_on_win64]
14753
pub extern "C" fn __floatuntisf(i: u128) -> f32 {
148-
int_to_float!(i, u128, f32)
54+
floatconv::fast::u128_to_f32_round(i)
14955
}
15056

15157
#[unadjusted_on_win64]
15258
pub extern "C" fn __floatuntidf(i: u128) -> f64 {
153-
int_to_float!(i, u128, f64)
59+
floatconv::fast::u128_to_f64_round(i)
15460
}
155-
}
156-
157-
#[derive(PartialEq)]
158-
enum Sign {
159-
Positive,
160-
Negative,
161-
}
162-
163-
macro_rules! float_to_int {
164-
($f:expr, $fty:ty, $ity:ty) => {{
165-
let f = $f;
166-
let fixint_min = <$ity>::min_value();
167-
let fixint_max = <$ity>::max_value();
168-
let fixint_bits = <$ity>::BITS as usize;
169-
let fixint_unsigned = fixint_min == 0;
170-
171-
let sign_bit = <$fty>::SIGN_MASK;
172-
let significand_bits = <$fty>::SIGNIFICAND_BITS as usize;
173-
let exponent_bias = <$fty>::EXPONENT_BIAS as usize;
174-
//let exponent_max = <$fty>::exponent_max() as usize;
175-
176-
// Break a into sign, exponent, significand
177-
let a_rep = <$fty>::repr(f);
178-
let a_abs = a_rep & !sign_bit;
17961

180-
// this is used to work around -1 not being available for unsigned
181-
let sign = if (a_rep & sign_bit) == 0 {
182-
Sign::Positive
183-
} else {
184-
Sign::Negative
185-
};
186-
let mut exponent = (a_abs >> significand_bits) as usize;
187-
let significand = (a_abs & <$fty>::SIGNIFICAND_MASK) | <$fty>::IMPLICIT_BIT;
188-
189-
// if < 1 or unsigned & negative
190-
if exponent < exponent_bias || fixint_unsigned && sign == Sign::Negative {
191-
return 0;
192-
}
193-
exponent -= exponent_bias;
194-
195-
// If the value is infinity, saturate.
196-
// If the value is too large for the integer type, 0.
197-
if exponent
198-
>= (if fixint_unsigned {
199-
fixint_bits
200-
} else {
201-
fixint_bits - 1
202-
})
203-
{
204-
return if sign == Sign::Positive {
205-
fixint_max
206-
} else {
207-
fixint_min
208-
};
209-
}
210-
// If 0 <= exponent < significand_bits, right shift to get the result.
211-
// Otherwise, shift left.
212-
// (sign - 1) will never overflow as negative signs are already returned as 0 for unsigned
213-
let r = if exponent < significand_bits {
214-
(significand >> (significand_bits - exponent)) as $ity
215-
} else {
216-
(significand as $ity) << (exponent - significand_bits)
217-
};
218-
219-
if sign == Sign::Negative {
220-
(!r).wrapping_add(1)
221-
} else {
222-
r
223-
}
224-
}};
225-
}
226-
227-
intrinsics! {
22862
#[arm_aeabi_alias = __aeabi_f2iz]
22963
pub extern "C" fn __fixsfsi(f: f32) -> i32 {
230-
float_to_int!(f, f32, i32)
64+
floatconv::fast::f32_to_i32(f)
23165
}
23266

23367
#[arm_aeabi_alias = __aeabi_f2lz]
23468
pub extern "C" fn __fixsfdi(f: f32) -> i64 {
235-
float_to_int!(f, f32, i64)
69+
floatconv::fast::f32_to_i64(f)
23670
}
23771

23872
#[unadjusted_on_win64]
23973
pub extern "C" fn __fixsfti(f: f32) -> i128 {
240-
float_to_int!(f, f32, i128)
74+
floatconv::fast::f32_to_i128(f)
24175
}
24276

24377
#[arm_aeabi_alias = __aeabi_d2iz]
24478
pub extern "C" fn __fixdfsi(f: f64) -> i32 {
245-
float_to_int!(f, f64, i32)
79+
floatconv::fast::f64_to_i32(f)
24680
}
24781

24882
#[arm_aeabi_alias = __aeabi_d2lz]
24983
pub extern "C" fn __fixdfdi(f: f64) -> i64 {
250-
float_to_int!(f, f64, i64)
84+
floatconv::fast::f64_to_i64(f)
25185
}
25286

25387
#[unadjusted_on_win64]
25488
pub extern "C" fn __fixdfti(f: f64) -> i128 {
255-
float_to_int!(f, f64, i128)
89+
floatconv::fast::f64_to_i128(f)
25690
}
25791

25892
#[arm_aeabi_alias = __aeabi_f2uiz]
25993
pub extern "C" fn __fixunssfsi(f: f32) -> u32 {
260-
float_to_int!(f, f32, u32)
94+
floatconv::fast::f32_to_u32(f)
26195
}
26296

26397
#[arm_aeabi_alias = __aeabi_f2ulz]
26498
pub extern "C" fn __fixunssfdi(f: f32) -> u64 {
265-
float_to_int!(f, f32, u64)
99+
floatconv::fast::f32_to_u64(f)
266100
}
267101

268102
#[unadjusted_on_win64]
269103
pub extern "C" fn __fixunssfti(f: f32) -> u128 {
270-
float_to_int!(f, f32, u128)
104+
floatconv::fast::f32_to_u128(f)
271105
}
272106

273107
#[arm_aeabi_alias = __aeabi_d2uiz]
274108
pub extern "C" fn __fixunsdfsi(f: f64) -> u32 {
275-
float_to_int!(f, f64, u32)
109+
floatconv::fast::f64_to_u32(f)
276110
}
277111

278112
#[arm_aeabi_alias = __aeabi_d2ulz]
279113
pub extern "C" fn __fixunsdfdi(f: f64) -> u64 {
280-
float_to_int!(f, f64, u64)
114+
floatconv::fast::f64_to_u64(f)
281115
}
282116

283117
#[unadjusted_on_win64]
284118
pub extern "C" fn __fixunsdfti(f: f64) -> u128 {
285-
float_to_int!(f, f64, u128)
119+
floatconv::fast::f64_to_u128(f)
286120
}
287121
}

0 commit comments

Comments
 (0)