Skip to content

Commit 839c72a

Browse files
committed
Add sqrtf16 and sqrtf128
Use the generic algorithms to provide implementations for these routines.
1 parent 2a29b7a commit 839c72a

File tree

11 files changed

+132
-2
lines changed

11 files changed

+132
-2
lines changed

crates/libm-macros/src/shared.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
99
FloatTy::F16,
1010
Signature { args: &[Ty::F16], returns: &[Ty::F16] },
1111
None,
12-
&["fabsf16", "truncf16"],
12+
&["fabsf16", "sqrtf16", "truncf16"],
1313
),
1414
(
1515
// `fn(f32) -> f32`
@@ -40,7 +40,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
4040
FloatTy::F128,
4141
Signature { args: &[Ty::F128], returns: &[Ty::F128] },
4242
None,
43-
&["fabsf128", "truncf128"],
43+
&["fabsf128", "sqrtf128", "truncf128"],
4444
),
4545
(
4646
// `(f16, f16) -> f16`

crates/libm-test/benches/icount.rs

+2
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ main!(
155155
icount_bench_sinh_group,
156156
icount_bench_sinhf_group,
157157
icount_bench_sqrt_group,
158+
icount_bench_sqrtf128_group,
159+
icount_bench_sqrtf16_group,
158160
icount_bench_sqrtf_group,
159161
icount_bench_tan_group,
160162
icount_bench_tanf_group,

crates/libm-test/benches/random.rs

+2
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ libm_macros::for_each_function! {
123123
| fabsf16
124124
| fdimf128
125125
| fdimf16
126+
| sqrtf16
127+
| sqrtf128
126128
| truncf128
127129
| truncf16 => (false, None),
128130

crates/libm-test/tests/compare_built_musl.rs

+2
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,7 @@ libm_macros::for_each_function! {
8787
fdimf16,
8888
truncf128,
8989
truncf16,
90+
sqrtf16,
91+
sqrtf128,
9092
],
9193
}

crates/util/src/main.rs

+2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
9090
| fabsf16
9191
| fdimf128
9292
| fdimf16
93+
| sqrtf128
94+
| sqrtf16
9395
| truncf128
9496
| truncf16 => None,
9597
_ => Some(musl_math_sys::MACRO_FN_NAME)

etc/function-definitions.json

+14
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,20 @@
718718
],
719719
"type": "f32"
720720
},
721+
"sqrtf128": {
722+
"sources": [
723+
"src/math/generic/sqrt.rs",
724+
"src/math/sqrtf128.rs"
725+
],
726+
"type": "f128"
727+
},
728+
"sqrtf16": {
729+
"sources": [
730+
"src/math/generic/sqrt.rs",
731+
"src/math/sqrtf16.rs"
732+
],
733+
"type": "f16"
734+
},
721735
"tan": {
722736
"sources": [
723737
"src/libm_helper.rs",

etc/function-list.txt

+2
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ sinh
105105
sinhf
106106
sqrt
107107
sqrtf
108+
sqrtf128
109+
sqrtf16
108110
tan
109111
tanf
110112
tanh

src/math/generic/sqrt.rs

+92
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,14 @@ pub trait SqrtHelper: Float {
294294
const FINAL_ROUNDS: u32;
295295
}
296296

297+
#[cfg(f16_enabled)]
298+
impl SqrtHelper for f16 {
299+
type ISet1 = u16; // unused
300+
type ISet2 = u16; // unused
301+
302+
const FINAL_ROUNDS: u32 = 2;
303+
}
304+
297305
impl SqrtHelper for f32 {
298306
type ISet1 = u32; // unused
299307
type ISet2 = u32; // unused
@@ -309,6 +317,16 @@ impl SqrtHelper for f64 {
309317
const FINAL_ROUNDS: u32 = 2;
310318
}
311319

320+
#[cfg(f128_enabled)]
321+
impl SqrtHelper for f128 {
322+
type ISet1 = u32;
323+
type ISet2 = u64;
324+
325+
const SET1_ROUNDS: u32 = 1;
326+
const SET2_ROUNDS: u32 = 2;
327+
const FINAL_ROUNDS: u32 = 2;
328+
}
329+
312330
/// A U0.16 representation of `1/sqrt(x)`.
313331
///
314332
// / The index is a 7-bit number consisting of a single exponent bit and 6 bits of significand.
@@ -355,6 +373,42 @@ mod tests {
355373
}
356374
}
357375

376+
#[test]
377+
#[cfg(f16_enabled)]
378+
fn sanity_check_f16() {
379+
assert_biteq!(sqrt(100.0f16), 10.0);
380+
assert_biteq!(sqrt(4.0f16), 2.0);
381+
}
382+
383+
#[test]
384+
#[cfg(f16_enabled)]
385+
fn spec_tests_f16() {
386+
spec_test::<f16>();
387+
}
388+
389+
#[test]
390+
#[cfg(f16_enabled)]
391+
#[allow(clippy::approx_constant)]
392+
fn conformance_tests_f16() {
393+
let cases = [
394+
(f16::PI, 0x3f17_u16),
395+
// 10_000.0, using a hex literal for MSRV hack (Rust < 1.67 checks literal widths as
396+
// part of the AST, so the `cfg` is irrelevant here).
397+
(f16::from_bits(0x70e2), 0x5640_u16),
398+
(f16::from_bits(0x0000000f), 0x13bf_u16),
399+
(f16::INFINITY, f16::INFINITY.to_bits()),
400+
];
401+
402+
for (input, output) in cases {
403+
assert_biteq!(
404+
sqrt(input),
405+
f16::from_bits(output),
406+
"input: {input:?} ({:#018x})",
407+
input.to_bits()
408+
);
409+
}
410+
}
411+
358412
#[test]
359413
fn sanity_check_f32() {
360414
assert_biteq!(sqrt(100.0f32), 10.0);
@@ -416,4 +470,42 @@ mod tests {
416470
);
417471
}
418472
}
473+
474+
#[test]
475+
#[cfg(f128_enabled)]
476+
fn sanity_check_f128() {
477+
assert_biteq!(sqrt(100.0f128), 10.0);
478+
assert_biteq!(sqrt(4.0f128), 2.0);
479+
}
480+
481+
#[test]
482+
#[cfg(f128_enabled)]
483+
fn spec_tests_f128() {
484+
spec_test::<f128>();
485+
}
486+
487+
#[test]
488+
#[cfg(f128_enabled)]
489+
#[allow(clippy::approx_constant)]
490+
fn conformance_tests_f128() {
491+
let cases = [
492+
(f128::PI, 0x3fffc5bf891b4ef6aa79c3b0520d5db9_u128),
493+
// 10_000.0, see `f16` for reasoning.
494+
(
495+
f128::from_bits(0x400c3880000000000000000000000000),
496+
0x40059000000000000000000000000000_u128,
497+
),
498+
(f128::from_bits(0x0000000f), 0x1fc9efbdeb14f4ed9b17ae807907e1e9_u128),
499+
(f128::INFINITY, f128::INFINITY.to_bits()),
500+
];
501+
502+
for (input, output) in cases {
503+
assert_biteq!(
504+
sqrt(input),
505+
f128::from_bits(output),
506+
"input: {input:?} ({:#018x})",
507+
input.to_bits()
508+
);
509+
}
510+
}
419511
}

