fix x87 stack imbalance in corner cases of i386 math asm
authorRich Felker <dalias@aerifal.cx>
Mon, 5 Aug 2019 22:41:47 +0000 (18:41 -0400)
committerRich Felker <dalias@aerifal.cx>
Mon, 5 Aug 2019 22:41:47 +0000 (18:41 -0400)
commit 31c5fb80b9eae86f801be4f46025bc6532a554c5 introduced underflow
code paths for the i386 math asm, along with checks on the fpu status
word to skip the underflow-generation instructions if the underflow
flag was already raised. unfortunately, at least one such path, in
log1p, returned with 2 items on the x87 stack rather than just 1 item
for the return value. this is a violation of the ABI's calling
convention, and could cause subsequent floating point code to produce
NANs due to x87 stack overflow. if floating point results are used in
flow control, this can lead to runaway wrong code execution.

rather than reviewing each "underflow already raised" code path for
correctness, remove them all. they're likely slower than just
performing the underflow code unconditionally, and significantly more
complex.

all of this code should be ripped out and replaced by C source files
with inline asm. doing so would preclude this kind of error by having
the compiler perform all x87 stack register allocation and stack
manipulation, and would produce comparable or better code. however
such a change is a much larger project.

src/math/i386/asin.s
src/math/i386/atan.s
src/math/i386/atan2.s
src/math/i386/atan2f.s
src/math/i386/atanf.s
src/math/i386/exp.s
src/math/i386/log1p.s
src/math/i386/log1pf.s

index a9f691bff3b16c21e0ab10a75b2243707117b92a..920d967acfd257e0a6ac1a1d17a867cca7e6d4f7 100644 (file)
@@ -7,13 +7,10 @@ asinf:
        cmp $0x01000000,%eax
        jae 1f
                # subnormal x, return x with underflow
-       fnstsw %ax
-       and $16,%ax
-       jnz 2f
        fld %st(0)
        fmul %st(1)
        fstps 4(%esp)
-2:     ret
+       ret
 
 .global asinl
 .type asinl,@function
@@ -30,11 +27,8 @@ asin:
        cmp $0x00200000,%eax
        jae 1f
                # subnormal x, return x with underflow
-       fnstsw %ax
-       and $16,%ax
-       jnz 2f
        fsts 4(%esp)
-2:     ret
+       ret
 1:     fld %st(0)
        fld1
        fsub %st(0),%st(1)
index d73137b28eb545c543338383b0a5bbc8947345a7..a26feae1ff53583f97ccfbbf56a3382fd7dbad03 100644 (file)
@@ -10,8 +10,5 @@ atan:
        fpatan
        ret
                # subnormal x, return x with underflow
-1:     fnstsw %ax
-       and $16,%ax
-       jnz 2f
-       fsts 4(%esp)
-2:     ret
+1:     fsts 4(%esp)
+       ret
index a7d2979b050cbdeec7989b208ad0e55e6ccc7f91..1fa0524db9f66016a2106309a0314ae3d91e0d24 100644 (file)
@@ -10,8 +10,5 @@ atan2:
        cmp $0x00200000,%eax
        jae 1f
                # subnormal x, return x with underflow
-       fnstsw %ax
-       and $16,%ax
-       jnz 1f
        fsts 4(%esp)
-1:     ret
+       ret
index 14b88ce54a032765360b57512e6a4ec245857008..0b264726ac5870e5c7ec677e48380eb40e797704 100644 (file)
@@ -10,10 +10,7 @@ atan2f:
        cmp $0x01000000,%eax
        jae 1f
                # subnormal x, return x with underflow
-       fnstsw %ax
-       and $16,%ax
-       jnz 1f
        fld %st(0)
        fmul %st(1)
        fstps 4(%esp)
-1:     ret
+       ret
index 8caddefa26efc0256e756b4b164def3b317dd148..893beac5066c9d679747fbc486db3599888216fc 100644 (file)
@@ -10,10 +10,7 @@ atanf:
        fpatan
        ret
                # subnormal x, return x with underflow
-1:     fnstsw %ax
-       and $16,%ax
-       jnz 2f
-       fld %st(0)
+1:     fld %st(0)
        fmul %st(1)
        fstps 4(%esp)
-2:     ret
+       ret
index c7aa5b6eaa37a8385ff3998cf5b690884295618d..df87c49728b2f0496921b09db8b6caeaf55441d0 100644 (file)
@@ -7,13 +7,10 @@ expm1f:
        cmp $0x01000000,%eax
        jae 1f
                # subnormal x, return x with underflow
-       fnstsw %ax
-       and $16,%ax
-       jnz 2f
        fld %st(0)
        fmul %st(1)
        fstps 4(%esp)
-2:     ret
+       ret
 
 .global expm1l
 .type expm1l,@function
@@ -30,11 +27,8 @@ expm1:
        cmp $0x00200000,%eax
        jae 1f
                # subnormal x, return x with underflow
-       fnstsw %ax
-       and $16,%ax
-       jnz 2f
        fsts 4(%esp)
-2:     ret
+       ret
 1:     fldl2e
        fmulp
        mov $0xc2820000,%eax
index 6b6929c72800ab35c07bc331995fe1ed2de1ba61..354f391a7e3707dad653269030da52082e5c4f0a 100644 (file)
@@ -16,9 +16,6 @@ log1p:
        fyl2x
        ret
                # subnormal x, return x with underflow
-2:     fnstsw %ax
-       and $16,%ax
-       jnz 1f
-       fsts 4(%esp)
+2:     fsts 4(%esp)
        fstp %st(1)
-1:     ret
+       ret
index c0bcd30f0e6efd46b0b1223d5439097f7bc7febd..4d3484cd3747ad300c8732632e181d8cac716018 100644 (file)
@@ -16,10 +16,7 @@ log1pf:
        fyl2x
        ret
                # subnormal x, return x with underflow
-2:     fnstsw %ax
-       and $16,%ax
-       jnz 1f
-       fxch
+2:     fxch
        fmul %st(1)
        fstps 4(%esp)
-1:     ret
+       ret