Skip to content

Commit 93e3091

Browse files
authored
Merge pull request #206 from aeleos/div
Implement divsf3 and divdf3
2 parents bb2c81b + 8bb3002 commit 93e3091

File tree

6 files changed

+659
-2
lines changed

6 files changed

+659
-2
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,11 @@ features = ["c"]
133133
- [ ] arm/unordsf2vfp.S
134134
- [x] ashldi3.c
135135
- [x] ashrdi3.c
136-
- [ ] divdf3.c
136+
- [x] divdf3.c
137137
- [x] divdi3.c
138138
- [x] divmoddi4.c
139139
- [x] divmodsi4.c
140-
- [ ] divsf3.c
140+
- [x] divsf3.c
141141
- [x] divsi3.c
142142
- [ ] extendhfsf2.c
143143
- [ ] extendsfdf2.c

build.rs

+185
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ mod tests {
125125
Mulsf3,
126126
Muldf3,
127127

128+
// float/div.rs
129+
Divsf3,
130+
Divdf3,
131+
128132
// int/mul.rs
129133
Muldi3,
130134
Mulodi4,
@@ -3399,6 +3403,187 @@ fn muldf3() {
33993403
}
34003404
}
34013405

3406+
#[derive(Eq, Hash, PartialEq)]
3407+
pub struct Divsf3 {
3408+
a: u32, // f32
3409+
b: u32, // f32
3410+
c: u32, // f32
3411+
}
3412+
3413+
impl TestCase for Divsf3 {
3414+
fn name() -> &'static str {
3415+
"divsf3"
3416+
}
3417+
3418+
fn generate<R>(rng: &mut R) -> Option<Self>
3419+
where
3420+
R: Rng,
3421+
Self: Sized,
3422+
{
3423+
let a = gen_large_f32(rng);
3424+
let b = gen_large_f32(rng);
3425+
if b == 0.0 {
3426+
return None;
3427+
}
3428+
let c = a / b;
3429+
// TODO accept NaNs. We don't do that right now because we can't check
3430+
// for NaN-ness on the thumb targets (due to missing intrinsics)
3431+
if a.is_nan() || b.is_nan() || c.is_nan()|| c.abs() <= unsafe { mem::transmute(16777215u32) } {
3432+
return None;
3433+
}
3434+
3435+
Some(
3436+
Divsf3 {
3437+
a: to_u32(a),
3438+
b: to_u32(b),
3439+
c: to_u32(c),
3440+
},
3441+
)
3442+
}
3443+
3444+
fn to_string(&self, buffer: &mut String) {
3445+
writeln!(
3446+
buffer,
3447+
"(({a}, {b}), {c}),",
3448+
a = self.a,
3449+
b = self.b,
3450+
c = self.c
3451+
)
3452+
.unwrap();
3453+
}
3454+
3455+
fn prologue() -> &'static str {
3456+
r#"
3457+
#[cfg(all(target_arch = "arm",
3458+
not(any(target_env = "gnu", target_env = "musl")),
3459+
target_os = "linux",
3460+
test))]
3461+
use core::mem;
3462+
#[cfg(not(all(target_arch = "arm",
3463+
not(any(target_env = "gnu", target_env = "musl")),
3464+
target_os = "linux",
3465+
test)))]
3466+
use std::mem;
3467+
use compiler_builtins::float::div::__divsf3;
3468+
3469+
fn mk_f32(x: u32) -> f32 {
3470+
unsafe { mem::transmute(x) }
3471+
}
3472+
3473+
fn to_u32(x: f32) -> u32 {
3474+
unsafe { mem::transmute(x) }
3475+
}
3476+
3477+
static TEST_CASES: &[((u32, u32), u32)] = &[
3478+
"#
3479+
}
3480+
3481+
fn epilogue() -> &'static str {
3482+
"
3483+
];
3484+
3485+
#[test]
3486+
fn divsf3() {
3487+
for &((a, b), c) in TEST_CASES {
3488+
let c_ = __divsf3(mk_f32(a), mk_f32(b));
3489+
assert_eq!(((a, b), c), ((a, b), to_u32(c_)));
3490+
}
3491+
}
3492+
"
3493+
}
3494+
}
3495+
3496+
#[derive(Eq, Hash, PartialEq)]
3497+
pub struct Divdf3 {
3498+
a: u64, // f64
3499+
b: u64, // f64
3500+
c: u64, // f64
3501+
}
3502+
3503+
impl TestCase for Divdf3 {
3504+
fn name() -> &'static str {
3505+
"divdf3"
3506+
}
3507+
3508+
fn generate<R>(rng: &mut R) -> Option<Self>
3509+
where
3510+
R: Rng,
3511+
Self: Sized,
3512+
{
3513+
let a = gen_large_f64(rng);
3514+
let b = gen_large_f64(rng);
3515+
if b == 0.0 {
3516+
return None;
3517+
}
3518+
let c = a / b;
3519+
// TODO accept NaNs. We don't do that right now because we can't check
3520+
// for NaN-ness on the thumb targets (due to missing intrinsics)
3521+
if a.is_nan() || b.is_nan() || c.is_nan()
3522+
|| c.abs() <= unsafe { mem::transmute(4503599627370495u64) } {
3523+
return None;
3524+
}
3525+
3526+
Some(
3527+
Divdf3 {
3528+
a: to_u64(a),
3529+
b: to_u64(b),
3530+
c: to_u64(c),
3531+
},
3532+
)
3533+
}
3534+
3535+
fn to_string(&self, buffer: &mut String) {
3536+
writeln!(
3537+
buffer,
3538+
"(({a}, {b}), {c}),",
3539+
a = self.a,
3540+
b = self.b,
3541+
c = self.c
3542+
)
3543+
.unwrap();
3544+
}
3545+
3546+
fn prologue() -> &'static str {
3547+
r#"
3548+
#[cfg(all(target_arch = "arm",
3549+
not(any(target_env = "gnu", target_env = "musl")),
3550+
target_os = "linux",
3551+
test))]
3552+
use core::mem;
3553+
#[cfg(not(all(target_arch = "arm",
3554+
not(any(target_env = "gnu", target_env = "musl")),
3555+
target_os = "linux",
3556+
test)))]
3557+
use std::mem;
3558+
use compiler_builtins::float::div::__divdf3;
3559+
3560+
fn mk_f64(x: u64) -> f64 {
3561+
unsafe { mem::transmute(x) }
3562+
}
3563+
3564+
fn to_u64(x: f64) -> u64 {
3565+
unsafe { mem::transmute(x) }
3566+
}
3567+
3568+
static TEST_CASES: &[((u64, u64), u64)] = &[
3569+
"#
3570+
}
3571+
3572+
fn epilogue() -> &'static str {
3573+
"
3574+
];
3575+
3576+
#[test]
3577+
fn divdf3() {
3578+
for &((a, b), c) in TEST_CASES {
3579+
let c_ = __divdf3(mk_f64(a), mk_f64(b));
3580+
assert_eq!(((a, b), c), ((a, b), to_u64(c_)));
3581+
}
3582+
}
3583+
"
3584+
}
3585+
}
3586+
34023587

34033588
#[derive(Eq, Hash, PartialEq)]
34043589
pub struct Udivdi3 {

0 commit comments

Comments
 (0)