X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Ffenv%2Fi386%2Ffenv.s;h=e7f7932a1cd5d9d703b813025ac08c753b9ffdf0;hb=7865d569de7b29dd90b94b5680ec7a2a86ed27af;hp=e365b8f418bd19ff2e00d35b0ff6e848065d4dce;hpb=316e024f63af0d0d2bb0df3dfce2620f4be827d1;p=musl diff --git a/src/fenv/i386/fenv.s b/src/fenv/i386/fenv.s index e365b8f4..e7f7932a 100644 --- a/src/fenv/i386/fenv.s +++ b/src/fenv/i386/fenv.s @@ -1,17 +1,45 @@ +.hidden __hwcap + .global feclearexcept .type feclearexcept,@function feclearexcept: mov 4(%esp),%ecx + and $0x3f,%ecx + fnstsw %ax + # consider sse fenv as well if the cpu has XMM capability + call 1f +1: addl $__hwcap-1b,(%esp) + pop %edx + testl $0x02000000,(%edx) + jz 2f + # maintain exceptions in the sse mxcsr, clear x87 exceptions + test %eax,%ecx + jz 1f + fnclex +1: push %edx + stmxcsr (%esp) + pop %edx + and $0x3f,%eax + or %eax,%edx + test %edx,%ecx + jz 1f not %ecx - test $0x3f,%ecx - jnz 2f -1: fnclex - xor %eax,%eax + and %ecx,%edx + push %edx + ldmxcsr (%esp) + pop %edx +1: xor %eax,%eax ret -2: fnstsw %ax - and %ecx,%eax + # only do the expensive x87 fenv load/store when needed +2: test %eax,%ecx jz 1b - sub $32,%esp + not %ecx + and %ecx,%eax + test $0x3f,%eax + jz 1f + fnclex + jmp 1b +1: sub $32,%esp fnstenv (%esp) mov %al,4(%esp) fldenv (%esp) @@ -23,6 +51,7 @@ feclearexcept: .type feraiseexcept,@function feraiseexcept: mov 4(%esp),%eax + and $0x3f,%eax sub $32,%esp fnstenv (%esp) or %al,4(%esp) @@ -31,9 +60,10 @@ feraiseexcept: xor %eax,%eax ret -.global fesetround -.type fesetround,@function -fesetround: +.global __fesetround +.hidden __fesetround +.type __fesetround,@function +__fesetround: mov 4(%esp),%ecx push %eax xor %eax,%eax @@ -41,7 +71,18 @@ fesetround: andb $0xf3,1(%esp) or %ch,1(%esp) fldcw (%esp) - pop %ecx + # consider sse fenv as well if the cpu has XMM capability + call 1f +1: addl $__hwcap-1b,(%esp) + pop %edx + testl $0x02000000,(%edx) + jz 1f + stmxcsr (%esp) + shl $3,%ch + andb $0x9f,1(%esp) + or %ch,1(%esp) + ldmxcsr (%esp) +1: pop %ecx ret .global fegetround @@ -59,32 +100,65 @@ fegetenv: mov 4(%esp),%ecx xor %eax,%eax fnstenv (%ecx) - ret + # consider sse fenv as well if the cpu has XMM capability + call 1f +1: addl $__hwcap-1b,(%esp) + pop %edx + testl $0x02000000,(%edx) + jz 1f + push %eax + stmxcsr (%esp) + pop %edx + and $0x3f,%edx + or %edx,4(%ecx) +1: ret .global fesetenv .type fesetenv,@function fesetenv: mov 4(%esp),%ecx xor %eax,%eax - test %ecx,%ecx + inc %ecx jz 1f - fldenv (%ecx) - ret + fldenv -1(%ecx) + movl -1(%ecx),%ecx + jmp 2f 1: push %eax push %eax push %eax push %eax - push %eax + pushl $0xffff push %eax pushl $0x37f fldenv (%esp) add $28,%esp - ret + # consider sse fenv as well if the cpu has XMM capability +2: call 1f +1: addl $__hwcap-1b,(%esp) + pop %edx + testl $0x02000000,(%edx) + jz 1f + # mxcsr := same rounding mode, cleared exceptions, default mask + and $0xc00,%ecx + shl $3,%ecx + or $0x1f80,%ecx + mov %ecx,4(%esp) + ldmxcsr 4(%esp) +1: ret .global fetestexcept .type fetestexcept,@function fetestexcept: mov 4(%esp),%ecx + and $0x3f,%ecx fnstsw %ax - and %ecx,%eax + # consider sse fenv as well if the cpu has XMM capability + call 1f +1: addl $__hwcap-1b,(%esp) + pop %edx + testl $0x02000000,(%edx) + jz 1f + stmxcsr 4(%esp) + or 4(%esp),%eax +1: and %ecx,%eax ret