am 04e115c7: am 385f7009: Merge "Move x86 fenv implementation details into fenv.c."

* commit '04e115c7f9a90002c2e80a490848890ec284699b':
  Move x86 fenv implementation details into fenv.c.
This commit is contained in:
Elliott Hughes 2014-06-11 17:58:38 +00:00 committed by Android Git Automerger
commit 1aecbb85ce
4 changed files with 25 additions and 25 deletions

View File

@ -30,6 +30,15 @@
#include <fenv.h> #include <fenv.h>
#include <machine/fpu.h> #include <machine/fpu.h>
#define SSE_MASK_SHIFT 7
/*
* The following symbol is simply the bitwise-inclusive OR of all floating-point
* rounding direction constants defined above.
*/
#define X87_ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
#define SSE_ROUND_SHIFT 3
/* /*
* The following constant represents the default floating-point environment * The following constant represents the default floating-point environment
* (that is, the one installed at program startup) and has type pointer to * (that is, the one installed at program startup) and has type pointer to
@ -203,7 +212,7 @@ fegetround(void)
*/ */
__asm__ __volatile__ ("fnstcw %0" : "=m" (control)); __asm__ __volatile__ ("fnstcw %0" : "=m" (control));
return (control & _X87_ROUND_MASK); return (control & X87_ROUND_MASK);
} }
/* /*
@ -218,14 +227,14 @@ fesetround(int round)
unsigned int mxcsr; unsigned int mxcsr;
/* Check whether requested rounding direction is supported */ /* Check whether requested rounding direction is supported */
if (round & ~_X87_ROUND_MASK) if (round & ~X87_ROUND_MASK)
return (-1); return (-1);
/* Store the current x87 control word register */ /* Store the current x87 control word register */
__asm__ __volatile__ ("fnstcw %0" : "=m" (control)); __asm__ __volatile__ ("fnstcw %0" : "=m" (control));
/* Set the rounding direction */ /* Set the rounding direction */
control &= ~_X87_ROUND_MASK; control &= ~X87_ROUND_MASK;
control |= round; control |= round;
/* Load the x87 control word register */ /* Load the x87 control word register */
@ -233,8 +242,8 @@ fesetround(int round)
/* Same for the SSE environment */ /* Same for the SSE environment */
__asm__ __volatile__ ("stmxcsr %0" : "=m" (mxcsr)); __asm__ __volatile__ ("stmxcsr %0" : "=m" (mxcsr));
mxcsr &= ~(_X87_ROUND_MASK << _SSE_ROUND_SHIFT); mxcsr &= ~(X87_ROUND_MASK << SSE_ROUND_SHIFT);
mxcsr |= round << _SSE_ROUND_SHIFT; mxcsr |= round << SSE_ROUND_SHIFT;
__asm__ __volatile__ ("ldmxcsr %0" : : "m" (mxcsr)); __asm__ __volatile__ ("ldmxcsr %0" : : "m" (mxcsr));
return (0); return (0);
@ -291,7 +300,7 @@ feholdexcept(fenv_t *envp)
mxcsr &= ~FE_ALL_EXCEPT; mxcsr &= ~FE_ALL_EXCEPT;
/* Mask all exceptions */ /* Mask all exceptions */
mxcsr |= FE_ALL_EXCEPT << _SSE_MASK_SHIFT; mxcsr |= FE_ALL_EXCEPT << SSE_MASK_SHIFT;
/* Store the MXCSR register */ /* Store the MXCSR register */
__asm__ __volatile__ ("ldmxcsr %0" : : "m" (mxcsr)); __asm__ __volatile__ ("ldmxcsr %0" : : "m" (mxcsr));
@ -362,11 +371,11 @@ feenableexcept(int mask)
__asm__ __volatile__ ("fnstcw %0" : "=m" (control)); __asm__ __volatile__ ("fnstcw %0" : "=m" (control));
__asm__ __volatile__ ("stmxcsr %0" : "=m" (mxcsr)); __asm__ __volatile__ ("stmxcsr %0" : "=m" (mxcsr));
omask = ~(control | (mxcsr >> _SSE_MASK_SHIFT)) & FE_ALL_EXCEPT; omask = ~(control | (mxcsr >> SSE_MASK_SHIFT)) & FE_ALL_EXCEPT;
control &= ~mask; control &= ~mask;
__asm__ __volatile__ ("fldcw %0" : : "m" (control)); __asm__ __volatile__ ("fldcw %0" : : "m" (control));
mxcsr &= ~(mask << _SSE_MASK_SHIFT); mxcsr &= ~(mask << SSE_MASK_SHIFT);
__asm__ __volatile__ ("ldmxcsr %0" : : "m" (mxcsr)); __asm__ __volatile__ ("ldmxcsr %0" : : "m" (mxcsr));
return (omask); return (omask);
@ -383,11 +392,11 @@ fedisableexcept(int mask)
__asm__ __volatile__ ("fnstcw %0" : "=m" (control)); __asm__ __volatile__ ("fnstcw %0" : "=m" (control));
__asm__ __volatile__ ("stmxcsr %0" : "=m" (mxcsr)); __asm__ __volatile__ ("stmxcsr %0" : "=m" (mxcsr));
omask = ~(control | (mxcsr >> _SSE_MASK_SHIFT)) & FE_ALL_EXCEPT; omask = ~(control | (mxcsr >> SSE_MASK_SHIFT)) & FE_ALL_EXCEPT;
control |= mask; control |= mask;
__asm__ __volatile__ ("fldcw %0" : : "m" (control)); __asm__ __volatile__ ("fldcw %0" : : "m" (control));
mxcsr |= mask << _SSE_MASK_SHIFT; mxcsr |= mask << SSE_MASK_SHIFT;
__asm__ __volatile__ ("ldmxcsr %0" : : "m" (mxcsr)); __asm__ __volatile__ ("ldmxcsr %0" : : "m" (mxcsr));
return (omask); return (omask);

