Skip to content

Commit 0c317ce

Browse files
committed
libm: Add frexpf128 and ilogbf128
The `f16` versions are added but left unimplemented, to make traits easier.
1 parent 700d744 commit 0c317ce

File tree

11 files changed

+201
-39
lines changed

11 files changed

+201
-39
lines changed

crates/libm-macros/src/shared.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,17 @@ const ALL_OPERATIONS_NESTED: &[NestedOp] = &[
279279
fn_list: &["fmaf128"],
280280
public: true,
281281
},
282+
NestedOp {
283+
// `(f16) -> i32`
284+
float_ty: FloatTy::F16,
285+
rust_sig: Signature {
286+
args: &[Ty::F16],
287+
returns: &[Ty::I32],
288+
},
289+
c_sig: None,
290+
fn_list: &["ilogbf16"],
291+
public: true,
292+
},
282293
NestedOp {
283294
// `(f32) -> i32`
284295
float_ty: FloatTy::F32,
@@ -301,6 +312,17 @@ const ALL_OPERATIONS_NESTED: &[NestedOp] = &[
301312
fn_list: &["ilogb"],
302313
public: true,
303314
},
315+
NestedOp {
316+
// `(f128) -> i32`
317+
float_ty: FloatTy::F128,
318+
rust_sig: Signature {
319+
args: &[Ty::F128],
320+
returns: &[Ty::I32],
321+
},
322+
c_sig: None,
323+
fn_list: &["ilogbf128"],
324+
public: true,
325+
},
304326
NestedOp {
305327
// `(i32, f32) -> f32`
306328
float_ty: FloatTy::F32,
@@ -395,6 +417,20 @@ const ALL_OPERATIONS_NESTED: &[NestedOp] = &[
395417
fn_list: &["modf"],
396418
public: true,
397419
},
420+
NestedOp {
421+
// `(f16, &mut c_int) -> f16` as `(f16) -> (f16, i32)`
422+
float_ty: FloatTy::F16,
423+
rust_sig: Signature {
424+
args: &[Ty::F16],
425+
returns: &[Ty::F16, Ty::I32],
426+
},
427+
c_sig: Some(Signature {
428+
args: &[Ty::F16, Ty::MutCInt],
429+
returns: &[Ty::F16],
430+
}),
431+
fn_list: &["frexpf16"],
432+
public: true,
433+
},
398434
NestedOp {
399435
// `(f32, &mut c_int) -> f32` as `(f32) -> (f32, i32)`
400436
float_ty: FloatTy::F32,
@@ -423,6 +459,20 @@ const ALL_OPERATIONS_NESTED: &[NestedOp] = &[
423459
fn_list: &["frexp", "lgamma_r"],
424460
public: true,
425461
},
462+
NestedOp {
463+
// `(f128, &mut c_int) -> f128` as `(f128) -> (f128, i32)`
464+
float_ty: FloatTy::F128,
465+
rust_sig: Signature {
466+
args: &[Ty::F128],
467+
returns: &[Ty::F128, Ty::I32],
468+
},
469+
c_sig: Some(Signature {
470+
args: &[Ty::F128, Ty::MutCInt],
471+
returns: &[Ty::F128],
472+
}),
473+
fn_list: &["frexpf128"],
474+
public: true,
475+
},
426476
NestedOp {
427477
// `(f32, f32, &mut c_int) -> f32` as `(f32, f32) -> (f32, i32)`
428478
float_ty: FloatTy::F32,

etc/function-definitions.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,20 @@
572572
],
573573
"type": "f32"
574574
},
575+
"frexpf128": {
576+
"sources": [
577+
"libm/src/math/frexp.rs",
578+
"libm/src/math/generic/frexp.rs"
579+
],
580+
"type": "f128"
581+
},
582+
"frexpf16": {
583+
"sources": [
584+
"libm/src/math/frexp.rs",
585+
"libm/src/math/generic/frexp.rs"
586+
],
587+
"type": "f16"
588+
},
575589
"hypot": {
576590
"sources": [
577591
"libm/src/math/hypot.rs"
@@ -598,6 +612,20 @@
598612
],
599613
"type": "f32"
600614
},
615+
"ilogbf128": {
616+
"sources": [
617+
"libm/src/math/generic/ilogb.rs",
618+
"libm/src/math/ilogb.rs"
619+
],
620+
"type": "f128"
621+
},
622+
"ilogbf16": {
623+
"sources": [
624+
"libm/src/math/generic/ilogb.rs",
625+
"libm/src/math/ilogb.rs"
626+
],
627+
"type": "f16"
628+
},
601629
"j0": {
602630
"sources": [
603631
"libm/src/math/j0.rs"

etc/function-list.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,14 @@ fmodf128
8484
fmodf16
8585
frexp
8686
frexpf
87+
frexpf128
88+
frexpf16
8789
hypot
8890
hypotf
8991
ilogb
9092
ilogbf
93+
ilogbf128
94+
ilogbf16
9195
j0
9296
j0f
9397
j1

libm-test/benches/icount.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,10 +331,14 @@ main!(
331331
icount_bench_fmodf16_group,
332332
icount_bench_fmodf_group,
333333
icount_bench_frexp_group,
334+
icount_bench_frexpf128_group,
335+
icount_bench_frexpf16_group,
334336
icount_bench_frexpf_group,
335337
icount_bench_hypot_group,
336338
icount_bench_hypotf_group,
337339
icount_bench_ilogb_group,
340+
icount_bench_ilogbf128_group,
341+
icount_bench_ilogbf16_group,
338342
icount_bench_ilogbf_group,
339343
icount_bench_j0_group,
340344
icount_bench_j0f_group,

libm-test/src/generate/case_list.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,14 +460,24 @@ fn fmodf16_cases() -> Vec<TestCase<op::fmodf16::Routine>> {
460460
vec![]
461461
}
462462

463-
fn frexp_cases() -> Vec<TestCase<op::frexp::Routine>> {
463+
#[cfg(f16_enabled)]
464+
fn frexpf16_cases() -> Vec<TestCase<op::frexpf16::Routine>> {
464465
vec![]
465466
}
466467

467468
fn frexpf_cases() -> Vec<TestCase<op::frexpf::Routine>> {
468469
vec![]
469470
}
470471

472+
fn frexp_cases() -> Vec<TestCase<op::frexp::Routine>> {
473+
vec![]
474+
}
475+
476+
#[cfg(f128_enabled)]
477+
fn frexpf128_cases() -> Vec<TestCase<op::frexpf128::Routine>> {
478+
vec![]
479+
}
480+
471481
fn hypot_cases() -> Vec<TestCase<op::hypot::Routine>> {
472482
vec![]
473483
}
@@ -476,14 +486,24 @@ fn hypotf_cases() -> Vec<TestCase<op::hypotf::Routine>> {
476486
vec![]
477487
}
478488

479-
fn ilogb_cases() -> Vec<TestCase<op::ilogb::Routine>> {
489+
#[cfg(f16_enabled)]
490+
fn ilogbf16_cases() -> Vec<TestCase<op::ilogbf16::Routine>> {
480491
vec![]
481492
}
482493

483494
fn ilogbf_cases() -> Vec<TestCase<op::ilogbf::Routine>> {
484495
vec![]
485496
}
486497

498+
fn ilogb_cases() -> Vec<TestCase<op::ilogb::Routine>> {
499+
vec![]
500+
}
501+
502+
#[cfg(f128_enabled)]
503+
fn ilogbf128_cases() -> Vec<TestCase<op::ilogbf128::Routine>> {
504+
vec![]
505+
}
506+
487507
fn j0_cases() -> Vec<TestCase<op::j0::Routine>> {
488508
vec![]
489509
}

libm-test/src/mpfloat.rs

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,12 @@ libm_macros::for_each_function! {
162162
fmodf16,
163163
frexp,
164164
frexpf,
165+
frexpf128,
166+
frexpf16,
165167
ilogb,
166168
ilogbf,
169+
ilogbf128,
170+
ilogbf16,
167171
jn,
168172
jnf,
169173
ldexp,
@@ -324,43 +328,6 @@ macro_rules! impl_op_for_ty {
324328
}
325329
}
326330

327-
impl MpOp for crate::op::[<frexp $suffix>]::Routine {
328-
type MpTy = MpFloat;
329-
330-
fn new_mp() -> Self::MpTy {
331-
new_mpfloat::<Self::FTy>()
332-
}
333-
334-
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
335-
this.assign(input.0);
336-
let exp = this.frexp_mut();
337-
(prep_retval::<Self::FTy>(this, Ordering::Equal), exp)
338-
}
339-
}
340-
341-
impl MpOp for crate::op::[<ilogb $suffix>]::Routine {
342-
type MpTy = MpFloat;
343-
344-
fn new_mp() -> Self::MpTy {
345-
new_mpfloat::<Self::FTy>()
346-
}
347-
348-
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
349-
this.assign(input.0);
350-
351-
// `get_exp` follows `frexp` for `0.5 <= |m| < 1.0`. Adjust the exponent by
352-
// one to scale the significand to `1.0 <= |m| < 2.0`.
353-
this.get_exp().map(|v| v - 1).unwrap_or_else(|| {
354-
if this.is_infinite() {
355-
i32::MAX
356-
} else {
357-
// Zero or NaN
358-
i32::MIN
359-
}
360-
})
361-
}
362-
}
363-
364331
impl MpOp for crate::op::[<jn $suffix>]::Routine {
365332
type MpTy = MpFloat;
366333

@@ -505,6 +472,43 @@ macro_rules! impl_op_for_ty_all {
505472
}
506473
}
507474

475+
impl MpOp for crate::op::[<frexp $suffix>]::Routine {
476+
type MpTy = MpFloat;
477+
478+
fn new_mp() -> Self::MpTy {
479+
new_mpfloat::<Self::FTy>()
480+
}
481+
482+
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
483+
this.assign(input.0);
484+
let exp = this.frexp_mut();
485+
(prep_retval::<Self::FTy>(this, Ordering::Equal), exp)
486+
}
487+
}
488+
489+
impl MpOp for crate::op::[<ilogb $suffix>]::Routine {
490+
type MpTy = MpFloat;
491+
492+
fn new_mp() -> Self::MpTy {
493+
new_mpfloat::<Self::FTy>()
494+
}
495+
496+
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
497+
this.assign(input.0);
498+
499+
// `get_exp` follows `frexp` for `0.5 <= |m| < 1.0`. Adjust the exponent by
500+
// one to scale the significand to `1.0 <= |m| < 2.0`.
501+
this.get_exp().map(|v| v - 1).unwrap_or_else(|| {
502+
if this.is_infinite() {
503+
i32::MAX
504+
} else {
505+
// Zero or NaN
506+
i32::MIN
507+
}
508+
})
509+
}
510+
}
511+
508512
// `ldexp` and `scalbn` are the same for binary floating point, so just forward all
509513
// methods.
510514
impl MpOp for crate::op::[<ldexp $suffix>]::Routine {

libm-test/src/test_traits.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,3 +456,15 @@ impl_tuples!(
456456
(f32, f32);
457457
(f64, f64);
458458
);
459+
460+
#[cfg(f16_enabled)]
461+
impl_tuples!(
462+
(f16, i32);
463+
(f16, f16);
464+
);
465+
466+
#[cfg(f128_enabled)]
467+
impl_tuples!(
468+
(f128, i32);
469+
(f128, f128);
470+
);

libm/src/libm_helper.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ libm_helper! {
202202
(fn fminimum(x: f16, y: f16) -> (f16); => fminimumf16);
203203
(fn fminimum_num(x: f16, y: f16) -> (f16); => fminimum_numf16);
204204
(fn fmod(x: f16, y: f16) -> (f16); => fmodf16);
205+
(fn frexp(x: f16) -> (f16, i32); => frexpf16);
206+
(fn ilogb(x: f16) -> (i32); => ilogbf16);
205207
(fn ldexp(x: f16, n: i32) -> (f16); => ldexpf16);
206208
(fn rint(x: f16) -> (f16); => rintf16);
207209
(fn round(x: f16) -> (f16); => roundf16);
@@ -231,6 +233,8 @@ libm_helper! {
231233
(fn fminimum(x: f128, y: f128) -> (f128); => fminimumf128);
232234
(fn fminimum_num(x: f128, y: f128) -> (f128); => fminimum_numf128);
233235
(fn fmod(x: f128, y: f128) -> (f128); => fmodf128);
236+
(fn frexp(x: f128) -> (f128, i32); => frexpf128);
237+
(fn ilogb(x: f128) -> (i32); => ilogbf128);
234238
(fn ldexp(x: f128, n: i32) -> (f128); => ldexpf128);
235239
(fn rint(x: f128) -> (f128); => rintf128);
236240
(fn round(x: f128) -> (f128); => roundf128);

libm/src/math/frexp.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
/// Decompose a float into a normalized value within the range `[0.5, 1)`, and a power of 2.
2+
///
3+
/// That is, `x * 2^p` will represent the input value.
4+
#[cfg(f16_enabled)]
5+
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
6+
pub fn frexpf16(x: f16) -> (f16, i32) {
7+
super::generic::frexp(x)
8+
}
9+
110
/// Decompose a float into a normalized value within the range `[0.5, 1)`, and a power of 2.
211
///
312
/// That is, `x * 2^p` will represent the input value.
@@ -13,3 +22,12 @@ pub fn frexpf(x: f32) -> (f32, i32) {
1322
pub fn frexp(x: f64) -> (f64, i32) {
1423
super::generic::frexp(x)
1524
}
25+
26+
/// Decompose a float into a normalized value within the range `[0.5, 1)`, and a power of 2.
27+
///
28+
/// That is, `x * 2^p` will represent the input value.
29+
#[cfg(f128_enabled)]
30+
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
31+
pub fn frexpf128(x: f128) -> (f128, i32) {
32+
super::generic::frexp(x)
33+
}

libm/src/math/ilogb.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
/// Extract the binary exponent of `x`.
2+
#[cfg(f16_enabled)]
3+
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
4+
pub fn ilogbf16(x: f16) -> i32 {
5+
super::generic::ilogb(x)
6+
}
7+
18
/// Extract the binary exponent of `x`.
29
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
310
pub fn ilogbf(x: f32) -> i32 {
@@ -9,3 +16,10 @@ pub fn ilogbf(x: f32) -> i32 {
916
pub fn ilogb(x: f64) -> i32 {
1017
super::generic::ilogb(x)
1118
}
19+
20+
/// Extract the binary exponent of `x`.
21+
#[cfg(f128_enabled)]
22+
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
23+
pub fn ilogbf128(x: f128) -> i32 {
24+
super::generic::ilogb(x)
25+
}

0 commit comments

Comments
 (0)