ndk: Fix GB x86 definitions for libm.so

The previous header and implementation were incorrect and didn't produce
correct results. This has been fixed in the internal Gingerbread branch.

Technically, this could result in ABI breakage, but the chances are very
low, and there are no official x86 Gingerbread release yet.

Change-Id: I0b2d857399358775d1490b72a1b75baac362f839
This commit is contained in:
David 'Digit' Turner
2011-10-10 21:43:54 +02:00
parent 28f0525172
commit 4fee0994c3
2 changed files with 27 additions and 157 deletions

View File

@@ -45,13 +45,6 @@ typedef struct {
char __other[16]; char __other[16];
} fenv_t; } fenv_t;
#define __get_mxcsr(env) (((env).__mxcsr_hi << 16) | \
((env).__mxcsr_lo))
#define __set_mxcsr(env, x) do { \
(env).__mxcsr_hi = (__uint32_t)(x) >> 16; \
(env).__mxcsr_lo = (__uint16_t)(x); \
} while (0)
typedef __uint16_t fexcept_t; typedef __uint16_t fexcept_t;
/* Exception flags */ /* Exception flags */
@@ -72,168 +65,35 @@ typedef __uint16_t fexcept_t;
#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
FE_UPWARD | FE_TOWARDZERO) FE_UPWARD | FE_TOWARDZERO)
/*
* 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
* bits offset by 7.
*/
#define _SSE_ROUND_SHIFT 3
#define _SSE_EMASK_SHIFT 7
/* After testing for SSE support once, we cache the result in __has_sse. */
enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK };
extern enum __sse_support __has_sse;
int __test_sse(void);
#ifdef __SSE__
#define __HAS_SSE() 1
#else
#define __HAS_SSE() (__has_sse == __SSE_YES || \
(__has_sse == __SSE_UNK && __test_sse()))
#endif
__BEGIN_DECLS __BEGIN_DECLS
/* Default floating-point environment */ /* Default floating-point environment */
extern const fenv_t __fe_dfl_env; extern const fenv_t __fe_dfl_env;
#define FE_DFL_ENV (&__fe_dfl_env) #define FE_DFL_ENV (&__fe_dfl_env)
#define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw)) /* C99 floating-point exception functions */
#define __fldenv(__env) __asm __volatile("fldenv %0" : : "m" (__env)) int feclearexcept(int excepts);
#define __fnclex() __asm __volatile("fnclex") int fegetexceptflag(fexcept_t *flagp, int excepts);
#define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env))) int fesetexceptflag(const fexcept_t *flagp, int excepts);
#define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw))) /* feraiseexcept does not set the inexact flag on overflow/underflow */
#define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=a" (*(__sw))) int feraiseexcept(int excepts);
#define __fwait() __asm __volatile("fwait") int fetestexcept(int excepts);
#define __ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr))
#define __stmxcsr(__csr) __asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
static __inline int /* C99 rounding control functions */
feclearexcept(int __excepts) int fegetround(void);
{ int fesetround(int round);
fenv_t __env;
int __mxcsr;
if (__excepts == FE_ALL_EXCEPT) {
__fnclex();
} else {
__fnstenv(&__env);
__env.__status &= ~__excepts;
__fldenv(__env);
}
if (__HAS_SSE()) {
__stmxcsr(&__mxcsr);
__mxcsr &= ~__excepts;
__ldmxcsr(__mxcsr);
}
return (0);
}
static __inline int
fegetexceptflag(fexcept_t *__flagp, int __excepts)
{
int __mxcsr;
short __status;
__fnstsw(&__status);
if (__HAS_SSE())
__stmxcsr(&__mxcsr);
else
__mxcsr = 0;
*__flagp = (__mxcsr | __status) & __excepts;
return (0);
}
int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
int feraiseexcept(int __excepts);
static __inline int
fetestexcept(int __excepts)
{
int __mxcsr;
short __status;
__fnstsw(&__status);
if (__HAS_SSE())
__stmxcsr(&__mxcsr);
else
__mxcsr = 0;
return ((__status | __mxcsr) & __excepts);
}
static __inline int
fegetround(void)
{
int __control;
/*
* We assume that the x87 and the SSE unit agree on the
* rounding mode. Reading the control word on the x87 turns
* out to be about 5 times faster than reading it on the SSE
* unit on an Opteron 244.
*/
__fnstcw(&__control);
return (__control & _ROUND_MASK);
}
static __inline int
fesetround(int __round)
{
int __mxcsr, __control;
if (__round & ~_ROUND_MASK)
return (-1);
__fnstcw(&__control);
__control &= ~_ROUND_MASK;
__control |= __round;
__fldcw(__control);
if (__HAS_SSE()) {
__stmxcsr(&__mxcsr);
__mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
__mxcsr |= __round << _SSE_ROUND_SHIFT;
__ldmxcsr(__mxcsr);
}
return (0);
}
/* C99 floating-point environment functions */
int fegetenv(fenv_t *__envp); int fegetenv(fenv_t *__envp);
int feholdexcept(fenv_t *__envp); int feholdexcept(fenv_t *__envp);
int fesetenv(const fenv_t *envp);
static __inline int
fesetenv(const fenv_t *__envp)
{
fenv_t __env = *__envp;
int __mxcsr;
__mxcsr = __get_mxcsr(__env);
__set_mxcsr(__env, 0xffffffff);
__fldenv(__env);
if (__HAS_SSE())
__ldmxcsr(__mxcsr);
return (0);
}
int feupdateenv(const fenv_t *__envp); int feupdateenv(const fenv_t *__envp);
#if __BSD_VISIBLE #if __BSD_VISIBLE
/* Additional support functions to set/query floating point traps */
int feenableexcept(int __mask); int feenableexcept(int __mask);
int fedisableexcept(int __mask); int fedisableexcept(int __mask);
int fegetexcept(void);
static __inline int
fegetexcept(void)
{
int __control;
/*
* We assume that the masks for the x87 and the SSE unit are
* the same.
*/
__fnstcw(&__control);
return (~__control & FE_ALL_EXCEPT);
}
#endif /* __BSD_VISIBLE */ #endif /* __BSD_VISIBLE */

View File

@@ -1,6 +1,4 @@
__exp__D __exp__D
__fedisableexcept
__feenableexcept
__fpclassifyd __fpclassifyd
__fpclassifyf __fpclassifyf
__fpclassifyl __fpclassifyl
@@ -27,7 +25,7 @@ __log__D
__signbit __signbit
__signbitf __signbitf
__signbitl __signbitl
__test_sse _scan_nan
acos acos
acosf acosf
acosh acosh
@@ -72,10 +70,19 @@ fabsl
fdim fdim
fdimf fdimf
fdiml fdiml
feclearexcept
fedisableexcept
feenableexcept
fegetenv fegetenv
fegetexcept
fegetexceptflag
fegetround
feholdexcept feholdexcept
feraiseexcept feraiseexcept
fesetenv
fesetexceptflag fesetexceptflag
fesetround
fetestexcept
feupdateenv feupdateenv
finite finite
finitef finitef
@@ -137,6 +144,8 @@ lroundf
lroundl lroundl
modf modf
modff modff
nan
nanf
nearbyint nearbyint
nearbyintf nearbyintf
nextafter nextafter
@@ -174,6 +183,7 @@ tanf
tanh tanh
tanhf tanhf
tgamma tgamma
tgammaf
trunc trunc
truncf truncf
truncl truncl