fix excess precision in return value of i386 atan[2][f]
authorRich Felker <dalias@aerifal.cx>
Thu, 6 Feb 2020 16:34:54 +0000 (11:34 -0500)
committerRich Felker <dalias@aerifal.cx>
Thu, 6 Feb 2020 18:18:00 +0000 (13:18 -0500)
for functions implemented in C, this is a requirement of C11 (F.6);
strictly speaking that text does not apply to standard library
functions, but it seems to be intended to apply to them, and C2x is
expected to make it a requirement.

failure to drop excess precision is particularly bad for inverse trig
functions, where a value with excess precision can be outside the
range of the function (entire range, or range for a particular
subdomain), breaking reasonable invariants a caller may expect.

src/math/i386/atan.s
src/math/i386/atan2.s
src/math/i386/atan2f.s
src/math/i386/atanf.s

index a26feae1ff53583f97ccfbbf56a3382fd7dbad03..2c57f6b309d3d5e54430f17db69171e0ce5bc833 100644 (file)
@@ -8,6 +8,8 @@ atan:
        jb 1f
        fld1
        fpatan
+       fstpl 4(%esp)
+       fldl 4(%esp)
        ret
                # subnormal x, return x with underflow
 1:     fsts 4(%esp)
index 76b95f3176d49904a918e36aad30517ea720cb68..8bc441b1e47ec344454d851f4b01d3f1744ba0c6 100644 (file)
@@ -4,7 +4,8 @@ atan2:
        fldl 4(%esp)
        fldl 12(%esp)
        fpatan
-       fstl 4(%esp)
+       fstpl 4(%esp)
+       fldl 4(%esp)
        mov 8(%esp),%eax
        add %eax,%eax
        cmp $0x00200000,%eax
index c9408a9088d076e8a12618b3eeb2d32612d315ff..3908c86df9bac816fb8275bc4243f840ed94714c 100644 (file)
@@ -4,7 +4,8 @@ atan2f:
        flds 4(%esp)
        flds 8(%esp)
        fpatan
-       fsts 4(%esp)
+       fstps 4(%esp)
+       flds 4(%esp)
        mov 4(%esp),%eax
        add %eax,%eax
        cmp $0x01000000,%eax
index 893beac5066c9d679747fbc486db3599888216fc..c2cbe2e0267f93272a195725489afcbbc24c8876 100644 (file)
@@ -8,6 +8,8 @@ atanf:
        jb 1f
        fld1
        fpatan
+       fstps 4(%esp)
+       flds 4(%esp)
        ret
                # subnormal x, return x with underflow
 1:     fld %st(0)