View File

@ -31,6 +31,8 @@
#include "npx.h" #include "npx.h"
#include "fenv.h" #include "fenv.h"
#define ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
/* /*
* As compared to the x87 control word, the SSE unit's control word * As compared to the x87 control word, the SSE unit's control word
* has the rounding control bits offset by 3 and the exception mask * has the rounding control bits offset by 3 and the exception mask
@ -327,7 +329,7 @@ fegetround(void)
* unit on an Opteron 244. * unit on an Opteron 244.
*/ */
__fnstcw(&control); __fnstcw(&control);
return (control & _ROUND_MASK); return (control & ROUND_MASK);
} }
int int
@ -336,16 +338,16 @@ fesetround(int round)
__uint32_t mxcsr; __uint32_t mxcsr;
__uint16_t control; __uint16_t control;
if (round & ~_ROUND_MASK) { if (round & ~ROUND_MASK) {
return (-1); return (-1);
} else { } else {
__fnstcw(&control); __fnstcw(&control);
control &= ~_ROUND_MASK; control &= ~ROUND_MASK;
control |= round; control |= round;
__fldcw(control); __fldcw(control);
if (__HAS_SSE()) { if (__HAS_SSE()) {
__stmxcsr(&mxcsr); __stmxcsr(&mxcsr);
mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT); mxcsr &= ~(ROUND_MASK << _SSE_ROUND_SHIFT);
mxcsr |= round << _SSE_ROUND_SHIFT; mxcsr |= round << _SSE_ROUND_SHIFT;
__ldmxcsr(mxcsr); __ldmxcsr(mxcsr);
} }

View File

@ -51,7 +51,6 @@ __BEGIN_DECLS
*/ */
#define FE_ALL_EXCEPT (FE_INVALID | FE_DENORMAL | FE_DIVBYZERO | \ #define FE_ALL_EXCEPT (FE_INVALID | FE_DENORMAL | FE_DIVBYZERO | \
FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
#define _SSE_MASK_SHIFT 7
/* /*
* Each symbol representing the rounding direction, expands to an integer * Each symbol representing the rounding direction, expands to an integer
@ -64,14 +63,6 @@ __BEGIN_DECLS
#define FE_UPWARD 0x800 #define FE_UPWARD 0x800
#define FE_TOWARDZERO 0xc00 #define FE_TOWARDZERO 0xc00
/*
* The following symbol is simply the bitwise-inclusive OR of all floating-point
* rounding direction constants defined above.
*/
#define _X87_ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | \
FE_TOWARDZERO)
#define _SSE_ROUND_SHIFT 3
/* /*
* fenv_t represents the entire floating-point environment. * fenv_t represents the entire floating-point environment.
*/ */

View File

@ -63,8 +63,6 @@ typedef __uint16_t fexcept_t;
#define FE_DOWNWARD 0x0400 #define FE_DOWNWARD 0x0400
#define FE_UPWARD 0x0800 #define FE_UPWARD 0x0800
#define FE_TOWARDZERO 0x0c00 #define FE_TOWARDZERO 0x0c00
#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
FE_UPWARD | FE_TOWARDZERO)
__END_DECLS __END_DECLS