authorgravatar for 39607947+vegecode@users.noreply.github.comvegecode <39607947+vegecode@users.noreply.github.com> 2019-04-05 10:04:46-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-05 11:04:46-04:00
logc24a49a1a7a74937fca4375fe418a92c398c013f
treea1378b37240c7272c1c3b6fc62a9ba6b331e568f
parentaecbd1892a871a2b046ceda9058c4132cd0cb392

Fixes to divsf3 (#2186)

* Fixes to divsf3 Embarrassingly failed to notice a section that was unchanged from where it was copied from mulXf3.zig. The test cases for this function series div{s,d,t}f3 are very incomplete and don't exercise all code paths. Remove unnecessary switch from divsf3 left during development from when I tried to make it generic to support f32, f64, and f128 in one go. Make runtime safety dependent on whether a test is being run. * divsf3: switch plus to minus

1 files changed, 25 insertions(+), 24 deletions(-)

std/special/compiler_rt/divsf3.zig+25-24
......@@ -3,8 +3,10 @@
33// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/divsf3.c
44
55const std = @import("std");
6const builtin = @import("builtin");
67
78pub extern fn __divsf3(a: f32, b: f32) f32 {
9 @setRuntimeSafety(builtin.is_test);
810 const Z = @IntType(false, f32.bit_count);
911
1012 const typeWidth = f32.bit_count;
......@@ -37,41 +39,43 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {
3739 const aAbs: Z = @bitCast(Z, a) & absMask;
3840 const bAbs: Z = @bitCast(Z, b) & absMask;
3941
40 // NaN * anything = qNaN
42 // NaN / anything = qNaN
4143 if (aAbs > infRep) return @bitCast(f32, @bitCast(Z, a) | quietBit);
42 // anything * NaN = qNaN
44 // anything / NaN = qNaN
4345 if (bAbs > infRep) return @bitCast(f32, @bitCast(Z, b) | quietBit);
4446
4547 if (aAbs == infRep) {
46 // infinity * non-zero = +/- infinity
47 if (bAbs != 0) {
48 return @bitCast(f32, aAbs | quotientSign);
49 } else {
50 // infinity * zero = NaN
48 // infinity / infinity = NaN
49 if (bAbs == infRep) {
5150 return @bitCast(f32, qnanRep);
5251 }
52 // infinity / anything else = +/- infinity
53 else {
54 return @bitCast(f32, aAbs | quotientSign);
55 }
5356 }
5457
55 if (bAbs == infRep) {
56 //? non-zero * infinity = +/- infinity
57 if (aAbs != 0) {
58 return @bitCast(f32, bAbs | quotientSign);
59 } else {
60 // zero * infinity = NaN
58 // anything else / infinity = +/- 0
59 if (bAbs == infRep) return @bitCast(f32, quotientSign);
60
61 if (aAbs == 0) {
62 // zero / zero = NaN
63 if (bAbs == 0) {
6164 return @bitCast(f32, qnanRep);
6265 }
66 // zero / anything else = +/- zero
67 else {
68 return @bitCast(f32, quotientSign);
69 }
6370 }
64
65 // zero * anything = +/- zero
66 if (aAbs == 0) return @bitCast(f32, quotientSign);
67 // anything * zero = +/- zero
68 if (bAbs == 0) return @bitCast(f32, quotientSign);
71 // anything else / zero = +/- infinity
72 if (bAbs == 0) return @bitCast(f32, infRep | quotientSign);
6973
7074 // one or both of a or b is denormal, the other (if applicable) is a
7175 // normal number. Renormalize one or both of a and b, and set scale to
7276 // include the necessary exponent adjustment.
7377 if (aAbs < implicitBit) scale +%= normalize(f32, &aSignificand);
74 if (bAbs < implicitBit) scale +%= normalize(f32, &bSignificand);
78 if (bAbs < implicitBit) scale -%= normalize(f32, &bSignificand);
7579 }
7680
7781 // Or in the implicit significand bit. (If we fell through from the
......@@ -85,11 +89,7 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {
8589 // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax
8690 // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
8791 // is accurate to about 3.5 binary digits.
88 const q31b = switch (f32) {
89 f32 => bSignificand << 8,
90 f64 => bSignificand >> 21,
91 else => @compileError("Type not implemented."),
92 };
92 const q31b = bSignificand << 8;
9393 var reciprocal = u32(0x7504f333) -% q31b;
9494
9595 // Now refine the reciprocal estimate using a Newton-Raphson iteration:
......@@ -186,6 +186,7 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {
186186}
187187
188188fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
189 @setRuntimeSafety(builtin.is_test);
189190 const Z = @IntType(false, T.bit_count);
190191 const significandBits = std.math.floatMantissaBits(T);
191192 const implicitBit = Z(1) << significandBits;