mirror of git://sourceware.org/git/glibc.git
x86: Remove obsolete "*&" GCC asm memory operand workaround
GCC now accept plain variable names as valid lvalues for "m" constraints, automatically spilling locals to memory if necessary. The long-standing "*&" pattern was originally used as a defensive workaround for older compiler versions that rejected operands such as: asm ("incl %0" : "+m"(x)); with errors like "memory input is not directly addressable". Modern compilers (GCC >= 9) reliably generate correct code without the workaround, and the resulting assembly is identical. No functional changes intended. Signed-off-by: Uros Bizjak <ubizjak@gmail.com> Reviewed-by: Florian Weimer <fweimer@redhat.com> Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
This commit is contained in:
parent
eba46f7077
commit
3014dec3ad
|
@ -30,13 +30,13 @@ __feclearexcept (int excepts)
|
|||
|
||||
/* Bah, we have to clear selected exceptions. Since there is no
|
||||
`fldsw' instruction we have to do it the hard way. */
|
||||
__asm__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
/* Clear the relevant bits. */
|
||||
temp.__status_word &= excepts ^ FE_ALL_EXCEPT;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ ("fldenv %0" : : "m" (temp));
|
||||
|
||||
/* If the CPU supports SSE, we clear the MXCSR as well. */
|
||||
if (CPU_FEATURE_USABLE (SSE))
|
||||
|
@ -44,13 +44,13 @@ __feclearexcept (int excepts)
|
|||
unsigned int xnew_exc;
|
||||
|
||||
/* Get the current MXCSR. */
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
|
||||
__asm__ ("stmxcsr %0" : "=m" (xnew_exc));
|
||||
|
||||
/* Clear the relevant bits. */
|
||||
xnew_exc &= ~excepts;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (xnew_exc));
|
||||
}
|
||||
|
||||
/* Success. */
|
||||
|
|
|
@ -26,14 +26,14 @@ fedisableexcept (int excepts)
|
|||
unsigned short int new_exc, old_exc;
|
||||
|
||||
/* Get the current control word. */
|
||||
__asm__ ("fstcw %0" : "=m" (*&new_exc));
|
||||
__asm__ ("fstcw %0" : "=m" (new_exc));
|
||||
|
||||
old_exc = (~new_exc) & FE_ALL_EXCEPT;
|
||||
|
||||
excepts &= FE_ALL_EXCEPT;
|
||||
|
||||
new_exc |= excepts;
|
||||
__asm__ ("fldcw %0" : : "m" (*&new_exc));
|
||||
__asm__ ("fldcw %0" : : "m" (new_exc));
|
||||
|
||||
/* If the CPU supports SSE we set the MXCSR as well. */
|
||||
if (CPU_FEATURE_USABLE (SSE))
|
||||
|
@ -41,11 +41,11 @@ fedisableexcept (int excepts)
|
|||
unsigned int xnew_exc;
|
||||
|
||||
/* Get the current control word. */
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
|
||||
__asm__ ("stmxcsr %0" : "=m" (xnew_exc));
|
||||
|
||||
xnew_exc |= excepts << 7;
|
||||
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (xnew_exc));
|
||||
}
|
||||
|
||||
return old_exc;
|
||||
|
|
|
@ -27,13 +27,13 @@ feenableexcept (int excepts)
|
|||
unsigned short int old_exc;
|
||||
|
||||
/* Get the current control word. */
|
||||
__asm__ ("fstcw %0" : "=m" (*&new_exc));
|
||||
__asm__ ("fstcw %0" : "=m" (new_exc));
|
||||
|
||||
excepts &= FE_ALL_EXCEPT;
|
||||
old_exc = (~new_exc) & FE_ALL_EXCEPT;
|
||||
|
||||
new_exc &= ~excepts;
|
||||
__asm__ ("fldcw %0" : : "m" (*&new_exc));
|
||||
__asm__ ("fldcw %0" : : "m" (new_exc));
|
||||
|
||||
/* If the CPU supports SSE we set the MXCSR as well. */
|
||||
if (CPU_FEATURE_USABLE (SSE))
|
||||
|
@ -41,11 +41,11 @@ feenableexcept (int excepts)
|
|||
unsigned int xnew_exc;
|
||||
|
||||
/* Get the current control word. */
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
|
||||
__asm__ ("stmxcsr %0" : "=m" (xnew_exc));
|
||||
|
||||
xnew_exc &= ~(excepts << 7);
|
||||
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (xnew_exc));
|
||||
}
|
||||
|
||||
return old_exc;
|
||||
|
|
|
@ -24,7 +24,7 @@ fegetexcept (void)
|
|||
unsigned short int exc;
|
||||
|
||||
/* Get the current control word. */
|
||||
__asm__ ("fstcw %0" : "=m" (*&exc));
|
||||
__asm__ ("fstcw %0" : "=m" (exc));
|
||||
|
||||
return (~exc) & FE_ALL_EXCEPT;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ __fegetround (void)
|
|||
{
|
||||
int cw;
|
||||
|
||||
__asm__ ("fnstcw %0" : "=m" (*&cw));
|
||||
__asm__ ("fnstcw %0" : "=m" (cw));
|
||||
|
||||
return cw & 0xc00;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ __feholdexcept (fenv_t *envp)
|
|||
/* Set all exceptions to non-stop and clear them. */
|
||||
xwork = (envp->__eip | 0x1f80) & ~0x3f;
|
||||
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&xwork));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (xwork));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -40,7 +40,7 @@ __fesetenv (const fenv_t *envp)
|
|||
values which we do not want to come from the saved environment.
|
||||
Therefore, we get the current environment and replace the values
|
||||
we want to use from the environment specified by the parameter. */
|
||||
__asm__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
if (envp == FE_DFL_ENV)
|
||||
{
|
||||
|
|
|
@ -33,13 +33,13 @@ fesetexcept (int excepts)
|
|||
{
|
||||
/* Get the control word of the SSE unit. */
|
||||
unsigned int mxcsr;
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
|
||||
__asm__ ("stmxcsr %0" : "=m" (mxcsr));
|
||||
|
||||
/* Set relevant flags. */
|
||||
mxcsr |= excepts;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (mxcsr));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ fesetexcept (int excepts)
|
|||
|
||||
/* Note: fnstenv masks all floating-point exceptions until the fldenv
|
||||
or fldcw below. */
|
||||
__asm__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
/* Set relevant flags. */
|
||||
temp.__status_word |= excepts;
|
||||
|
@ -57,12 +57,12 @@ fesetexcept (int excepts)
|
|||
/* Setting the exception flags may trigger a trap (at the next
|
||||
floating-point instruction, but that does not matter).
|
||||
ISO C23 (7.6.4.4) does not allow it. */
|
||||
__asm__ volatile ("fldcw %0" : : "m" (*&temp.__control_word));
|
||||
__asm__ volatile ("fldcw %0" : : "m" (temp.__control_word));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Store the new status word (along with the rest of the environment). */
|
||||
__asm__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ ("fldenv %0" : : "m" (temp));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -29,20 +29,20 @@ __fesetround (int round)
|
|||
/* ROUND is no valid rounding mode. */
|
||||
return 1;
|
||||
|
||||
__asm__ ("fnstcw %0" : "=m" (*&cw));
|
||||
__asm__ ("fnstcw %0" : "=m" (cw));
|
||||
cw &= ~0xc00;
|
||||
cw |= round;
|
||||
__asm__ ("fldcw %0" : : "m" (*&cw));
|
||||
__asm__ ("fldcw %0" : : "m" (cw));
|
||||
|
||||
/* If the CPU supports SSE we set the MXCSR as well. */
|
||||
if (CPU_FEATURE_USABLE (SSE))
|
||||
{
|
||||
unsigned int xcw;
|
||||
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&xcw));
|
||||
__asm__ ("stmxcsr %0" : "=m" (xcw));
|
||||
xcw &= ~0x6000;
|
||||
xcw |= round << 3;
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&xcw));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (xcw));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -27,11 +27,11 @@ __feupdateenv (const fenv_t *envp)
|
|||
unsigned int xtemp = 0;
|
||||
|
||||
/* Save current exceptions. */
|
||||
__asm__ ("fnstsw %0" : "=m" (*&temp));
|
||||
__asm__ ("fnstsw %0" : "=m" (temp));
|
||||
|
||||
/* If the CPU supports SSE we test the MXCSR as well. */
|
||||
if (CPU_FEATURE_USABLE (SSE))
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&xtemp));
|
||||
__asm__ ("stmxcsr %0" : "=m" (xtemp));
|
||||
|
||||
temp = (temp | xtemp) & FE_ALL_EXCEPT;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ __fegetexceptflag (fexcept_t *flagp, int excepts)
|
|||
fexcept_t temp;
|
||||
|
||||
/* Get the current exceptions. */
|
||||
__asm__ ("fnstsw %0" : "=m" (*&temp));
|
||||
__asm__ ("fnstsw %0" : "=m" (temp));
|
||||
|
||||
*flagp = temp & excepts & FE_ALL_EXCEPT;
|
||||
|
||||
|
@ -37,7 +37,7 @@ __fegetexceptflag (fexcept_t *flagp, int excepts)
|
|||
unsigned int sse_exc;
|
||||
|
||||
/* Get the current MXCSR. */
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&sse_exc));
|
||||
__asm__ ("stmxcsr %0" : "=m" (sse_exc));
|
||||
|
||||
*flagp |= sse_exc & excepts & FE_ALL_EXCEPT;
|
||||
}
|
||||
|
|
|
@ -54,13 +54,13 @@ __feraiseexcept (int excepts)
|
|||
|
||||
/* Bah, we have to clear selected exceptions. Since there is no
|
||||
`fldsw' instruction we have to do it the hard way. */
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
/* Set the relevant bits. */
|
||||
temp.__status_word |= FE_OVERFLOW;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (temp));
|
||||
|
||||
/* And raise the exception. */
|
||||
__asm__ __volatile__ ("fwait");
|
||||
|
@ -75,13 +75,13 @@ __feraiseexcept (int excepts)
|
|||
|
||||
/* Bah, we have to clear selected exceptions. Since there is no
|
||||
`fldsw' instruction we have to do it the hard way. */
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
/* Set the relevant bits. */
|
||||
temp.__status_word |= FE_UNDERFLOW;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (temp));
|
||||
|
||||
/* And raise the exception. */
|
||||
__asm__ __volatile__ ("fwait");
|
||||
|
@ -96,13 +96,13 @@ __feraiseexcept (int excepts)
|
|||
|
||||
/* Bah, we have to clear selected exceptions. Since there is no
|
||||
`fldsw' instruction we have to do it the hard way. */
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
/* Set the relevant bits. */
|
||||
temp.__status_word |= FE_INEXACT;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (temp));
|
||||
|
||||
/* And raise the exception. */
|
||||
__asm__ __volatile__ ("fwait");
|
||||
|
|
|
@ -37,7 +37,7 @@ __fesetexceptflag (const fexcept_t *flagp, int excepts)
|
|||
cannot separately set the status word.
|
||||
Note: fnstenv masks all floating-point exceptions until the fldenv
|
||||
or fldcw below. */
|
||||
__asm__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
if (CPU_FEATURE_USABLE (SSE))
|
||||
{
|
||||
|
@ -47,16 +47,16 @@ __fesetexceptflag (const fexcept_t *flagp, int excepts)
|
|||
temp.__status_word &= ~(excepts & ~ *flagp);
|
||||
|
||||
/* Store the new status word (along with the rest of the environment). */
|
||||
__asm__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ ("fldenv %0" : : "m" (temp));
|
||||
|
||||
/* And now similarly for SSE. */
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
|
||||
__asm__ ("stmxcsr %0" : "=m" (mxcsr));
|
||||
|
||||
/* Clear or set relevant flags. */
|
||||
mxcsr ^= (mxcsr ^ *flagp) & excepts;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (mxcsr));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -68,12 +68,12 @@ __fesetexceptflag (const fexcept_t *flagp, int excepts)
|
|||
/* Setting the exception flags may trigger a trap (at the next
|
||||
floating-point instruction, but that does not matter).
|
||||
ISO C 23 § 7.6.4.5 does not allow it. */
|
||||
__asm__ volatile ("fldcw %0" : : "m" (*&temp.__control_word));
|
||||
__asm__ volatile ("fldcw %0" : : "m" (temp.__control_word));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Store the new status word (along with the rest of the environment). */
|
||||
__asm__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ ("fldenv %0" : : "m" (temp));
|
||||
}
|
||||
|
||||
/* Success. */
|
||||
|
|
|
@ -31,7 +31,7 @@ __fetestexcept (int excepts)
|
|||
|
||||
/* If the CPU supports SSE we test the MXCSR as well. */
|
||||
if (CPU_FEATURE_USABLE (SSE))
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&xtemp));
|
||||
__asm__ ("stmxcsr %0" : "=m" (xtemp));
|
||||
|
||||
return (temp | xtemp) & excepts & FE_ALL_EXCEPT;
|
||||
}
|
||||
|
|
|
@ -28,14 +28,14 @@ __setfpucw (fpu_control_t set)
|
|||
fpu_control_t cw;
|
||||
|
||||
/* Fetch the current control word. */
|
||||
__asm__ ("fnstcw %0" : "=m" (*&cw));
|
||||
__asm__ ("fnstcw %0" : "=m" (cw));
|
||||
|
||||
/* Preserve the reserved bits, and set the rest as the user
|
||||
specified (or the default, if the user gave zero). */
|
||||
cw &= _FPU_RESERVED;
|
||||
cw |= set & ~_FPU_RESERVED;
|
||||
|
||||
__asm__ ("fldcw %0" : : "m" (*&cw));
|
||||
__asm__ ("fldcw %0" : : "m" (cw));
|
||||
|
||||
/* If the CPU supports SSE, we set the MXCSR as well. */
|
||||
if (CPU_FEATURE_USABLE (SSE))
|
||||
|
@ -43,11 +43,11 @@ __setfpucw (fpu_control_t set)
|
|||
unsigned int xnew_exc;
|
||||
|
||||
/* Get the current MXCSR. */
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
|
||||
__asm__ ("stmxcsr %0" : "=m" (xnew_exc));
|
||||
|
||||
xnew_exc &= ~((0xc00 << 3) | (FE_ALL_EXCEPT << 7));
|
||||
xnew_exc |= ((set & 0xc00) << 3) | ((set & FE_ALL_EXCEPT) << 7);
|
||||
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (xnew_exc));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,10 +30,10 @@ static __always_inline void
|
|||
libc_feholdexcept_sse (fenv_t *e)
|
||||
{
|
||||
unsigned int mxcsr;
|
||||
asm (STMXCSR " %0" : "=m" (*&mxcsr));
|
||||
asm (STMXCSR " %0" : "=m" (mxcsr));
|
||||
e->__mxcsr = mxcsr;
|
||||
mxcsr = (mxcsr | 0x1f80) & ~0x3f;
|
||||
asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
|
||||
asm volatile (LDMXCSR " %0" : : "m" (mxcsr));
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
|
@ -51,9 +51,9 @@ static __always_inline void
|
|||
libc_fesetround_sse (int r)
|
||||
{
|
||||
unsigned int mxcsr;
|
||||
asm (STMXCSR " %0" : "=m" (*&mxcsr));
|
||||
asm (STMXCSR " %0" : "=m" (mxcsr));
|
||||
mxcsr = (mxcsr & ~0x6000) | (r << 3);
|
||||
asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
|
||||
asm volatile (LDMXCSR " %0" : : "m" (mxcsr));
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
|
@ -69,10 +69,10 @@ static __always_inline void
|
|||
libc_feholdexcept_setround_sse (fenv_t *e, int r)
|
||||
{
|
||||
unsigned int mxcsr;
|
||||
asm (STMXCSR " %0" : "=m" (*&mxcsr));
|
||||
asm (STMXCSR " %0" : "=m" (mxcsr));
|
||||
e->__mxcsr = mxcsr;
|
||||
mxcsr = ((mxcsr | 0x1f80) & ~0x603f) | (r << 3);
|
||||
asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
|
||||
asm volatile (LDMXCSR " %0" : : "m" (mxcsr));
|
||||
}
|
||||
|
||||
/* Set both rounding mode and precision. A convenience function for use
|
||||
|
@ -104,7 +104,7 @@ static __always_inline int
|
|||
libc_fetestexcept_sse (int e)
|
||||
{
|
||||
unsigned int mxcsr;
|
||||
asm volatile (STMXCSR " %0" : "=m" (*&mxcsr));
|
||||
asm volatile (STMXCSR " %0" : "=m" (mxcsr));
|
||||
return mxcsr & e & FE_ALL_EXCEPT;
|
||||
}
|
||||
|
||||
|
@ -137,13 +137,13 @@ static __always_inline int
|
|||
libc_feupdateenv_test_sse (fenv_t *e, int ex)
|
||||
{
|
||||
unsigned int mxcsr, old_mxcsr, cur_ex;
|
||||
asm volatile (STMXCSR " %0" : "=m" (*&mxcsr));
|
||||
asm volatile (STMXCSR " %0" : "=m" (mxcsr));
|
||||
cur_ex = mxcsr & FE_ALL_EXCEPT;
|
||||
|
||||
/* Merge current exceptions with the old environment. */
|
||||
old_mxcsr = e->__mxcsr;
|
||||
mxcsr = old_mxcsr | cur_ex;
|
||||
asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
|
||||
asm volatile (LDMXCSR " %0" : : "m" (mxcsr));
|
||||
|
||||
/* Raise SIGFPE for any new exceptions since the hold. Expect that
|
||||
the normal environment has all exceptions masked. */
|
||||
|
@ -189,10 +189,10 @@ static __always_inline void
|
|||
libc_feholdsetround_sse (fenv_t *e, int r)
|
||||
{
|
||||
unsigned int mxcsr;
|
||||
asm (STMXCSR " %0" : "=m" (*&mxcsr));
|
||||
asm (STMXCSR " %0" : "=m" (mxcsr));
|
||||
e->__mxcsr = mxcsr;
|
||||
mxcsr = (mxcsr & ~0x6000) | (r << 3);
|
||||
asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
|
||||
asm volatile (LDMXCSR " %0" : : "m" (mxcsr));
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
|
@ -223,9 +223,9 @@ static __always_inline void
|
|||
libc_feresetround_sse (fenv_t *e)
|
||||
{
|
||||
unsigned int mxcsr;
|
||||
asm (STMXCSR " %0" : "=m" (*&mxcsr));
|
||||
asm (STMXCSR " %0" : "=m" (mxcsr));
|
||||
mxcsr = (mxcsr & ~0x6000) | (e->__mxcsr & 0x6000);
|
||||
asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
|
||||
asm volatile (LDMXCSR " %0" : : "m" (mxcsr));
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
|
@ -315,13 +315,13 @@ static __always_inline void
|
|||
libc_feholdexcept_setround_sse_ctx (struct rm_ctx *ctx, int r)
|
||||
{
|
||||
unsigned int mxcsr, new_mxcsr;
|
||||
asm (STMXCSR " %0" : "=m" (*&mxcsr));
|
||||
asm (STMXCSR " %0" : "=m" (mxcsr));
|
||||
new_mxcsr = ((mxcsr | 0x1f80) & ~0x603f) | (r << 3);
|
||||
|
||||
ctx->env.__mxcsr = mxcsr;
|
||||
if (__glibc_unlikely (mxcsr != new_mxcsr))
|
||||
{
|
||||
asm volatile (LDMXCSR " %0" : : "m" (*&new_mxcsr));
|
||||
asm volatile (LDMXCSR " %0" : : "m" (new_mxcsr));
|
||||
ctx->updated_status = true;
|
||||
}
|
||||
else
|
||||
|
@ -412,13 +412,13 @@ libc_feholdsetround_sse_ctx (struct rm_ctx *ctx, int r)
|
|||
{
|
||||
unsigned int mxcsr, new_mxcsr;
|
||||
|
||||
asm (STMXCSR " %0" : "=m" (*&mxcsr));
|
||||
asm (STMXCSR " %0" : "=m" (mxcsr));
|
||||
new_mxcsr = (mxcsr & ~0x6000) | (r << 3);
|
||||
|
||||
ctx->env.__mxcsr = mxcsr;
|
||||
if (__glibc_unlikely (new_mxcsr != mxcsr))
|
||||
{
|
||||
asm volatile (LDMXCSR " %0" : : "m" (*&new_mxcsr));
|
||||
asm volatile (LDMXCSR " %0" : : "m" (new_mxcsr));
|
||||
ctx->updated_status = true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
/* Type of the control word. */
|
||||
typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
|
||||
|
||||
/* Macros for accessing the hardware control word. "*&" is used to
|
||||
/* Macros for accessing the hardware control word. "" is used to
|
||||
work around a bug in older versions of GCC. __volatile__ is used
|
||||
to support combination of writing the control register and reading
|
||||
it back. Without __volatile__, the old value may be used for reading
|
||||
|
@ -99,8 +99,8 @@ typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
|
|||
recent hardware nor on x86-64. Some floating point operations are
|
||||
executed in the SSE/SSE2 engines which have their own control and
|
||||
status register. */
|
||||
#define _FPU_GETCW(cw) __asm__ __volatile__ ("fnstcw %0" : "=m" (*&cw))
|
||||
#define _FPU_SETCW(cw) __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw))
|
||||
#define _FPU_GETCW(cw) __asm__ __volatile__ ("fnstcw %0" : "=m" (cw))
|
||||
#define _FPU_SETCW(cw) __asm__ __volatile__ ("fldcw %0" : : "m" (cw))
|
||||
|
||||
/* Default control word set at startup. */
|
||||
extern fpu_control_t __fpu_control;
|
||||
|
|
|
@ -29,22 +29,22 @@ __feclearexcept (int excepts)
|
|||
|
||||
/* Bah, we have to clear selected exceptions. Since there is no
|
||||
`fldsw' instruction we have to do it the hard way. */
|
||||
__asm__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
/* Clear the relevant bits. */
|
||||
temp.__status_word &= excepts ^ FE_ALL_EXCEPT;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ ("fldenv %0" : : "m" (temp));
|
||||
|
||||
/* And the same procedure for SSE. */
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
|
||||
__asm__ ("stmxcsr %0" : "=m" (mxcsr));
|
||||
|
||||
/* Clear the relevant bits. */
|
||||
mxcsr &= ~excepts;
|
||||
|
||||
/* And put them into effect. */
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (mxcsr));
|
||||
|
||||
/* Success. */
|
||||
return 0;
|
||||
|
|
|
@ -27,19 +27,19 @@ fedisableexcept (int excepts)
|
|||
excepts &= FE_ALL_EXCEPT;
|
||||
|
||||
/* Get the current control word of the x87 FPU. */
|
||||
__asm__ ("fstcw %0" : "=m" (*&new_exc));
|
||||
__asm__ ("fstcw %0" : "=m" (new_exc));
|
||||
|
||||
old_exc = (~new_exc) & FE_ALL_EXCEPT;
|
||||
|
||||
new_exc |= excepts;
|
||||
__asm__ ("fldcw %0" : : "m" (*&new_exc));
|
||||
__asm__ ("fldcw %0" : : "m" (new_exc));
|
||||
|
||||
/* And now the same for the SSE MXCSR register. */
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&new));
|
||||
__asm__ ("stmxcsr %0" : "=m" (new));
|
||||
|
||||
/* The SSE exception masks are shifted by 7 bits. */
|
||||
new |= excepts << 7;
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&new));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (new));
|
||||
|
||||
return old_exc;
|
||||
}
|
||||
|
|
|
@ -27,19 +27,19 @@ feenableexcept (int excepts)
|
|||
excepts &= FE_ALL_EXCEPT;
|
||||
|
||||
/* Get the current control word of the x87 FPU. */
|
||||
__asm__ ("fstcw %0" : "=m" (*&new_exc));
|
||||
__asm__ ("fstcw %0" : "=m" (new_exc));
|
||||
|
||||
old_exc = (~new_exc) & FE_ALL_EXCEPT;
|
||||
|
||||
new_exc &= ~excepts;
|
||||
__asm__ ("fldcw %0" : : "m" (*&new_exc));
|
||||
__asm__ ("fldcw %0" : : "m" (new_exc));
|
||||
|
||||
/* And now the same for the SSE MXCSR register. */
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&new));
|
||||
__asm__ ("stmxcsr %0" : "=m" (new));
|
||||
|
||||
/* The SSE exception masks are shifted by 7 bits. */
|
||||
new &= ~(excepts << 7);
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&new));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (new));
|
||||
|
||||
return old_exc;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ fegetexcept (void)
|
|||
unsigned short int exc;
|
||||
|
||||
/* Get the current control word. */
|
||||
__asm__ ("fstcw %0" : "=m" (*&exc));
|
||||
__asm__ ("fstcw %0" : "=m" (exc));
|
||||
|
||||
return (~exc) & FE_ALL_EXCEPT;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ __fegetround (void)
|
|||
/* We only check the x87 FPU unit. The SSE unit should be the same
|
||||
- and if it's not the same there's no way to signal it. */
|
||||
|
||||
__asm__ ("fnstcw %0" : "=m" (*&cw));
|
||||
__asm__ ("fnstcw %0" : "=m" (cw));
|
||||
|
||||
return cw & 0xc00;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ __feholdexcept (fenv_t *envp)
|
|||
|
||||
/* Set the SSE MXCSR register. */
|
||||
mxcsr = (envp->__mxcsr | 0x1f80) & ~0x3f;
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (mxcsr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ __fesetenv (const fenv_t *envp)
|
|||
Therefore, we get the current environment and replace the values
|
||||
we want to use from the environment specified by the parameter. */
|
||||
__asm__ ("fnstenv %0\n"
|
||||
"stmxcsr %1" : "=m" (*&temp), "=m" (*&temp.__mxcsr));
|
||||
"stmxcsr %1" : "=m" (temp), "=m" (temp.__mxcsr));
|
||||
|
||||
if (envp == FE_DFL_ENV)
|
||||
{
|
||||
|
|
|
@ -23,9 +23,9 @@ fesetexcept (int excepts)
|
|||
{
|
||||
unsigned int mxcsr;
|
||||
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
|
||||
__asm__ ("stmxcsr %0" : "=m" (mxcsr));
|
||||
mxcsr |= excepts & FE_ALL_EXCEPT;
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (mxcsr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -29,17 +29,17 @@ __fesetround (int round)
|
|||
return 1;
|
||||
|
||||
/* First set the x87 FPU. */
|
||||
asm ("fnstcw %0" : "=m" (*&cw));
|
||||
asm ("fnstcw %0" : "=m" (cw));
|
||||
cw &= ~0xc00;
|
||||
cw |= round;
|
||||
asm ("fldcw %0" : : "m" (*&cw));
|
||||
asm ("fldcw %0" : : "m" (cw));
|
||||
|
||||
/* And now the MSCSR register for SSE, the precision is at different bit
|
||||
positions in the different units, we need to shift it 3 bits. */
|
||||
asm ("stmxcsr %0" : "=m" (*&mxcsr));
|
||||
asm ("stmxcsr %0" : "=m" (mxcsr));
|
||||
mxcsr &= ~ 0x6000;
|
||||
mxcsr |= round << 3;
|
||||
asm ("ldmxcsr %0" : : "m" (*&mxcsr));
|
||||
asm ("ldmxcsr %0" : : "m" (mxcsr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ __feupdateenv (const fenv_t *envp)
|
|||
unsigned int xtemp;
|
||||
|
||||
/* Save current exceptions. */
|
||||
__asm__ ("fnstsw %0\n\tstmxcsr %1" : "=m" (*&temp), "=m" (xtemp));
|
||||
__asm__ ("fnstsw %0\n\tstmxcsr %1" : "=m" (temp), "=m" (xtemp));
|
||||
temp = (temp | xtemp) & FE_ALL_EXCEPT;
|
||||
|
||||
/* Install new environment. */
|
||||
|
|
|
@ -26,7 +26,7 @@ fegetexceptflag (fexcept_t *flagp, int excepts)
|
|||
|
||||
/* Get the current exceptions for the x87 FPU and SSE unit. */
|
||||
__asm__ ("fnstsw %0\n"
|
||||
"stmxcsr %1" : "=m" (*&temp), "=m" (*&mxscr));
|
||||
"stmxcsr %1" : "=m" (temp), "=m" (mxscr));
|
||||
|
||||
*flagp = (temp | mxscr) & FE_ALL_EXCEPT & excepts;
|
||||
|
||||
|
|
|
@ -57,13 +57,13 @@ __feraiseexcept (int excepts)
|
|||
|
||||
/* Bah, we have to clear selected exceptions. Since there is no
|
||||
`fldsw' instruction we have to do it the hard way. */
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
/* Set the relevant bits. */
|
||||
temp.__status_word |= FE_OVERFLOW;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (temp));
|
||||
|
||||
/* And raise the exception. */
|
||||
__asm__ __volatile__ ("fwait");
|
||||
|
@ -79,13 +79,13 @@ __feraiseexcept (int excepts)
|
|||
|
||||
/* Bah, we have to clear selected exceptions. Since there is no
|
||||
`fldsw' instruction we have to do it the hard way. */
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
/* Set the relevant bits. */
|
||||
temp.__status_word |= FE_UNDERFLOW;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (temp));
|
||||
|
||||
/* And raise the exception. */
|
||||
__asm__ __volatile__ ("fwait");
|
||||
|
@ -101,13 +101,13 @@ __feraiseexcept (int excepts)
|
|||
|
||||
/* Bah, we have to clear selected exceptions. Since there is no
|
||||
`fldsw' instruction we have to do it the hard way. */
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
/* Set the relevant bits. */
|
||||
temp.__status_word |= FE_INEXACT;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ __volatile__ ("fldenv %0" : : "m" (temp));
|
||||
|
||||
/* And raise the exception. */
|
||||
__asm__ __volatile__ ("fwait");
|
||||
|
|
|
@ -35,22 +35,22 @@ fesetexceptflag (const fexcept_t *flagp, int excepts)
|
|||
|
||||
/* Get the current x87 FPU environment. We have to do this since we
|
||||
cannot separately set the status word. */
|
||||
__asm__ ("fnstenv %0" : "=m" (*&temp));
|
||||
__asm__ ("fnstenv %0" : "=m" (temp));
|
||||
|
||||
/* Clear relevant flags. */
|
||||
temp.__status_word &= ~(excepts & ~ *flagp);
|
||||
|
||||
/* Store the new status word (along with the rest of the environment). */
|
||||
__asm__ ("fldenv %0" : : "m" (*&temp));
|
||||
__asm__ ("fldenv %0" : : "m" (temp));
|
||||
|
||||
/* And now similarly for SSE. */
|
||||
__asm__ ("stmxcsr %0" : "=m" (*&mxcsr));
|
||||
__asm__ ("stmxcsr %0" : "=m" (mxcsr));
|
||||
|
||||
/* Clear or set relevant flags. */
|
||||
mxcsr ^= (mxcsr ^ *flagp) & excepts;
|
||||
|
||||
/* Put the new data in effect. */
|
||||
__asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
|
||||
__asm__ ("ldmxcsr %0" : : "m" (mxcsr));
|
||||
|
||||
/* Success. */
|
||||
return 0;
|
||||
|
|
|
@ -26,7 +26,7 @@ __fetestexcept (int excepts)
|
|||
|
||||
/* Get current exceptions. */
|
||||
__asm__ ("fnstsw %0\n"
|
||||
"stmxcsr %1" : "=m" (*&temp), "=m" (*&mxscr));
|
||||
"stmxcsr %1" : "=m" (temp), "=m" (mxscr));
|
||||
|
||||
return (temp | mxscr) & excepts & FE_ALL_EXCEPT;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue