* commit '04e115c7f9a90002c2e80a490848890ec284699b': Move x86 fenv implementation details into fenv.c.
This commit is contained in:
commit
1aecbb85ce
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user