src/math/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -344,11 +344,13 @@ cfg_if! {
344344
mod copysignf16;
345345
mod fabsf16;
346346
mod fdimf16;
347+
mod sqrtf16;
347348
mod truncf16;
348349

349350
pub use self::copysignf16::copysignf16;
350351
pub use self::fabsf16::fabsf16;
351352
pub use self::fdimf16::fdimf16;
353+
pub use self::sqrtf16::sqrtf16;
352354
pub use self::truncf16::truncf16;
353355
}
354356
}
@@ -358,11 +360,13 @@ cfg_if! {
358360
mod copysignf128;
359361
mod fabsf128;
360362
mod fdimf128;
363+
mod sqrtf128;
361364
mod truncf128;
362365

363366
pub use self::copysignf128::copysignf128;
364367
pub use self::fabsf128::fabsf128;
365368
pub use self::fdimf128::fdimf128;
369+
pub use self::sqrtf128::sqrtf128;
366370
pub use self::truncf128::truncf128;
367371
}
368372
}

src/math/sqrtf128.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/// The square root of `x` (f128).
2+
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
3+
pub fn sqrtf128(x: f128) -> f128 {
4+
return super::generic::sqrt(x);
5+
}

src/math/sqrtf16.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/// The square root of `x` (f16).
2+
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
3+
pub fn sqrtf16(x: f16) -> f16 {
4+
return super::generic::sqrt(x);
5+
}

0 commit comments

Comments
 (0)