libroot: Drop a lot of glibc-internal headers that are not needed.
No functional change intended.
This commit is contained in:
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* IBM Accurate Mathematical Library
|
||||
* Written by International Business Machines Corp.
|
||||
* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/***********************************************************************/
|
||||
/*MODULE_NAME: dla.h */
|
||||
/* */
|
||||
/* This file holds C language macros for 'Double Length Floating Point */
|
||||
/* Arithmetic'. The macros are based on the paper: */
|
||||
/* T.J.Dekker, "A floating-point Technique for extending the */
|
||||
/* Available Precision", Number. Math. 18, 224-242 (1971). */
|
||||
/* A Double-Length number is defined by a pair (r,s), of IEEE double */
|
||||
/* precision floating point numbers that satisfy, */
|
||||
/* */
|
||||
/* abs(s) <= abs(r+s)*2**(-53)/(1+2**(-53)). */
|
||||
/* */
|
||||
/* The computer arithmetic assumed is IEEE double precision in */
|
||||
/* round to nearest mode. All variables in the macros must be of type */
|
||||
/* IEEE double. */
|
||||
/***********************************************************************/
|
||||
|
||||
/* CN = 1+2**27 = '41a0000002000000' IEEE double format */
|
||||
#define CN 134217729.0
|
||||
|
||||
|
||||
/* Exact addition of two single-length floating point numbers, Dekker. */
|
||||
/* The macro produces a double-length number (z,zz) that satisfies */
|
||||
/* z+zz = x+y exactly. */
|
||||
|
||||
#define EADD(x,y,z,zz) \
|
||||
z=(x)+(y); zz=(ABS(x)>ABS(y)) ? (((x)-(z))+(y)) : (((y)-(z))+(x));
|
||||
|
||||
|
||||
/* Exact subtraction of two single-length floating point numbers, Dekker. */
|
||||
/* The macro produces a double-length number (z,zz) that satisfies */
|
||||
/* z+zz = x-y exactly. */
|
||||
|
||||
#define ESUB(x,y,z,zz) \
|
||||
z=(x)-(y); zz=(ABS(x)>ABS(y)) ? (((x)-(z))-(y)) : ((x)-((y)+(z)));
|
||||
|
||||
|
||||
/* Exact multiplication of two single-length floating point numbers, */
|
||||
/* Veltkamp. The macro produces a double-length number (z,zz) that */
|
||||
/* satisfies z+zz = x*y exactly. p,hx,tx,hy,ty are temporary */
|
||||
/* storage variables of type double. */
|
||||
|
||||
#define EMULV(x,y,z,zz,p,hx,tx,hy,ty) \
|
||||
p=CN*(x); hx=((x)-p)+p; tx=(x)-hx; \
|
||||
p=CN*(y); hy=((y)-p)+p; ty=(y)-hy; \
|
||||
z=(x)*(y); zz=(((hx*hy-z)+hx*ty)+tx*hy)+tx*ty;
|
||||
|
||||
|
||||
/* Exact multiplication of two single-length floating point numbers, Dekker. */
|
||||
/* The macro produces a nearly double-length number (z,zz) (see Dekker) */
|
||||
/* that satisfies z+zz = x*y exactly. p,hx,tx,hy,ty,q are temporary */
|
||||
/* storage variables of type double. */
|
||||
|
||||
#define MUL12(x,y,z,zz,p,hx,tx,hy,ty,q) \
|
||||
p=CN*(x); hx=((x)-p)+p; tx=(x)-hx; \
|
||||
p=CN*(y); hy=((y)-p)+p; ty=(y)-hy; \
|
||||
p=hx*hy; q=hx*ty+tx*hy; z=p+q; zz=((p-z)+q)+tx*ty;
|
||||
|
||||
|
||||
/* Double-length addition, Dekker. The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = x+xx + y+yy. */
|
||||
/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. r,s are temporary */
|
||||
/* storage variables of type double. */
|
||||
|
||||
#define ADD2(x,xx,y,yy,z,zz,r,s) \
|
||||
r=(x)+(y); s=(ABS(x)>ABS(y)) ? \
|
||||
(((((x)-r)+(y))+(yy))+(xx)) : \
|
||||
(((((y)-r)+(x))+(xx))+(yy)); \
|
||||
z=r+s; zz=(r-z)+s;
|
||||
|
||||
|
||||
/* Double-length subtraction, Dekker. The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = x+xx - (y+yy). */
|
||||
/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. r,s are temporary */
|
||||
/* storage variables of type double. */
|
||||
|
||||
#define SUB2(x,xx,y,yy,z,zz,r,s) \
|
||||
r=(x)-(y); s=(ABS(x)>ABS(y)) ? \
|
||||
(((((x)-r)-(y))-(yy))+(xx)) : \
|
||||
((((x)-((y)+r))+(xx))-(yy)); \
|
||||
z=r+s; zz=(r-z)+s;
|
||||
|
||||
|
||||
/* Double-length multiplication, Dekker. The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = (x+xx)*(y+yy). */
|
||||
/* An error bound: abs((x+xx)*(y+yy))*1.24e-31. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc are */
|
||||
/* temporary storage variables of type double. */
|
||||
|
||||
#define MUL2(x,xx,y,yy,z,zz,p,hx,tx,hy,ty,q,c,cc) \
|
||||
MUL12(x,y,c,cc,p,hx,tx,hy,ty,q) \
|
||||
cc=((x)*(yy)+(xx)*(y))+cc; z=c+cc; zz=(c-z)+cc;
|
||||
|
||||
|
||||
/* Double-length division, Dekker. The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = (x+xx)/(y+yy). */
|
||||
/* An error bound: abs((x+xx)/(y+yy))*1.50e-31. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc,u,uu */
|
||||
/* are temporary storage variables of type double. */
|
||||
|
||||
#define DIV2(x,xx,y,yy,z,zz,p,hx,tx,hy,ty,q,c,cc,u,uu) \
|
||||
c=(x)/(y); MUL12(c,y,u,uu,p,hx,tx,hy,ty,q) \
|
||||
cc=(((((x)-u)-uu)+(xx))-c*(yy))/(y); z=c+cc; zz=(c-z)+cc;
|
||||
|
||||
|
||||
/* Double-length addition, slower but more accurate than ADD2. */
|
||||
/* The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = (x+xx)+(y+yy). */
|
||||
/* An error bound: abs(x+xx + y+yy)*1.50e-31. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */
|
||||
/* are temporary storage variables of type double. */
|
||||
|
||||
#define ADD2A(x,xx,y,yy,z,zz,r,rr,s,ss,u,uu,w) \
|
||||
r=(x)+(y); \
|
||||
if (ABS(x)>ABS(y)) { rr=((x)-r)+(y); s=(rr+(yy))+(xx); } \
|
||||
else { rr=((y)-r)+(x); s=(rr+(xx))+(yy); } \
|
||||
if (rr!=0.0) { \
|
||||
z=r+s; zz=(r-z)+s; } \
|
||||
else { \
|
||||
ss=(ABS(xx)>ABS(yy)) ? (((xx)-s)+(yy)) : (((yy)-s)+(xx)); \
|
||||
u=r+s; \
|
||||
uu=(ABS(r)>ABS(s)) ? ((r-u)+s) : ((s-u)+r) ; \
|
||||
w=uu+ss; z=u+w; \
|
||||
zz=(ABS(u)>ABS(w)) ? ((u-z)+w) : ((w-z)+u) ; }
|
||||
|
||||
|
||||
/* Double-length subtraction, slower but more accurate than SUB2. */
|
||||
/* The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = (x+xx)-(y+yy). */
|
||||
/* An error bound: abs(x+xx - (y+yy))*1.50e-31. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */
|
||||
/* are temporary storage variables of type double. */
|
||||
|
||||
#define SUB2A(x,xx,y,yy,z,zz,r,rr,s,ss,u,uu,w) \
|
||||
r=(x)-(y); \
|
||||
if (ABS(x)>ABS(y)) { rr=((x)-r)-(y); s=(rr-(yy))+(xx); } \
|
||||
else { rr=(x)-((y)+r); s=(rr+(xx))-(yy); } \
|
||||
if (rr!=0.0) { \
|
||||
z=r+s; zz=(r-z)+s; } \
|
||||
else { \
|
||||
ss=(ABS(xx)>ABS(yy)) ? (((xx)-s)-(yy)) : ((xx)-((yy)+s)); \
|
||||
u=r+s; \
|
||||
uu=(ABS(r)>ABS(s)) ? ((r-u)+s) : ((s-u)+r) ; \
|
||||
w=uu+ss; z=u+w; \
|
||||
zz=(ABS(u)>ABS(w)) ? ((u-z)+w) : ((w-z)+u) ; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#warning ARM: check mathinline.h
|
||||
@@ -1,251 +0,0 @@
|
||||
/* Private floating point rounding and exceptions handling. ARM VFP version.
|
||||
Copyright (C) 2014-2018 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef FENV_PRIVATE_H
|
||||
#define FENV_PRIVATE_H 1
|
||||
|
||||
#include <fenv.h>
|
||||
#include <fpu_control.h>
|
||||
|
||||
# define __glibc_unlikely(x) __builtin_expect ((x), 0)
|
||||
|
||||
static __always_inline void
|
||||
libc_feholdexcept_vfp (fenv_t *envp)
|
||||
{
|
||||
fpu_control_t fpscr;
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
envp->__cw = fpscr;
|
||||
|
||||
/* Clear exception flags and set all exceptions to non-stop. */
|
||||
fpscr &= ~_FPU_MASK_EXCEPT;
|
||||
_FPU_SETCW (fpscr);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_fesetround_vfp (int round)
|
||||
{
|
||||
fpu_control_t fpscr;
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
|
||||
/* Set new rounding mode if different. */
|
||||
if (__glibc_unlikely ((fpscr & _FPU_MASK_RM) != round))
|
||||
_FPU_SETCW ((fpscr & ~_FPU_MASK_RM) | round);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feholdexcept_setround_vfp (fenv_t *envp, int round)
|
||||
{
|
||||
fpu_control_t fpscr;
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
envp->__cw = fpscr;
|
||||
|
||||
/* Clear exception flags, set all exceptions to non-stop,
|
||||
and set new rounding mode. */
|
||||
fpscr &= ~(_FPU_MASK_EXCEPT | _FPU_MASK_RM);
|
||||
_FPU_SETCW (fpscr | round);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feholdsetround_vfp (fenv_t *envp, int round)
|
||||
{
|
||||
fpu_control_t fpscr;
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
envp->__cw = fpscr;
|
||||
|
||||
/* Set new rounding mode if different. */
|
||||
if (__glibc_unlikely ((fpscr & _FPU_MASK_RM) != round))
|
||||
_FPU_SETCW ((fpscr & ~_FPU_MASK_RM) | round);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feresetround_vfp (fenv_t *envp)
|
||||
{
|
||||
fpu_control_t fpscr, round;
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
|
||||
/* Check whether rounding modes are different. */
|
||||
round = (envp->__cw ^ fpscr) & _FPU_MASK_RM;
|
||||
|
||||
/* Restore the rounding mode if it was changed. */
|
||||
if (__glibc_unlikely (round != 0))
|
||||
_FPU_SETCW (fpscr ^ round);
|
||||
}
|
||||
|
||||
static __always_inline int
|
||||
libc_fetestexcept_vfp (int ex)
|
||||
{
|
||||
fpu_control_t fpscr;
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
return fpscr & ex & FE_ALL_EXCEPT;
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_fesetenv_vfp (const fenv_t *envp)
|
||||
{
|
||||
fpu_control_t fpscr, new_fpscr;
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
new_fpscr = envp->__cw;
|
||||
|
||||
/* Write new FPSCR if different (ignoring NZCV flags). */
|
||||
if (__glibc_unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0))
|
||||
_FPU_SETCW (new_fpscr);
|
||||
}
|
||||
|
||||
static __always_inline int
|
||||
libc_feupdateenv_test_vfp (const fenv_t *envp, int ex)
|
||||
{
|
||||
fpu_control_t fpscr, new_fpscr;
|
||||
int excepts;
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
|
||||
/* Merge current exception flags with the saved fenv. */
|
||||
excepts = fpscr & FE_ALL_EXCEPT;
|
||||
new_fpscr = envp->__cw | excepts;
|
||||
|
||||
/* Write new FPSCR if different (ignoring NZCV flags). */
|
||||
if (__glibc_unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0))
|
||||
_FPU_SETCW (new_fpscr);
|
||||
|
||||
/* Raise the exceptions if enabled in the new FP state. */
|
||||
if (__glibc_unlikely (excepts & (new_fpscr >> FE_EXCEPT_SHIFT)))
|
||||
__feraiseexcept (excepts);
|
||||
|
||||
return excepts & ex;
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feupdateenv_vfp (const fenv_t *envp)
|
||||
{
|
||||
libc_feupdateenv_test_vfp (envp, 0);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feholdsetround_vfp_ctx (struct rm_ctx *ctx, int r)
|
||||
{
|
||||
fpu_control_t fpscr, round;
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
ctx->updated_status = false;
|
||||
ctx->env.__cw = fpscr;
|
||||
|
||||
/* Check whether rounding modes are different. */
|
||||
round = (fpscr ^ r) & _FPU_MASK_RM;
|
||||
|
||||
/* Set the rounding mode if changed. */
|
||||
if (__glibc_unlikely (round != 0))
|
||||
{
|
||||
ctx->updated_status = true;
|
||||
_FPU_SETCW (fpscr ^ round);
|
||||
}
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feresetround_vfp_ctx (struct rm_ctx *ctx)
|
||||
{
|
||||
/* Restore the rounding mode if updated. */
|
||||
if (__glibc_unlikely (ctx->updated_status))
|
||||
{
|
||||
fpu_control_t fpscr;
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
fpscr = (fpscr & ~_FPU_MASK_RM) | (ctx->env.__cw & _FPU_MASK_RM);
|
||||
_FPU_SETCW (fpscr);
|
||||
}
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_fesetenv_vfp_ctx (struct rm_ctx *ctx)
|
||||
{
|
||||
fpu_control_t fpscr, new_fpscr;
|
||||
|
||||
_FPU_GETCW (fpscr);
|
||||
new_fpscr = ctx->env.__cw;
|
||||
|
||||
/* Write new FPSCR if different (ignoring NZCV flags). */
|
||||
if (__glibc_unlikely (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0))
|
||||
_FPU_SETCW (new_fpscr);
|
||||
}
|
||||
|
||||
#ifndef __SOFTFP__
|
||||
|
||||
# define libc_feholdexcept libc_feholdexcept_vfp
|
||||
# define libc_feholdexceptf libc_feholdexcept_vfp
|
||||
# define libc_feholdexceptl libc_feholdexcept_vfp
|
||||
|
||||
# define libc_fesetround libc_fesetround_vfp
|
||||
# define libc_fesetroundf libc_fesetround_vfp
|
||||
# define libc_fesetroundl libc_fesetround_vfp
|
||||
|
||||
# define libc_feresetround libc_feresetround_vfp
|
||||
# define libc_feresetroundf libc_feresetround_vfp
|
||||
# define libc_feresetroundl libc_feresetround_vfp
|
||||
|
||||
# define libc_feresetround_noex libc_fesetenv_vfp
|
||||
# define libc_feresetround_noexf libc_fesetenv_vfp
|
||||
# define libc_feresetround_noexl libc_fesetenv_vfp
|
||||
|
||||
# define libc_feholdexcept_setround libc_feholdexcept_setround_vfp
|
||||
# define libc_feholdexcept_setroundf libc_feholdexcept_setround_vfp
|
||||
# define libc_feholdexcept_setroundl libc_feholdexcept_setround_vfp
|
||||
|
||||
# define libc_feholdsetround libc_feholdsetround_vfp
|
||||
# define libc_feholdsetroundf libc_feholdsetround_vfp
|
||||
# define libc_feholdsetroundl libc_feholdsetround_vfp
|
||||
|
||||
# define libc_fetestexcept libc_fetestexcept_vfp
|
||||
# define libc_fetestexceptf libc_fetestexcept_vfp
|
||||
# define libc_fetestexceptl libc_fetestexcept_vfp
|
||||
|
||||
# define libc_fesetenv libc_fesetenv_vfp
|
||||
# define libc_fesetenvf libc_fesetenv_vfp
|
||||
# define libc_fesetenvl libc_fesetenv_vfp
|
||||
|
||||
# define libc_feupdateenv libc_feupdateenv_vfp
|
||||
# define libc_feupdateenvf libc_feupdateenv_vfp
|
||||
# define libc_feupdateenvl libc_feupdateenv_vfp
|
||||
|
||||
# define libc_feupdateenv_test libc_feupdateenv_test_vfp
|
||||
# define libc_feupdateenv_testf libc_feupdateenv_test_vfp
|
||||
# define libc_feupdateenv_testl libc_feupdateenv_test_vfp
|
||||
|
||||
/* We have support for rounding mode context. */
|
||||
#define HAVE_RM_CTX 1
|
||||
|
||||
# define libc_feholdsetround_ctx libc_feholdsetround_vfp_ctx
|
||||
# define libc_feresetround_ctx libc_feresetround_vfp_ctx
|
||||
# define libc_feresetround_noex_ctx libc_fesetenv_vfp_ctx
|
||||
|
||||
# define libc_feholdsetroundf_ctx libc_feholdsetround_vfp_ctx
|
||||
# define libc_feresetroundf_ctx libc_feresetround_vfp_ctx
|
||||
# define libc_feresetround_noexf_ctx libc_fesetenv_vfp_ctx
|
||||
|
||||
# define libc_feholdsetroundl_ctx libc_feholdsetround_vfp_ctx
|
||||
# define libc_feresetroundl_ctx libc_feresetround_vfp_ctx
|
||||
# define libc_feresetround_noexl_ctx libc_fesetenv_vfp_ctx
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* FENV_PRIVATE_H */
|
||||
@@ -1,75 +0,0 @@
|
||||
/* FPU control word definitions. ARM VFP version.
|
||||
Copyright (C) 2004-2018 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _FPU_CONTROL_H
|
||||
#define _FPU_CONTROL_H
|
||||
|
||||
#if !(defined(_LIBC) && !defined(_LIBC_TEST)) && defined(__SOFTFP__)
|
||||
|
||||
#define _FPU_RESERVED 0xffffffff
|
||||
#define _FPU_DEFAULT 0x00000000
|
||||
typedef unsigned int fpu_control_t;
|
||||
#define _FPU_GETCW(cw) (cw) = 0
|
||||
#define _FPU_SETCW(cw) (void) (cw)
|
||||
extern fpu_control_t __fpu_control;
|
||||
|
||||
#else
|
||||
|
||||
/* masking of interrupts */
|
||||
#define _FPU_MASK_IM 0x00000100 /* invalid operation */
|
||||
#define _FPU_MASK_ZM 0x00000200 /* divide by zero */
|
||||
#define _FPU_MASK_OM 0x00000400 /* overflow */
|
||||
#define _FPU_MASK_UM 0x00000800 /* underflow */
|
||||
#define _FPU_MASK_PM 0x00001000 /* inexact */
|
||||
|
||||
#define _FPU_MASK_NZCV 0xf0000000 /* NZCV flags */
|
||||
#define _FPU_MASK_RM 0x00c00000 /* rounding mode */
|
||||
#define _FPU_MASK_EXCEPT 0x00001f1f /* all exception flags */
|
||||
|
||||
/* Some bits in the FPSCR are not yet defined. They must be preserved when
|
||||
modifying the contents. */
|
||||
#define _FPU_RESERVED 0x00086060
|
||||
#define _FPU_DEFAULT 0x00000000
|
||||
|
||||
/* Default + exceptions enabled. */
|
||||
#define _FPU_IEEE (_FPU_DEFAULT | 0x00001f00)
|
||||
|
||||
/* Type of the control word. */
|
||||
typedef unsigned int fpu_control_t;
|
||||
|
||||
/* Macros for accessing the hardware control word. */
|
||||
#ifdef __SOFTFP__
|
||||
/* This is fmrx %0, fpscr. */
|
||||
# define _FPU_GETCW(cw) \
|
||||
__asm__ __volatile__ ("mrc p10, 7, %0, cr1, cr0, 0" : "=r" (cw))
|
||||
/* This is fmxr fpscr, %0. */
|
||||
# define _FPU_SETCW(cw) \
|
||||
__asm__ __volatile__ ("mcr p10, 7, %0, cr1, cr0, 0" : : "r" (cw))
|
||||
#else
|
||||
# define _FPU_GETCW(cw) \
|
||||
__asm__ __volatile__ ("vmrs %0, fpscr" : "=r" (cw))
|
||||
# define _FPU_SETCW(cw) \
|
||||
__asm__ __volatile__ ("vmsr fpscr, %0" : : "r" (cw))
|
||||
#endif
|
||||
|
||||
/* Default control word set at startup. */
|
||||
extern fpu_control_t __fpu_control;
|
||||
|
||||
#endif /* __SOFTFP__ */
|
||||
|
||||
#endif /* _FPU_CONTROL_H */
|
||||
@@ -1 +0,0 @@
|
||||
#warning ARM64: check mathinline.h
|
||||
@@ -1,329 +0,0 @@
|
||||
/* Macros to control TS 18661-3 glibc features where the same
|
||||
definitions are appropriate for all platforms.
|
||||
Copyright (C) 2017-2019 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _BITS_FLOATN_COMMON_H
|
||||
#define _BITS_FLOATN_COMMON_H
|
||||
|
||||
#include <features.h>
|
||||
#include <bits/long-double.h>
|
||||
|
||||
/* This header should be included at the bottom of each bits/floatn.h.
|
||||
It defines the following macros for each _FloatN and _FloatNx type,
|
||||
where the same definitions, or definitions based only on the macros
|
||||
in bits/floatn.h, are appropriate for all glibc configurations. */
|
||||
|
||||
/* Defined to 1 if the current compiler invocation provides a
|
||||
floating-point type with the right format for this type, and this
|
||||
glibc includes corresponding *fN or *fNx interfaces for it. */
|
||||
#define __HAVE_FLOAT16 0
|
||||
#define __HAVE_FLOAT32 1
|
||||
#define __HAVE_FLOAT64 1
|
||||
#define __HAVE_FLOAT32X 1
|
||||
#define __HAVE_FLOAT128X 0
|
||||
|
||||
/* Defined to 1 if the corresponding __HAVE_<type> macro is 1 and the
|
||||
type is the first with its format in the sequence of (the default
|
||||
choices for) float, double, long double, _Float16, _Float32,
|
||||
_Float64, _Float128, _Float32x, _Float64x, _Float128x for this
|
||||
glibc; that is, if functions present once per floating-point format
|
||||
rather than once per type are present for this type.
|
||||
|
||||
All configurations supported by glibc have _Float32 the same format
|
||||
as float, _Float64 and _Float32x the same format as double, the
|
||||
_Float64x the same format as either long double or _Float128. No
|
||||
configurations support _Float128x or, as of GCC 7, have compiler
|
||||
support for a type meeting the requirements for _Float128x. */
|
||||
#define __HAVE_DISTINCT_FLOAT16 __HAVE_FLOAT16
|
||||
#define __HAVE_DISTINCT_FLOAT32 0
|
||||
#define __HAVE_DISTINCT_FLOAT64 0
|
||||
#define __HAVE_DISTINCT_FLOAT32X 0
|
||||
#define __HAVE_DISTINCT_FLOAT64X 0
|
||||
#define __HAVE_DISTINCT_FLOAT128X __HAVE_FLOAT128X
|
||||
|
||||
/* Defined to 1 if the corresponding _FloatN type is not binary compatible
|
||||
with the corresponding ISO C type in the current compilation unit as
|
||||
opposed to __HAVE_DISTINCT_FLOATN, which indicates the default types built
|
||||
in glibc. */
|
||||
#define __HAVE_FLOAT128_UNLIKE_LDBL (__HAVE_DISTINCT_FLOAT128 \
|
||||
&& __LDBL_MANT_DIG__ != 113)
|
||||
|
||||
/* Defined to 1 if any _FloatN or _FloatNx types that are not
|
||||
ABI-distinct are however distinct types at the C language level (so
|
||||
for the purposes of __builtin_types_compatible_p and _Generic). */
|
||||
#if __GNUC_PREREQ (7, 0) && !defined __cplusplus
|
||||
# define __HAVE_FLOATN_NOT_TYPEDEF 1
|
||||
#else
|
||||
# define __HAVE_FLOATN_NOT_TYPEDEF 0
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Defined to concatenate the literal suffix to be used with _FloatN
|
||||
or _FloatNx types, if __HAVE_<type> is 1. The corresponding
|
||||
literal suffixes exist since GCC 7, for C only. */
|
||||
# if __HAVE_FLOAT16
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
/* No corresponding suffix available for this type. */
|
||||
# define __f16(x) ((_Float16) x##f)
|
||||
# else
|
||||
# define __f16(x) x##f16
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT32
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# define __f32(x) x##f
|
||||
# else
|
||||
# define __f32(x) x##f32
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT64
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
# define __f64(x) x##l
|
||||
# else
|
||||
# define __f64(x) x
|
||||
# endif
|
||||
# else
|
||||
# define __f64(x) x##f64
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT32X
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# define __f32x(x) x
|
||||
# else
|
||||
# define __f32x(x) x##f32x
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT64X
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# if __HAVE_FLOAT64X_LONG_DOUBLE
|
||||
# define __f64x(x) x##l
|
||||
# else
|
||||
# define __f64x(x) __f128 (x)
|
||||
# endif
|
||||
# else
|
||||
# define __f64x(x) x##f64x
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT128X
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# error "_Float128X supported but no constant suffix"
|
||||
# else
|
||||
# define __f128x(x) x##f128x
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Defined to a complex type if __HAVE_<type> is 1. */
|
||||
# if __HAVE_FLOAT16
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
typedef _Complex float __cfloat16 __attribute__ ((__mode__ (__HC__)));
|
||||
# define __CFLOAT16 __cfloat16
|
||||
# else
|
||||
# define __CFLOAT16 _Complex _Float16
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT32
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# define __CFLOAT32 _Complex float
|
||||
# else
|
||||
# define __CFLOAT32 _Complex _Float32
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT64
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
# define __CFLOAT64 _Complex long double
|
||||
# else
|
||||
# define __CFLOAT64 _Complex double
|
||||
# endif
|
||||
# else
|
||||
# define __CFLOAT64 _Complex _Float64
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT32X
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# define __CFLOAT32X _Complex double
|
||||
# else
|
||||
# define __CFLOAT32X _Complex _Float32x
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT64X
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# if __HAVE_FLOAT64X_LONG_DOUBLE
|
||||
# define __CFLOAT64X _Complex long double
|
||||
# else
|
||||
# define __CFLOAT64X __CFLOAT128
|
||||
# endif
|
||||
# else
|
||||
# define __CFLOAT64X _Complex _Float64x
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT128X
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# error "_Float128X supported but no complex type"
|
||||
# else
|
||||
# define __CFLOAT128X _Complex _Float128x
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* The remaining of this file provides support for older compilers. */
|
||||
# if __HAVE_FLOAT16
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
typedef float _Float16 __attribute__ ((__mode__ (__HF__)));
|
||||
# endif
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf16() ((_Float16) __builtin_huge_val ())
|
||||
# define __builtin_inff16() ((_Float16) __builtin_inf ())
|
||||
# define __builtin_nanf16(x) ((_Float16) __builtin_nan (x))
|
||||
# define __builtin_nansf16(x) ((_Float16) __builtin_nans (x))
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT32
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
typedef float _Float32;
|
||||
# endif
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf32() (__builtin_huge_valf ())
|
||||
# define __builtin_inff32() (__builtin_inff ())
|
||||
# define __builtin_nanf32(x) (__builtin_nanf (x))
|
||||
# define __builtin_nansf32(x) (__builtin_nansf (x))
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT64
|
||||
|
||||
/* If double, long double and _Float64 all have the same set of
|
||||
values, TS 18661-3 requires the usual arithmetic conversions on
|
||||
long double and _Float64 to produce _Float64. For this to be the
|
||||
case when building with a compiler without a distinct _Float64
|
||||
type, _Float64 must be a typedef for long double, not for
|
||||
double. */
|
||||
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
typedef long double _Float64;
|
||||
# endif
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf64() (__builtin_huge_vall ())
|
||||
# define __builtin_inff64() (__builtin_infl ())
|
||||
# define __builtin_nanf64(x) (__builtin_nanl (x))
|
||||
# define __builtin_nansf64(x) (__builtin_nansl (x))
|
||||
# endif
|
||||
|
||||
# else
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
typedef double _Float64;
|
||||
# endif
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf64() (__builtin_huge_val ())
|
||||
# define __builtin_inff64() (__builtin_inf ())
|
||||
# define __builtin_nanf64(x) (__builtin_nan (x))
|
||||
# define __builtin_nansf64(x) (__builtin_nans (x))
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT32X
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
typedef double _Float32x;
|
||||
# endif
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf32x() (__builtin_huge_val ())
|
||||
# define __builtin_inff32x() (__builtin_inf ())
|
||||
# define __builtin_nanf32x(x) (__builtin_nan (x))
|
||||
# define __builtin_nansf32x(x) (__builtin_nans (x))
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT64X
|
||||
|
||||
# if __HAVE_FLOAT64X_LONG_DOUBLE
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
typedef long double _Float64x;
|
||||
# endif
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf64x() (__builtin_huge_vall ())
|
||||
# define __builtin_inff64x() (__builtin_infl ())
|
||||
# define __builtin_nanf64x(x) (__builtin_nanl (x))
|
||||
# define __builtin_nansf64x(x) (__builtin_nansl (x))
|
||||
# endif
|
||||
|
||||
# else
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
typedef _Float128 _Float64x;
|
||||
# endif
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf64x() (__builtin_huge_valf128 ())
|
||||
# define __builtin_inff64x() (__builtin_inff128 ())
|
||||
# define __builtin_nanf64x(x) (__builtin_nanf128 (x))
|
||||
# define __builtin_nansf64x(x) (__builtin_nansf128 (x))
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
# if __HAVE_FLOAT128X
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# error "_Float128x supported but no type"
|
||||
# endif
|
||||
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf128x() ((_Float128x) __builtin_huge_val ())
|
||||
# define __builtin_inff128x() ((_Float128x) __builtin_inf ())
|
||||
# define __builtin_nanf128x(x) ((_Float128x) __builtin_nan (x))
|
||||
# define __builtin_nansf128x(x) ((_Float128x) __builtin_nans (x))
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
#endif /* !__ASSEMBLER__. */
|
||||
|
||||
#endif /* _BITS_FLOATN_COMMON_H */
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* IBM Accurate Mathematical Library
|
||||
* Written by International Business Machines Corp.
|
||||
* Copyright (C) 2001-2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/***********************************************************************/
|
||||
/*MODULE_NAME: dla.h */
|
||||
/* */
|
||||
/* This file holds C language macros for 'Double Length Floating Point */
|
||||
/* Arithmetic'. The macros are based on the paper: */
|
||||
/* T.J.Dekker, "A floating-point Technique for extending the */
|
||||
/* Available Precision", Number. Math. 18, 224-242 (1971). */
|
||||
/* A Double-Length number is defined by a pair (r,s), of IEEE double */
|
||||
/* precision floating point numbers that satisfy, */
|
||||
/* */
|
||||
/* abs(s) <= abs(r+s)*2**(-53)/(1+2**(-53)). */
|
||||
/* */
|
||||
/* The computer arithmetic assumed is IEEE double precision in */
|
||||
/* round to nearest mode. All variables in the macros must be of type */
|
||||
/* IEEE double. */
|
||||
/***********************************************************************/
|
||||
|
||||
/* CN = 1+2**27 = '41a0000002000000' IEEE double format. Use it to split a
|
||||
double for better accuracy. */
|
||||
#define CN 134217729.0
|
||||
|
||||
|
||||
/* Exact addition of two single-length floating point numbers, Dekker. */
|
||||
/* The macro produces a double-length number (z,zz) that satisfies */
|
||||
/* z+zz = x+y exactly. */
|
||||
|
||||
#define EADD(x,y,z,zz) \
|
||||
z=(x)+(y); zz=(fabs(x)>fabs(y)) ? (((x)-(z))+(y)) : (((y)-(z))+(x));
|
||||
|
||||
|
||||
/* Exact subtraction of two single-length floating point numbers, Dekker. */
|
||||
/* The macro produces a double-length number (z,zz) that satisfies */
|
||||
/* z+zz = x-y exactly. */
|
||||
|
||||
#define ESUB(x,y,z,zz) \
|
||||
z=(x)-(y); zz=(fabs(x)>fabs(y)) ? (((x)-(z))-(y)) : ((x)-((y)+(z)));
|
||||
|
||||
|
||||
#ifdef __FP_FAST_FMA
|
||||
# define DLA_FMS(x, y, z) __builtin_fma (x, y, -(z))
|
||||
#endif
|
||||
|
||||
/* Exact multiplication of two single-length floating point numbers, */
|
||||
/* Veltkamp. The macro produces a double-length number (z,zz) that */
|
||||
/* satisfies z+zz = x*y exactly. p,hx,tx,hy,ty are temporary */
|
||||
/* storage variables of type double. */
|
||||
|
||||
#ifdef DLA_FMS
|
||||
# define EMULV(x, y, z, zz, p, hx, tx, hy, ty) \
|
||||
z = x * y; zz = DLA_FMS (x, y, z);
|
||||
#else
|
||||
# define EMULV(x, y, z, zz, p, hx, tx, hy, ty) \
|
||||
p = CN * (x); hx = ((x) - p) + p; tx = (x) - hx; \
|
||||
p = CN * (y); hy = ((y) - p) + p; ty = (y) - hy; \
|
||||
z = (x) * (y); zz = (((hx * hy - z) + hx * ty) + tx * hy) + tx * ty;
|
||||
#endif
|
||||
|
||||
|
||||
/* Exact multiplication of two single-length floating point numbers, Dekker. */
|
||||
/* The macro produces a nearly double-length number (z,zz) (see Dekker) */
|
||||
/* that satisfies z+zz = x*y exactly. p,hx,tx,hy,ty,q are temporary */
|
||||
/* storage variables of type double. */
|
||||
|
||||
#ifdef DLA_FMS
|
||||
# define MUL12(x,y,z,zz,p,hx,tx,hy,ty,q) \
|
||||
EMULV(x,y,z,zz,p,hx,tx,hy,ty)
|
||||
#else
|
||||
# define MUL12(x,y,z,zz,p,hx,tx,hy,ty,q) \
|
||||
p=CN*(x); hx=((x)-p)+p; tx=(x)-hx; \
|
||||
p=CN*(y); hy=((y)-p)+p; ty=(y)-hy; \
|
||||
p=hx*hy; q=hx*ty+tx*hy; z=p+q; zz=((p-z)+q)+tx*ty;
|
||||
#endif
|
||||
|
||||
|
||||
/* Double-length addition, Dekker. The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = x+xx + y+yy. */
|
||||
/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. r,s are temporary */
|
||||
/* storage variables of type double. */
|
||||
|
||||
#define ADD2(x, xx, y, yy, z, zz, r, s) \
|
||||
r = (x) + (y); s = (fabs (x) > fabs (y)) ? \
|
||||
(((((x) - r) + (y)) + (yy)) + (xx)) : \
|
||||
(((((y) - r) + (x)) + (xx)) + (yy)); \
|
||||
z = r + s; zz = (r - z) + s;
|
||||
|
||||
|
||||
/* Double-length subtraction, Dekker. The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = x+xx - (y+yy). */
|
||||
/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. r,s are temporary */
|
||||
/* storage variables of type double. */
|
||||
|
||||
#define SUB2(x, xx, y, yy, z, zz, r, s) \
|
||||
r = (x) - (y); s = (fabs (x) > fabs (y)) ? \
|
||||
(((((x) - r) - (y)) - (yy)) + (xx)) : \
|
||||
((((x) - ((y) + r)) + (xx)) - (yy)); \
|
||||
z = r + s; zz = (r - z) + s;
|
||||
|
||||
|
||||
/* Double-length multiplication, Dekker. The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = (x+xx)*(y+yy). */
|
||||
/* An error bound: abs((x+xx)*(y+yy))*1.24e-31. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc are */
|
||||
/* temporary storage variables of type double. */
|
||||
|
||||
#define MUL2(x, xx, y, yy, z, zz, p, hx, tx, hy, ty, q, c, cc) \
|
||||
MUL12 (x, y, c, cc, p, hx, tx, hy, ty, q) \
|
||||
cc = ((x) * (yy) + (xx) * (y)) + cc; z = c + cc; zz = (c - z) + cc;
|
||||
|
||||
|
||||
/* Double-length division, Dekker. The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = (x+xx)/(y+yy). */
|
||||
/* An error bound: abs((x+xx)/(y+yy))*1.50e-31. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc,u,uu */
|
||||
/* are temporary storage variables of type double. */
|
||||
|
||||
#define DIV2(x,xx,y,yy,z,zz,p,hx,tx,hy,ty,q,c,cc,u,uu) \
|
||||
c=(x)/(y); MUL12(c,y,u,uu,p,hx,tx,hy,ty,q) \
|
||||
cc=(((((x)-u)-uu)+(xx))-c*(yy))/(y); z=c+cc; zz=(c-z)+cc;
|
||||
|
||||
|
||||
/* Double-length addition, slower but more accurate than ADD2. */
|
||||
/* The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = (x+xx)+(y+yy). */
|
||||
/* An error bound: abs(x+xx + y+yy)*1.50e-31. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */
|
||||
/* are temporary storage variables of type double. */
|
||||
|
||||
#define ADD2A(x, xx, y, yy, z, zz, r, rr, s, ss, u, uu, w) \
|
||||
r = (x) + (y); \
|
||||
if (fabs (x) > fabs (y)) { rr = ((x) - r) + (y); s = (rr + (yy)) + (xx); } \
|
||||
else { rr = ((y) - r) + (x); s = (rr + (xx)) + (yy); } \
|
||||
if (rr != 0.0) { \
|
||||
z = r + s; zz = (r - z) + s; } \
|
||||
else { \
|
||||
ss = (fabs (xx) > fabs (yy)) ? (((xx) - s) + (yy)) : (((yy) - s) + (xx));\
|
||||
u = r + s; \
|
||||
uu = (fabs (r) > fabs (s)) ? ((r - u) + s) : ((s - u) + r); \
|
||||
w = uu + ss; z = u + w; \
|
||||
zz = (fabs (u) > fabs (w)) ? ((u - z) + w) : ((w - z) + u); }
|
||||
|
||||
|
||||
/* Double-length subtraction, slower but more accurate than SUB2. */
|
||||
/* The macro produces a double-length */
|
||||
/* number (z,zz) which satisfies approximately z+zz = (x+xx)-(y+yy). */
|
||||
/* An error bound: abs(x+xx - (y+yy))*1.50e-31. (x,xx), (y,yy) */
|
||||
/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */
|
||||
/* are temporary storage variables of type double. */
|
||||
|
||||
#define SUB2A(x, xx, y, yy, z, zz, r, rr, s, ss, u, uu, w) \
|
||||
r = (x) - (y); \
|
||||
if (fabs (x) > fabs (y)) { rr = ((x) - r) - (y); s = (rr - (yy)) + (xx); } \
|
||||
else { rr = (x) - ((y) + r); s = (rr + (xx)) - (yy); } \
|
||||
if (rr != 0.0) { \
|
||||
z = r + s; zz = (r - z) + s; } \
|
||||
else { \
|
||||
ss = (fabs (xx) > fabs (yy)) ? (((xx) - s) - (yy)) : ((xx) - ((yy) + s)); \
|
||||
u = r + s; \
|
||||
uu = (fabs (r) > fabs (s)) ? ((r - u) + s) : ((s - u) + r); \
|
||||
w = uu + ss; z = u + w; \
|
||||
zz = (fabs (u) > fabs (w)) ? ((u - z) + w) : ((w - z) + u); }
|
||||
@@ -1,65 +0,0 @@
|
||||
/* Define aliases for libm long double functions.
|
||||
Copyright (C) 2017-2019 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _LIBM_ALIAS_LDOUBLE_H
|
||||
#define _LIBM_ALIAS_LDOUBLE_H
|
||||
|
||||
#include <bits/floatn.h>
|
||||
|
||||
#if __HAVE_FLOAT128 && !__HAVE_DISTINCT_FLOAT128
|
||||
# define libm_alias_ldouble_other_r_f128(from, to, r) \
|
||||
weak_alias (from ## l ## r, to ## f128 ## r)
|
||||
#else
|
||||
# define libm_alias_ldouble_other_r_f128(from, to, r)
|
||||
#endif
|
||||
|
||||
#if __HAVE_FLOAT64X_LONG_DOUBLE
|
||||
# define libm_alias_ldouble_other_r_f64x(from, to, r) \
|
||||
weak_alias (from ## l ## r, to ## f64x ## r)
|
||||
#else
|
||||
# define libm_alias_ldouble_other_r_f64x(from, to, r)
|
||||
#endif
|
||||
|
||||
/* Define _FloatN / _FloatNx aliases for a long double libm function
|
||||
that has internal name FROM ## l ## R and public names TO ## suffix
|
||||
## R for each suffix of a supported _FloatN / _FloatNx
|
||||
floating-point type with the same format as long double. */
|
||||
#define libm_alias_ldouble_other_r(from, to, r) \
|
||||
libm_alias_ldouble_other_r_f128 (from, to, r); \
|
||||
libm_alias_ldouble_other_r_f64x (from, to, r)
|
||||
|
||||
/* Likewise, but without the R suffix. */
|
||||
#define libm_alias_ldouble_other(from, to) \
|
||||
libm_alias_ldouble_other_r (from, to, )
|
||||
|
||||
/* Define aliases for a long double libm function that has internal
|
||||
name FROM ## l ## R and public names TO ## suffix ## R for each
|
||||
suffix of a supported floating-point type with the same format as
|
||||
long double. This should only be used for functions where such
|
||||
public names exist for _FloatN types, not for
|
||||
implementation-namespace exported names (where there is one name
|
||||
per format, not per type) or for obsolescent functions not provided
|
||||
for _FloatN types. */
|
||||
#define libm_alias_ldouble_r(from, to, r) \
|
||||
weak_alias (from ## l ## r, to ## l ## r); \
|
||||
libm_alias_ldouble_other_r (from, to, r)
|
||||
|
||||
/* Likewise, but without the R suffix. */
|
||||
#define libm_alias_ldouble(from, to) libm_alias_ldouble_r (from, to, )
|
||||
|
||||
#endif
|
||||
@@ -1,79 +0,0 @@
|
||||
/* Check for underflow and force underflow exceptions.
|
||||
Copyright (C) 2015-2018 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _MATH_UNDERFLOW_H
|
||||
#define _MATH_UNDERFLOW_H 1
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <math-barriers.h>
|
||||
|
||||
#define fabs_tg(x) __MATH_TG ((x), (__typeof (x)) __builtin_fabs, (x))
|
||||
|
||||
/* These must be function-like macros because some __MATH_TG
|
||||
implementations macro-expand the function-name argument before
|
||||
concatenating a suffix to it. */
|
||||
#define min_of_type_f() FLT_MIN
|
||||
#define min_of_type_() DBL_MIN
|
||||
#define min_of_type_l() LDBL_MIN
|
||||
#define min_of_type_f128() FLT128_MIN
|
||||
|
||||
#define min_of_type(x) __MATH_TG ((x), (__typeof (x)) min_of_type_, ())
|
||||
|
||||
/* If X (which is not a NaN) is subnormal, force an underflow
|
||||
exception. */
|
||||
#define math_check_force_underflow(x) \
|
||||
do \
|
||||
{ \
|
||||
__typeof (x) force_underflow_tmp = (x); \
|
||||
if (fabs_tg (force_underflow_tmp) \
|
||||
< min_of_type (force_underflow_tmp)) \
|
||||
{ \
|
||||
__typeof (force_underflow_tmp) force_underflow_tmp2 \
|
||||
= force_underflow_tmp * force_underflow_tmp; \
|
||||
math_force_eval (force_underflow_tmp2); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
/* Likewise, but X is also known to be nonnegative. */
|
||||
#define math_check_force_underflow_nonneg(x) \
|
||||
do \
|
||||
{ \
|
||||
__typeof (x) force_underflow_tmp = (x); \
|
||||
if (force_underflow_tmp \
|
||||
< min_of_type (force_underflow_tmp)) \
|
||||
{ \
|
||||
__typeof (force_underflow_tmp) force_underflow_tmp2 \
|
||||
= force_underflow_tmp * force_underflow_tmp; \
|
||||
math_force_eval (force_underflow_tmp2); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
/* Likewise, for both real and imaginary parts of a complex
|
||||
result. */
|
||||
#define math_check_force_underflow_complex(x) \
|
||||
do \
|
||||
{ \
|
||||
__typeof (x) force_underflow_complex_tmp = (x); \
|
||||
math_check_force_underflow (__real__ force_underflow_complex_tmp); \
|
||||
math_check_force_underflow (__imag__ force_underflow_complex_tmp); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#endif /* math-underflow.h */
|
||||
@@ -1,150 +0,0 @@
|
||||
/* memcopy.h -- definitions for memory copy functions. Generic C version.
|
||||
Copyright (C) 1991, 1992, 1993, 1997, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Torbjorn Granlund ([email protected]).
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* The strategy of the memory functions is:
|
||||
|
||||
1. Copy bytes until the destination pointer is aligned.
|
||||
|
||||
2. Copy words in unrolled loops. If the source and destination
|
||||
are not aligned in the same way, use word memory operations,
|
||||
but shift and merge two read words before writing.
|
||||
|
||||
3. Copy the few remaining bytes.
|
||||
|
||||
This is fast on processors that have at least 10 registers for
|
||||
allocation by GCC, and that can access memory at reg+const in one
|
||||
instruction.
|
||||
|
||||
I made an "exhaustive" test of this memmove when I wrote it,
|
||||
exhaustive in the sense that I tried all alignment and length
|
||||
combinations, with and without overlap. */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <endian.h>
|
||||
|
||||
/* The macros defined in this file are:
|
||||
|
||||
BYTE_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_to_copy)
|
||||
|
||||
BYTE_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_to_copy)
|
||||
|
||||
WORD_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_remaining, nbytes_to_copy)
|
||||
|
||||
WORD_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_remaining, nbytes_to_copy)
|
||||
|
||||
MERGE(old_word, sh_1, new_word, sh_2)
|
||||
[I fail to understand. I feel stupid. --roland]
|
||||
*/
|
||||
|
||||
/* Type to use for aligned memory operations.
|
||||
This should normally be the biggest type supported by a single load
|
||||
and store. */
|
||||
#define op_t unsigned long int
|
||||
#define OPSIZ (sizeof(op_t))
|
||||
|
||||
/* Type to use for unaligned operations. */
|
||||
typedef unsigned char byte;
|
||||
|
||||
/* Optimal type for storing bytes in registers. */
|
||||
#define reg_char char
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
|
||||
#endif
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
|
||||
#endif
|
||||
|
||||
/* Copy exactly NBYTES bytes from SRC_BP to DST_BP,
|
||||
without any assumptions about alignment of the pointers. */
|
||||
#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \
|
||||
do \
|
||||
{ \
|
||||
size_t __nbytes = (nbytes); \
|
||||
while (__nbytes > 0) \
|
||||
{ \
|
||||
byte __x = ((byte *) src_bp)[0]; \
|
||||
src_bp += 1; \
|
||||
__nbytes -= 1; \
|
||||
((byte *) dst_bp)[0] = __x; \
|
||||
dst_bp += 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Copy exactly NBYTES_TO_COPY bytes from SRC_END_PTR to DST_END_PTR,
|
||||
beginning at the bytes right before the pointers and continuing towards
|
||||
smaller addresses. Don't assume anything about alignment of the
|
||||
pointers. */
|
||||
#define BYTE_COPY_BWD(dst_ep, src_ep, nbytes) \
|
||||
do \
|
||||
{ \
|
||||
size_t __nbytes = (nbytes); \
|
||||
while (__nbytes > 0) \
|
||||
{ \
|
||||
byte __x; \
|
||||
src_ep -= 1; \
|
||||
__x = ((byte *) src_ep)[0]; \
|
||||
dst_ep -= 1; \
|
||||
__nbytes -= 1; \
|
||||
((byte *) dst_ep)[0] = __x; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Copy *up to* NBYTES bytes from SRC_BP to DST_BP, with
|
||||
the assumption that DST_BP is aligned on an OPSIZ multiple. If
|
||||
not all bytes could be easily copied, store remaining number of bytes
|
||||
in NBYTES_LEFT, otherwise store 0. */
|
||||
extern void _wordcopy_fwd_aligned (long int, long int, size_t) __THROW;
|
||||
extern void _wordcopy_fwd_dest_aligned (long int, long int, size_t) __THROW;
|
||||
#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \
|
||||
do \
|
||||
{ \
|
||||
if (src_bp % OPSIZ == 0) \
|
||||
_wordcopy_fwd_aligned (dst_bp, src_bp, (nbytes) / OPSIZ); \
|
||||
else \
|
||||
_wordcopy_fwd_dest_aligned (dst_bp, src_bp, (nbytes) / OPSIZ); \
|
||||
src_bp += (nbytes) & -OPSIZ; \
|
||||
dst_bp += (nbytes) & -OPSIZ; \
|
||||
(nbytes_left) = (nbytes) % OPSIZ; \
|
||||
} while (0)
|
||||
|
||||
/* Copy *up to* NBYTES_TO_COPY bytes from SRC_END_PTR to DST_END_PTR,
|
||||
beginning at the words (of type op_t) right before the pointers and
|
||||
continuing towards smaller addresses. May take advantage of that
|
||||
DST_END_PTR is aligned on an OPSIZ multiple. If not all bytes could be
|
||||
easily copied, store remaining number of bytes in NBYTES_REMAINING,
|
||||
otherwise store 0. */
|
||||
extern void _wordcopy_bwd_aligned (long int, long int, size_t) __THROW;
|
||||
extern void _wordcopy_bwd_dest_aligned (long int, long int, size_t) __THROW;
|
||||
#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) \
|
||||
do \
|
||||
{ \
|
||||
if (src_ep % OPSIZ == 0) \
|
||||
_wordcopy_bwd_aligned (dst_ep, src_ep, (nbytes) / OPSIZ); \
|
||||
else \
|
||||
_wordcopy_bwd_dest_aligned (dst_ep, src_ep, (nbytes) / OPSIZ); \
|
||||
src_ep -= (nbytes) & -OPSIZ; \
|
||||
dst_ep -= (nbytes) & -OPSIZ; \
|
||||
(nbytes_left) = (nbytes) % OPSIZ; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Threshold value for when to enter the unrolled loops. */
|
||||
#define OP_T_THRES 16
|
||||
@@ -1,27 +0,0 @@
|
||||
/* Specify NaN high-order bit conventions. Generic version.
|
||||
Copyright (C) 2016-2019 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef NAN_HIGH_ORDER_BIT_H
|
||||
#define NAN_HIGH_ORDER_BIT_H 1
|
||||
|
||||
/* Define this macro to 1 if the high-order bit of a NaN's mantissa is
|
||||
set for signaling NaNs and clear for quiet NaNs, 0 otherwise (the
|
||||
preferred IEEE convention). */
|
||||
#define HIGH_ORDER_BIT_IS_SET_FOR_SNAN 0
|
||||
|
||||
#endif /* nan-high-order-bit.h */
|
||||
@@ -1,463 +0,0 @@
|
||||
/* Definitions of inline math functions implemented by the m68881/2.
|
||||
Copyright (C) 1991,92,93,94,96,97,98,99,2000,2002, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
#ifdef __USE_ISOC99
|
||||
/* GCC 3.1 and up have builtins that actually can be used. */
|
||||
# if !__GNUC_PREREQ (3,1)
|
||||
/* ISO C99 defines some macros to perform unordered comparisons. The
|
||||
m68k FPU supports this with special opcodes and we should use them.
|
||||
These must not be inline functions since we have to be able to handle
|
||||
all floating-point types. */
|
||||
# undef isgreater
|
||||
# undef isgreaterequal
|
||||
# undef isless
|
||||
# undef islessequal
|
||||
# undef islessgreater
|
||||
# undef isunordered
|
||||
# define isgreater(x, y) \
|
||||
__extension__ \
|
||||
({ char __result; \
|
||||
__asm__ ("fcmp%.x %2,%1; fsogt %0" \
|
||||
: "=dm" (__result) : "f" (x), "f" (y)); \
|
||||
__result != 0; })
|
||||
|
||||
# define isgreaterequal(x, y) \
|
||||
__extension__ \
|
||||
({ char __result; \
|
||||
__asm__ ("fcmp%.x %2,%1; fsoge %0" \
|
||||
: "=dm" (__result) : "f" (x), "f" (y)); \
|
||||
__result != 0; })
|
||||
|
||||
# define isless(x, y) \
|
||||
__extension__ \
|
||||
({ char __result; \
|
||||
__asm__ ("fcmp%.x %2,%1; fsolt %0" \
|
||||
: "=dm" (__result) : "f" (x), "f" (y)); \
|
||||
__result != 0; })
|
||||
|
||||
# define islessequal(x, y) \
|
||||
__extension__ \
|
||||
({ char __result; \
|
||||
__asm__ ("fcmp%.x %2,%1; fsole %0" \
|
||||
: "=dm" (__result) : "f" (x), "f" (y)); \
|
||||
__result != 0; })
|
||||
|
||||
# define islessgreater(x, y) \
|
||||
__extension__ \
|
||||
({ char __result; \
|
||||
__asm__ ("fcmp%.x %2,%1; fsogl %0" \
|
||||
: "=dm" (__result) : "f" (x), "f" (y)); \
|
||||
__result != 0; })
|
||||
|
||||
# define isunordered(x, y) \
|
||||
__extension__ \
|
||||
({ char __result; \
|
||||
__asm__ ("fcmp%.x %2,%1; fsun %0" \
|
||||
: "=dm" (__result) : "f" (x), "f" (y)); \
|
||||
__result != 0; })
|
||||
# endif /* GCC 3.1 */
|
||||
#endif
|
||||
|
||||
|
||||
#if (!defined __NO_MATH_INLINES && defined __OPTIMIZE__) \
|
||||
|| defined __LIBC_INTERNAL_MATH_INLINES
|
||||
|
||||
#ifdef __LIBC_INTERNAL_MATH_INLINES
|
||||
/* This is used when defining the functions themselves. Define them with
|
||||
__ names, and with `static inline' instead of `extern inline' so the
|
||||
bodies will always be used, never an external function call. */
|
||||
# define __m81_u(x) __CONCAT(__,x)
|
||||
# define __m81_inline static __inline
|
||||
#else
|
||||
# define __m81_u(x) x
|
||||
# ifdef __cplusplus
|
||||
# define __m81_inline __inline
|
||||
# else
|
||||
# define __m81_inline extern __inline
|
||||
# endif
|
||||
# define __M81_MATH_INLINES 1
|
||||
#endif
|
||||
|
||||
/* Define a const math function. */
|
||||
#define __m81_defun(rettype, func, args) \
|
||||
__m81_inline rettype __attribute__((__const__)) \
|
||||
__m81_u(func) args
|
||||
|
||||
/* Define the three variants of a math function that has a direct
|
||||
implementation in the m68k fpu. FUNC is the name for C (which will be
|
||||
suffixed with f and l for the float and long double version, resp). OP
|
||||
is the name of the fpu operation (without leading f). */
|
||||
|
||||
#if defined __USE_MISC || defined __USE_ISOC99
|
||||
#ifndef NO_LONG_DOUBLE
|
||||
# define __inline_mathop(func, op) \
|
||||
__inline_mathop1(double, func, op) \
|
||||
__inline_mathop1(float, __CONCAT(func,f), op) \
|
||||
__inline_mathop1(long double, __CONCAT(func,l), op)
|
||||
#else
|
||||
# define __inline_mathop(func, op) \
|
||||
__inline_mathop1(double, func, op) \
|
||||
__inline_mathop1(float, __CONCAT(func,f), op)
|
||||
#endif
|
||||
#else
|
||||
# define __inline_mathop(func, op) \
|
||||
__inline_mathop1(double, func, op)
|
||||
#endif
|
||||
|
||||
#define __inline_mathop1(float_type,func, op) \
|
||||
__m81_defun (float_type, func, (float_type __mathop_x)) \
|
||||
{ \
|
||||
float_type __result; \
|
||||
__asm("f" __STRING(op) "%.x %1, %0" : "=f" (__result) : "f" (__mathop_x));\
|
||||
return __result; \
|
||||
}
|
||||
|
||||
__inline_mathop(__atan, atan)
|
||||
__inline_mathop(__cos, cos)
|
||||
__inline_mathop(__sin, sin)
|
||||
__inline_mathop(__tan, tan)
|
||||
__inline_mathop(__tanh, tanh)
|
||||
__inline_mathop(__fabs, abs)
|
||||
|
||||
#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
|
||||
__inline_mathop(__rint, int)
|
||||
__inline_mathop(__expm1, etoxm1)
|
||||
__inline_mathop(__log1p, lognp1)
|
||||
#endif
|
||||
|
||||
#ifdef __USE_MISC
|
||||
__inline_mathop(__significand, getman)
|
||||
#endif
|
||||
|
||||
#ifdef __USE_ISOC99
|
||||
__inline_mathop(__trunc, intrz)
|
||||
#endif
|
||||
|
||||
#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
|
||||
|
||||
__inline_mathop(atan, atan)
|
||||
__inline_mathop(cos, cos)
|
||||
__inline_mathop(sin, sin)
|
||||
__inline_mathop(tan, tan)
|
||||
__inline_mathop(tanh, tanh)
|
||||
|
||||
# if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
|
||||
__inline_mathop(rint, int)
|
||||
__inline_mathop(expm1, etoxm1)
|
||||
__inline_mathop(log1p, lognp1)
|
||||
# endif
|
||||
|
||||
# ifdef __USE_MISC
|
||||
__inline_mathop(significand, getman)
|
||||
# endif
|
||||
|
||||
# ifdef __USE_ISOC99
|
||||
__inline_mathop(trunc, intrz)
|
||||
# endif
|
||||
|
||||
#endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
|
||||
|
||||
/* This macro contains the definition for the rest of the inline
|
||||
functions, using FLOAT_TYPE as the domain type and S as the suffix
|
||||
for the function names. */
|
||||
|
||||
#define __inline_functions(float_type, s) \
|
||||
__m81_defun (float_type, __CONCAT(__floor,s), (float_type __x)) \
|
||||
{ \
|
||||
float_type __result; \
|
||||
unsigned long int __ctrl_reg; \
|
||||
__asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \
|
||||
/* Set rounding towards negative infinity. */ \
|
||||
__asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
|
||||
: "dmi" ((__ctrl_reg & ~0x10) | 0x20)); \
|
||||
/* Convert X to an integer, using -Inf rounding. */ \
|
||||
__asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \
|
||||
/* Restore the previous rounding mode. */ \
|
||||
__asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
|
||||
: "dmi" (__ctrl_reg)); \
|
||||
return __result; \
|
||||
} \
|
||||
\
|
||||
__m81_defun (float_type, __CONCAT(__ceil,s), (float_type __x)) \
|
||||
{ \
|
||||
float_type __result; \
|
||||
unsigned long int __ctrl_reg; \
|
||||
__asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \
|
||||
/* Set rounding towards positive infinity. */ \
|
||||
__asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
|
||||
: "dmi" (__ctrl_reg | 0x30)); \
|
||||
/* Convert X to an integer, using +Inf rounding. */ \
|
||||
__asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \
|
||||
/* Restore the previous rounding mode. */ \
|
||||
__asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
|
||||
: "dmi" (__ctrl_reg)); \
|
||||
return __result; \
|
||||
}
|
||||
|
||||
__inline_functions(double,)
|
||||
#if defined __USE_MISC || defined __USE_ISOC99
|
||||
__inline_functions(float,f)
|
||||
#ifndef NO_LONG_DOUBLE
|
||||
__inline_functions(long double,l)
|
||||
#endif
|
||||
#endif
|
||||
#undef __inline_functions
|
||||
|
||||
#ifdef __USE_MISC
|
||||
|
||||
# define __inline_functions(float_type, s) \
|
||||
__m81_defun (int, __CONCAT(__isinf,s), (float_type __value)) \
|
||||
{ \
|
||||
/* There is no branch-condition for infinity, \
|
||||
so we must extract and examine the condition codes manually. */ \
|
||||
unsigned long int __fpsr; \
|
||||
__asm("ftst%.x %1\n" \
|
||||
"fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \
|
||||
return (__fpsr & (2 << 24)) ? (__fpsr & (8 << 24) ? -1 : 1) : 0; \
|
||||
} \
|
||||
\
|
||||
__m81_defun (int, __CONCAT(__finite,s), (float_type __value)) \
|
||||
{ \
|
||||
/* There is no branch-condition for infinity, so we must extract and \
|
||||
examine the condition codes manually. */ \
|
||||
unsigned long int __fpsr; \
|
||||
__asm ("ftst%.x %1\n" \
|
||||
"fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \
|
||||
return (__fpsr & (3 << 24)) == 0; \
|
||||
} \
|
||||
\
|
||||
__m81_defun (float_type, __CONCAT(__scalbn,s), \
|
||||
(float_type __x, int __n)) \
|
||||
{ \
|
||||
float_type __result; \
|
||||
__asm ("fscale%.l %1, %0" : "=f" (__result) : "dmi" (__n), "0" (__x)); \
|
||||
return __result; \
|
||||
}
|
||||
|
||||
__inline_functions(double,)
|
||||
__inline_functions(float,f)
|
||||
#ifndef NO_LONG_DOUBLE
|
||||
__inline_functions(long double,l)
|
||||
#endif
|
||||
# undef __inline_functions
|
||||
|
||||
#endif /* Use misc. */
|
||||
|
||||
#if defined __USE_MISC || defined __USE_XOPEN
|
||||
|
||||
# define __inline_functions(float_type, s) \
|
||||
__m81_defun (int, __CONCAT(__isnan,s), (float_type __value)) \
|
||||
{ \
|
||||
char __result; \
|
||||
__asm("ftst%.x %1\n" \
|
||||
"fsun %0" : "=dm" (__result) : "f" (__value)); \
|
||||
return __result; \
|
||||
}
|
||||
|
||||
__inline_functions(double,)
|
||||
# ifdef __USE_MISC
|
||||
__inline_functions(float,f)
|
||||
#ifndef NO_LONG_DOUBLE
|
||||
__inline_functions(long double,l)
|
||||
#endif
|
||||
# endif
|
||||
# undef __inline_functions
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __USE_ISOC99
|
||||
|
||||
# define __inline_functions(float_type, s) \
|
||||
__m81_defun (int, __CONCAT(__signbit,s), (float_type __value)) \
|
||||
{ \
|
||||
/* There is no branch-condition for the sign bit, so we must extract \
|
||||
and examine the condition codes manually. */ \
|
||||
unsigned long int __fpsr; \
|
||||
__asm ("ftst%.x %1\n" \
|
||||
"fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \
|
||||
return (__fpsr >> 27) & 1; \
|
||||
} \
|
||||
\
|
||||
__m81_defun (float_type, __CONCAT(__scalbln,s), \
|
||||
(float_type __x, long int __n)) \
|
||||
{ \
|
||||
return __CONCAT(__scalbn,s) (__x, __n); \
|
||||
} \
|
||||
\
|
||||
__m81_defun (float_type, __CONCAT(__nearbyint,s), (float_type __x)) \
|
||||
{ \
|
||||
float_type __result; \
|
||||
unsigned long int __ctrl_reg; \
|
||||
__asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \
|
||||
/* Temporarily disable the inexact exception. */ \
|
||||
__asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
|
||||
: "dmi" (__ctrl_reg & ~0x200)); \
|
||||
__asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \
|
||||
__asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \
|
||||
: "dmi" (__ctrl_reg)); \
|
||||
return __result; \
|
||||
} \
|
||||
\
|
||||
__m81_defun (long int, __CONCAT(__lrint,s), (float_type __x)) \
|
||||
{ \
|
||||
long int __result; \
|
||||
__asm ("fmove%.l %1, %0" : "=dm" (__result) : "f" (__x)); \
|
||||
return __result; \
|
||||
} \
|
||||
\
|
||||
__m81_inline float_type \
|
||||
__m81_u(__CONCAT(__fma,s))(float_type __x, float_type __y, \
|
||||
float_type __z) \
|
||||
{ \
|
||||
return (__x * __y) + __z; \
|
||||
}
|
||||
|
||||
__inline_functions (double,)
|
||||
__inline_functions (float,f)
|
||||
#ifndef NO_LONG_DOUBLE
|
||||
__inline_functions (long double,l)
|
||||
#endif
|
||||
# undef __inline_functions
|
||||
|
||||
#endif /* Use ISO C9x */
|
||||
|
||||
#ifdef __USE_GNU
|
||||
|
||||
# define __inline_functions(float_type, s) \
|
||||
__m81_inline void \
|
||||
__m81_u(__CONCAT(__sincos,s))(float_type __x, float_type *__sinx, \
|
||||
float_type *__cosx) \
|
||||
{ \
|
||||
__asm ("fsincos%.x %2,%1:%0" \
|
||||
: "=f" (*__sinx), "=f" (*__cosx) : "f" (__x)); \
|
||||
}
|
||||
|
||||
__inline_functions (double,)
|
||||
__inline_functions (float,f)
|
||||
#ifndef NO_LONG_DOUBLE
|
||||
__inline_functions (long double,l)
|
||||
#endif
|
||||
# undef __inline_functions
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
|
||||
|
||||
/* Define inline versions of the user visible functions. */
|
||||
|
||||
/* Note that there must be no whitespace before the argument passed for
|
||||
NAME, to make token pasting work correctly with -traditional. */
|
||||
# define __inline_forward_c(rettype, name, args1, args2) \
|
||||
extern __inline rettype __attribute__((__const__)) \
|
||||
name args1 \
|
||||
{ \
|
||||
return __CONCAT(__,name) args2; \
|
||||
}
|
||||
|
||||
# define __inline_forward(rettype, name, args1, args2) \
|
||||
extern __inline rettype name args1 \
|
||||
{ \
|
||||
return __CONCAT(__,name) args2; \
|
||||
}
|
||||
|
||||
__inline_forward_c(double,floor, (double __x), (__x))
|
||||
__inline_forward_c(double,ceil, (double __x), (__x))
|
||||
# ifdef __USE_MISC
|
||||
# ifndef __USE_ISOC99 /* Conflict with macro of same name. */
|
||||
__inline_forward_c(int,isinf, (double __value), (__value))
|
||||
# endif
|
||||
__inline_forward_c(int,finite, (double __value), (__value))
|
||||
__inline_forward_c(double,scalbn, (double __x, int __n), (__x, __n))
|
||||
# endif
|
||||
# if defined __USE_MISC || defined __USE_XOPEN
|
||||
# ifndef __USE_ISOC99 /* Conflict with macro of same name. */
|
||||
__inline_forward_c(int,isnan, (double __value), (__value))
|
||||
# endif
|
||||
# endif
|
||||
# ifdef __USE_ISOC99
|
||||
__inline_forward_c(double,scalbln, (double __x, long int __n), (__x, __n))
|
||||
__inline_forward_c(double,nearbyint, (double __value), (__value))
|
||||
__inline_forward_c(long int,lrint, (double __value), (__value))
|
||||
__inline_forward_c(double,fma, (double __x, double __y, double __z),
|
||||
(__x, __y, __z))
|
||||
# endif
|
||||
# ifdef __USE_GNU
|
||||
__inline_forward(void,sincos, (double __x, double *__sinx, double *__cosx),
|
||||
(__x, __sinx, __cosx))
|
||||
# endif
|
||||
|
||||
# if defined __USE_MISC || defined __USE_ISOC99
|
||||
|
||||
__inline_forward_c(float,floorf, (float __x), (__x))
|
||||
__inline_forward_c(float,ceilf, (float __x), (__x))
|
||||
# ifdef __USE_MISC
|
||||
__inline_forward_c(int,isinff, (float __value), (__value))
|
||||
__inline_forward_c(int,finitef, (float __value), (__value))
|
||||
__inline_forward_c(float,scalbnf, (float __x, int __n), (__x, __n))
|
||||
__inline_forward_c(int,isnanf, (float __value), (__value))
|
||||
# endif
|
||||
# ifdef __USE_ISOC99
|
||||
__inline_forward_c(float,scalblnf, (float __x, long int __n), (__x, __n))
|
||||
__inline_forward_c(float,nearbyintf, (float __value), (__value))
|
||||
__inline_forward_c(long int,lrintf, (float __value), (__value))
|
||||
__inline_forward_c(float,fmaf, (float __x, float __y, float __z),
|
||||
(__x, __y, __z))
|
||||
# endif
|
||||
# ifdef __USE_GNU
|
||||
__inline_forward(void,sincosf, (float __x, float *__sinx, float *__cosx),
|
||||
(__x, __sinx, __cosx))
|
||||
# endif
|
||||
|
||||
# ifndef NO_LONG_DOUBLE
|
||||
__inline_forward_c(long double,floorl, (long double __x), (__x))
|
||||
__inline_forward_c(long double,ceill, (long double __x), (__x))
|
||||
# ifdef __USE_MISC
|
||||
__inline_forward_c(int,isinfl, (long double __value), (__value))
|
||||
__inline_forward_c(int,finitel, (long double __value), (__value))
|
||||
__inline_forward_c(long double,scalbnl, (long double __x, int __n), (__x, __n))
|
||||
__inline_forward_c(int,isnanl, (long double __value), (__value))
|
||||
# endif
|
||||
# ifdef __USE_ISOC99
|
||||
__inline_forward_c(long double,scalblnl, (long double __x, long int __n),
|
||||
(__x, __n))
|
||||
__inline_forward_c(long double,nearbyintl, (long double __value), (__value))
|
||||
__inline_forward_c(long int,lrintl, (long double __value), (__value))
|
||||
__inline_forward_c(long double,fmal,
|
||||
(long double __x, long double __y, long double __z),
|
||||
(__x, __y, __z))
|
||||
# endif
|
||||
# ifdef __USE_GNU
|
||||
__inline_forward(void,sincosl,
|
||||
(long double __x, long double *__sinx, long double *__cosx),
|
||||
(__x, __sinx, __cosx))
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif /* Use misc or ISO C99 */
|
||||
|
||||
#undef __inline_forward
|
||||
#undef __inline_forward_c
|
||||
|
||||
#endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
|
||||
|
||||
#endif
|
||||
#endif /* GCC. */
|
||||
@@ -1,101 +0,0 @@
|
||||
/* Inline math functions for powerpc.
|
||||
Copyright (C) 1995,1996,1997,1998,1999,2000 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if defined __GNUC__ && !defined _SOFT_FLOAT
|
||||
|
||||
#ifdef __USE_ISOC99
|
||||
# if __GNUC_PREREQ (2,96)
|
||||
|
||||
# define isgreater(x, y) __builtin_isgreater (x, y)
|
||||
# define isgreaterequal(x, y) __builtin_isgreaterequal (x, y)
|
||||
# define isless(x, y) __builtin_isless (x, y)
|
||||
# define islessequal(x, y) __builtin_islessequal (x, y)
|
||||
# define islessgreater(x, y) __builtin_islessgreater (x, y)
|
||||
# define isunordered(x, y) __builtin_isunordered (x, y)
|
||||
|
||||
# else
|
||||
|
||||
# define __unordered_cmp(x, y) \
|
||||
(__extension__ \
|
||||
({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
|
||||
unsigned __r; \
|
||||
__asm__("fcmpu 7,%1,%2 ; mfcr %0" : "=r" (__r) : "f" (__x), "f"(__y) \
|
||||
: "cr7"); \
|
||||
__r; }))
|
||||
|
||||
# define isgreater(x, y) (__unordered_cmp (x, y) >> 2 & 1)
|
||||
# define isgreaterequal(x, y) ((__unordered_cmp (x, y) & 6) != 0)
|
||||
# define isless(x, y) (__unordered_cmp (x, y) >> 3 & 1)
|
||||
# define islessequal(x, y) ((__unordered_cmp (x, y) & 0xA) != 0)
|
||||
# define islessgreater(x, y) ((__unordered_cmp (x, y) & 0xC) != 0)
|
||||
# define isunordered(x, y) (__unordered_cmp (x, y) & 1)
|
||||
|
||||
# endif /* __GNUC_PREREQ (2,97) */
|
||||
#endif /* __USE_ISOC99 */
|
||||
|
||||
#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
|
||||
|
||||
#ifndef __extern_always_inline
|
||||
# define __MATH_INLINE __inline
|
||||
#else
|
||||
# define __MATH_INLINE __extern_always_inline
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef __USE_ISOC99
|
||||
__MATH_INLINE long int lrint (double __x) __THROW;
|
||||
__MATH_INLINE long int
|
||||
lrint (double __x) __THROW
|
||||
{
|
||||
union {
|
||||
double __d;
|
||||
int __ll[2];
|
||||
} __u;
|
||||
__asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x));
|
||||
return __u.__ll[1];
|
||||
}
|
||||
|
||||
__MATH_INLINE long int lrintf (float __x) __THROW;
|
||||
__MATH_INLINE long int
|
||||
lrintf (float __x) __THROW
|
||||
{
|
||||
union {
|
||||
double __d;
|
||||
int __ll[2];
|
||||
} __u;
|
||||
__asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x));
|
||||
return __u.__ll[1];
|
||||
}
|
||||
|
||||
__MATH_INLINE double fdim (double __x, double __y) __THROW;
|
||||
__MATH_INLINE double
|
||||
fdim (double __x, double __y) __THROW
|
||||
{
|
||||
return __x < __y ? 0 : __x - __y;
|
||||
}
|
||||
|
||||
__MATH_INLINE float fdimf (float __x, float __y) __THROW;
|
||||
__MATH_INLINE float
|
||||
fdimf (float __x, float __y) __THROW
|
||||
{
|
||||
return __x < __y ? 0 : __x - __y;
|
||||
}
|
||||
|
||||
#endif /* __USE_ISOC99 */
|
||||
#endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
|
||||
#endif /* __GNUC__ && !_SOFT_FLOAT */
|
||||
@@ -1,106 +0,0 @@
|
||||
/* Internal libc stuff for floating point environment routines.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _FENV_LIBC_H
|
||||
#define _FENV_LIBC_H 1
|
||||
|
||||
#include <fenv.h>
|
||||
|
||||
/* The sticky bits in the FPSCR indicating exceptions have occurred. */
|
||||
#define FPSCR_STICKY_BITS ((FE_ALL_EXCEPT | FE_ALL_INVALID) & ~FE_INVALID)
|
||||
|
||||
/* Equivalent to fegetenv, but returns a fenv_t instead of taking a
|
||||
pointer. */
|
||||
#define fegetenv_register() \
|
||||
({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; })
|
||||
|
||||
/* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */
|
||||
#define fesetenv_register(env) \
|
||||
({ double d = (env); asm volatile ("mtfsf 0xff,%0" : : "f" (d)); })
|
||||
|
||||
/* This very handy macro:
|
||||
- Sets the rounding mode to 'round to nearest';
|
||||
- Sets the processor into IEEE mode; and
|
||||
- Prevents exceptions from being raised for inexact results.
|
||||
These things happen to be exactly what you need for typical elementary
|
||||
functions. */
|
||||
#define relax_fenv_state() asm ("mtfsfi 7,0")
|
||||
|
||||
/* Set/clear a particular FPSCR bit (for instance,
|
||||
reset_fpscr_bit(FPSCR_VE);
|
||||
prevents INVALID exceptions from being raised). */
|
||||
#define set_fpscr_bit(x) asm volatile ("mtfsb1 %0" : : "i"(x))
|
||||
#define reset_fpscr_bit(x) asm volatile ("mtfsb0 %0" : : "i"(x))
|
||||
|
||||
typedef union
|
||||
{
|
||||
fenv_t fenv;
|
||||
unsigned int l[2];
|
||||
} fenv_union_t;
|
||||
|
||||
/* Definitions of all the FPSCR bit numbers */
|
||||
enum {
|
||||
FPSCR_FX = 0, /* exception summary */
|
||||
FPSCR_FEX, /* enabled exception summary */
|
||||
FPSCR_VX, /* invalid operation summary */
|
||||
FPSCR_OX, /* overflow */
|
||||
FPSCR_UX, /* underflow */
|
||||
FPSCR_ZX, /* zero divide */
|
||||
FPSCR_XX, /* inexact */
|
||||
FPSCR_VXSNAN, /* invalid operation for SNaN */
|
||||
FPSCR_VXISI, /* invalid operation for Inf-Inf */
|
||||
FPSCR_VXIDI, /* invalid operation for Inf/Inf */
|
||||
FPSCR_VXZDZ, /* invalid operation for 0/0 */
|
||||
FPSCR_VXIMZ, /* invalid operation for Inf*0 */
|
||||
FPSCR_VXVC, /* invalid operation for invalid compare */
|
||||
FPSCR_FR, /* fraction rounded [fraction was incremented by round] */
|
||||
FPSCR_FI, /* fraction inexact */
|
||||
FPSCR_FPRF_C, /* result class descriptor */
|
||||
FPSCR_FPRF_FL, /* result less than (usually, less than 0) */
|
||||
FPSCR_FPRF_FG, /* result greater than */
|
||||
FPSCR_FPRF_FE, /* result equal to */
|
||||
FPSCR_FPRF_FU, /* result unordered */
|
||||
FPSCR_20, /* reserved */
|
||||
FPSCR_VXSOFT, /* invalid operation set by software */
|
||||
FPSCR_VXSQRT, /* invalid operation for square root */
|
||||
FPSCR_VXCVI, /* invalid operation for invalid integer convert */
|
||||
FPSCR_VE, /* invalid operation exception enable */
|
||||
FPSCR_OE, /* overflow exception enable */
|
||||
FPSCR_UE, /* underflow exception enable */
|
||||
FPSCR_ZE, /* zero divide exception enable */
|
||||
FPSCR_XE, /* inexact exception enable */
|
||||
FPSCR_NI /* non-IEEE mode (typically, no denormalised numbers) */
|
||||
/* the remaining two least-significant bits keep the rounding mode */
|
||||
};
|
||||
|
||||
/* This operation (i) sets the appropriate FPSCR bits for its
|
||||
parameter, (ii) converts SNaN to the corresponding NaN, and (iii)
|
||||
otherwise passes its parameter through unchanged (in particular, -0
|
||||
and +0 stay as they were). The `obvious' way to do this is optimised
|
||||
out by gcc. */
|
||||
#define f_wash(x) \
|
||||
({ double d; asm volatile ("fmul %0,%1,%2" \
|
||||
: "=f"(d) \
|
||||
: "f" (x), "f"((float)1.0)); d; })
|
||||
#define f_washf(x) \
|
||||
({ float f; asm volatile ("fmuls %0,%1,%2" \
|
||||
: "=f"(f) \
|
||||
: "f" (x), "f"((float)1.0)); f; })
|
||||
|
||||
#endif /* fenv_libc.h */
|
||||
@@ -1,97 +0,0 @@
|
||||
/* Macros to control TS 18661-3 glibc features on ldbl-128 platforms.
|
||||
Copyright (C) 2017-2019 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _BITS_FLOATN_H
|
||||
#define _BITS_FLOATN_H
|
||||
|
||||
#include <features.h>
|
||||
#include <bits/long-double.h>
|
||||
|
||||
/* Defined to 1 if the current compiler invocation provides a
|
||||
floating-point type with the IEEE 754 binary128 format, and this
|
||||
glibc includes corresponding *f128 interfaces for it. */
|
||||
#ifndef __NO_LONG_DOUBLE_MATH
|
||||
# define __HAVE_FLOAT128 1
|
||||
#else
|
||||
/* glibc does not support _Float128 for platforms where long double is
|
||||
normally binary128 when building with long double as binary64.
|
||||
GCC's default for supported scalar modes does not support it either
|
||||
in that case. */
|
||||
# define __HAVE_FLOAT128 0
|
||||
#endif
|
||||
|
||||
/* Defined to 1 if __HAVE_FLOAT128 is 1 and the type is ABI-distinct
|
||||
from the default float, double and long double types in this glibc. */
|
||||
#define __HAVE_DISTINCT_FLOAT128 0
|
||||
|
||||
/* Defined to 1 if the current compiler invocation provides a
|
||||
floating-point type with the right format for _Float64x, and this
|
||||
glibc includes corresponding *f64x interfaces for it. */
|
||||
#define __HAVE_FLOAT64X __HAVE_FLOAT128
|
||||
|
||||
/* Defined to 1 if __HAVE_FLOAT64X is 1 and _Float64x has the format
|
||||
of long double. Otherwise, if __HAVE_FLOAT64X is 1, _Float64x has
|
||||
the format of _Float128, which must be different from that of long
|
||||
double. */
|
||||
#define __HAVE_FLOAT64X_LONG_DOUBLE __HAVE_FLOAT128
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Defined to concatenate the literal suffix to be used with _Float128
|
||||
types, if __HAVE_FLOAT128 is 1. */
|
||||
# if __HAVE_FLOAT128
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
/* The literal suffix f128 exists only since GCC 7.0. */
|
||||
# define __f128(x) x##l
|
||||
# else
|
||||
# define __f128(x) x##f128
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Defined to a complex binary128 type if __HAVE_FLOAT128 is 1. */
|
||||
# if __HAVE_FLOAT128
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# define __CFLOAT128 _Complex long double
|
||||
# else
|
||||
# define __CFLOAT128 _Complex _Float128
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* The remaining of this file provides support for older compilers. */
|
||||
# if __HAVE_FLOAT128
|
||||
|
||||
/* The type _Float128 exists only since GCC 7.0. */
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
typedef long double _Float128;
|
||||
# endif
|
||||
|
||||
/* Various built-in functions do not exist before GCC 7.0. */
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf128() (__builtin_huge_vall ())
|
||||
# define __builtin_inff128() (__builtin_infl ())
|
||||
# define __builtin_nanf128(x) (__builtin_nanl (x))
|
||||
# define __builtin_nansf128(x) (__builtin_nansl (x))
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
#endif /* !__ASSEMBLER__. */
|
||||
|
||||
#include <bits/floatn-common.h>
|
||||
|
||||
#endif /* _BITS_FLOATN_H */
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef _MATH_H
|
||||
# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
|
||||
#endif
|
||||
|
||||
#define __NTH(fct) __attribute__ ((__nothrow__)) fct
|
||||
|
||||
#ifndef __extern_always_inline
|
||||
# define __MATH_INLINE __inline
|
||||
#else
|
||||
# define __MATH_INLINE __extern_always_inline
|
||||
#endif
|
||||
|
||||
#if defined __USE_ISOC99
|
||||
|
||||
# define isgreater(x, y) __builtin_isgreater (x, y)
|
||||
# define isgreaterequal(x, y) __builtin_isgreaterequal (x, y)
|
||||
# define isless(x, y) __builtin_isless (x, y)
|
||||
# define islessequal(x, y) __builtin_islessequal (x, y)
|
||||
# define islessgreater(x, y) __builtin_islessgreater (x, y)
|
||||
# define isunordered(x, y) __builtin_isunordered (x, y)
|
||||
|
||||
#endif
|
||||
@@ -1,97 +0,0 @@
|
||||
/* Macros to control TS 18661-3 glibc features on ldbl-128 platforms.
|
||||
Copyright (C) 2017-2019 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _BITS_FLOATN_H
|
||||
#define _BITS_FLOATN_H
|
||||
|
||||
#include <features.h>
|
||||
#include <bits/long-double.h>
|
||||
|
||||
/* Defined to 1 if the current compiler invocation provides a
|
||||
floating-point type with the IEEE 754 binary128 format, and this
|
||||
glibc includes corresponding *f128 interfaces for it. */
|
||||
#ifndef __NO_LONG_DOUBLE_MATH
|
||||
# define __HAVE_FLOAT128 1
|
||||
#else
|
||||
/* glibc does not support _Float128 for platforms where long double is
|
||||
normally binary128 when building with long double as binary64.
|
||||
GCC's default for supported scalar modes does not support it either
|
||||
in that case. */
|
||||
# define __HAVE_FLOAT128 0
|
||||
#endif
|
||||
|
||||
/* Defined to 1 if __HAVE_FLOAT128 is 1 and the type is ABI-distinct
|
||||
from the default float, double and long double types in this glibc. */
|
||||
#define __HAVE_DISTINCT_FLOAT128 0
|
||||
|
||||
/* Defined to 1 if the current compiler invocation provides a
|
||||
floating-point type with the right format for _Float64x, and this
|
||||
glibc includes corresponding *f64x interfaces for it. */
|
||||
#define __HAVE_FLOAT64X __HAVE_FLOAT128
|
||||
|
||||
/* Defined to 1 if __HAVE_FLOAT64X is 1 and _Float64x has the format
|
||||
of long double. Otherwise, if __HAVE_FLOAT64X is 1, _Float64x has
|
||||
the format of _Float128, which must be different from that of long
|
||||
double. */
|
||||
#define __HAVE_FLOAT64X_LONG_DOUBLE __HAVE_FLOAT128
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Defined to concatenate the literal suffix to be used with _Float128
|
||||
types, if __HAVE_FLOAT128 is 1. */
|
||||
# if __HAVE_FLOAT128
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
/* The literal suffix f128 exists only since GCC 7.0. */
|
||||
# define __f128(x) x##l
|
||||
# else
|
||||
# define __f128(x) x##f128
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Defined to a complex binary128 type if __HAVE_FLOAT128 is 1. */
|
||||
# if __HAVE_FLOAT128
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
# define __CFLOAT128 _Complex long double
|
||||
# else
|
||||
# define __CFLOAT128 _Complex _Float128
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* The remaining of this file provides support for older compilers. */
|
||||
# if __HAVE_FLOAT128
|
||||
|
||||
/* The type _Float128 exists only since GCC 7.0. */
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
typedef long double _Float128;
|
||||
# endif
|
||||
|
||||
/* Various built-in functions do not exist before GCC 7.0. */
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf128() (__builtin_huge_vall ())
|
||||
# define __builtin_inff128() (__builtin_infl ())
|
||||
# define __builtin_nanf128(x) (__builtin_nanl (x))
|
||||
# define __builtin_nansf128(x) (__builtin_nansl (x))
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
#endif /* !__ASSEMBLER__. */
|
||||
|
||||
#include <bits/floatn-common.h>
|
||||
|
||||
#endif /* _BITS_FLOATN_H */
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef _MATH_H
|
||||
# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
|
||||
#endif
|
||||
|
||||
#define __NTH(fct) __attribute__ ((__nothrow__)) fct
|
||||
|
||||
#ifndef __extern_always_inline
|
||||
# define __MATH_INLINE __inline
|
||||
#else
|
||||
# define __MATH_INLINE __extern_always_inline
|
||||
#endif
|
||||
|
||||
#if defined __USE_ISOC99
|
||||
|
||||
# define isgreater(x, y) __builtin_isgreater (x, y)
|
||||
# define isgreaterequal(x, y) __builtin_isgreaterequal (x, y)
|
||||
# define isless(x, y) __builtin_isless (x, y)
|
||||
# define islessequal(x, y) __builtin_islessequal (x, y)
|
||||
# define islessgreater(x, y) __builtin_islessgreater (x, y)
|
||||
# define isunordered(x, y) __builtin_isunordered (x, y)
|
||||
|
||||
#endif
|
||||
@@ -1,172 +0,0 @@
|
||||
#ifndef FENV_PRIVATE_H
|
||||
#define FENV_PRIVATE_H 1
|
||||
|
||||
#include <fenv.h>
|
||||
|
||||
static __always_inline void
|
||||
libc_fesetround (int r)
|
||||
{
|
||||
fenv_t etmp;
|
||||
__fenv_stfsr(etmp);
|
||||
etmp = (etmp & ~__FE_ROUND_MASK) | (r);
|
||||
__fenv_ldfsr(etmp);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feholdexcept_setround (fenv_t *e, int r)
|
||||
{
|
||||
fenv_t etmp;
|
||||
__fenv_stfsr(etmp);
|
||||
*(e) = etmp;
|
||||
etmp = etmp & ~((0x1f << 23) | FE_ALL_EXCEPT);
|
||||
etmp = (etmp & ~__FE_ROUND_MASK) | (r);
|
||||
__fenv_ldfsr(etmp);
|
||||
}
|
||||
|
||||
static __always_inline int
|
||||
libc_fetestexcept (int e)
|
||||
{
|
||||
fenv_t etmp;
|
||||
__fenv_stfsr(etmp);
|
||||
return etmp & (e) & FE_ALL_EXCEPT;
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_fesetenv (fenv_t *e)
|
||||
{
|
||||
__fenv_ldfsr(*e);
|
||||
}
|
||||
|
||||
static __always_inline int
|
||||
libc_feupdateenv_test (fenv_t *e, int ex)
|
||||
{
|
||||
fenv_t etmp;
|
||||
|
||||
__fenv_stfsr(etmp);
|
||||
etmp &= FE_ALL_EXCEPT;
|
||||
|
||||
__fenv_ldfsr(*e);
|
||||
|
||||
__feraiseexcept (etmp);
|
||||
|
||||
return etmp & ex;
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feupdateenv (fenv_t *e)
|
||||
{
|
||||
libc_feupdateenv_test (e, 0);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feholdsetround (fenv_t *e, int r)
|
||||
{
|
||||
fenv_t etmp;
|
||||
__fenv_stfsr(etmp);
|
||||
*(e) = etmp;
|
||||
etmp = (etmp & ~__FE_ROUND_MASK) | (r);
|
||||
__fenv_ldfsr(etmp);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feresetround (fenv_t *e)
|
||||
{
|
||||
fenv_t etmp;
|
||||
__fenv_stfsr(etmp);
|
||||
etmp = (etmp & ~__FE_ROUND_MASK) | (*e & __FE_ROUND_MASK);
|
||||
__fenv_ldfsr(etmp);
|
||||
}
|
||||
|
||||
#define libc_feholdexceptf libc_feholdexcept
|
||||
#define libc_fesetroundf libc_fesetround
|
||||
#define libc_feholdexcept_setroundf libc_feholdexcept_setround
|
||||
#define libc_fetestexceptf libc_fetestexcept
|
||||
#define libc_fesetenvf libc_fesetenv
|
||||
#define libc_feupdateenv_testf libc_feupdateenv_test
|
||||
#define libc_feupdateenvf libc_feupdateenv
|
||||
#define libc_feholdsetroundf libc_feholdsetround
|
||||
#define libc_feresetroundf libc_feresetround
|
||||
#define libc_feholdexcept libc_feholdexcept
|
||||
#define libc_fesetround libc_fesetround
|
||||
#define libc_feholdexcept_setround libc_feholdexcept_setround
|
||||
#define libc_fetestexcept libc_fetestexcept
|
||||
#define libc_fesetenv libc_fesetenv
|
||||
#define libc_feupdateenv_test libc_feupdateenv_test
|
||||
#define libc_feupdateenv libc_feupdateenv
|
||||
#define libc_feholdsetround libc_feholdsetround
|
||||
#define libc_feresetround libc_feresetround
|
||||
#define libc_feholdexceptl libc_feholdexcept
|
||||
#define libc_fesetroundl libc_fesetround
|
||||
#define libc_feholdexcept_setroundl libc_feholdexcept_setround
|
||||
#define libc_fetestexceptl libc_fetestexcept
|
||||
#define libc_fesetenvl libc_fesetenv
|
||||
#define libc_feupdateenv_testl libc_feupdateenv_test
|
||||
#define libc_feupdateenvl libc_feupdateenv
|
||||
#define libc_feholdsetroundl libc_feholdsetround
|
||||
#define libc_feresetroundl libc_feresetround
|
||||
|
||||
/* We have support for rounding mode context. */
|
||||
#define HAVE_RM_CTX 1
|
||||
|
||||
static __always_inline void
|
||||
libc_feholdexcept_setround_sparc_ctx (struct rm_ctx *ctx, int round)
|
||||
{
|
||||
fenv_t new;
|
||||
|
||||
__fenv_stfsr(ctx->env);
|
||||
new = ctx->env & ~((0x1f << 23) | FE_ALL_EXCEPT);
|
||||
new = (new & ~__FE_ROUND_MASK) | round;
|
||||
if (__glibc_unlikely (new != ctx->env))
|
||||
{
|
||||
__fenv_ldfsr(new);
|
||||
ctx->updated_status = true;
|
||||
}
|
||||
else
|
||||
ctx->updated_status = false;
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_fesetenv_sparc_ctx (struct rm_ctx *ctx)
|
||||
{
|
||||
libc_fesetenv(&ctx->env);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feupdateenv_sparc_ctx (struct rm_ctx *ctx)
|
||||
{
|
||||
if (__glibc_unlikely (ctx->updated_status))
|
||||
libc_feupdateenv_test (&ctx->env, 0);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
libc_feholdsetround_sparc_ctx (struct rm_ctx *ctx, int round)
|
||||
{
|
||||
fenv_t new;
|
||||
|
||||
__fenv_stfsr(ctx->env);
|
||||
new = (ctx->env & ~__FE_ROUND_MASK) | round;
|
||||
if (__glibc_unlikely (new != ctx->env))
|
||||
{
|
||||
__fenv_ldfsr(new);
|
||||
ctx->updated_status = true;
|
||||
}
|
||||
else
|
||||
ctx->updated_status = false;
|
||||
}
|
||||
#define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_sparc_ctx
|
||||
#define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_sparc_ctx
|
||||
#define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_sparc_ctx
|
||||
#define libc_fesetenv_ctx libc_fesetenv_sparc_ctx
|
||||
#define libc_fesetenvf_ctx libc_fesetenv_sparc_ctx
|
||||
#define libc_fesetenvl_ctx libc_fesetenv_sparc_ctx
|
||||
#define libc_feupdateenv_ctx libc_feupdateenv_sparc_ctx
|
||||
#define libc_feupdateenvf_ctx libc_feupdateenv_sparc_ctx
|
||||
#define libc_feupdateenvl_ctx libc_feupdateenv_sparc_ctx
|
||||
#define libc_feresetround_ctx libc_feupdateenv_sparc_ctx
|
||||
#define libc_feresetroundf_ctx libc_feupdateenv_sparc_ctx
|
||||
#define libc_feresetroundl_ctx libc_feupdateenv_sparc_ctx
|
||||
#define libc_feholdsetround_ctx libc_feholdsetround_sparc_ctx
|
||||
#define libc_feholdsetroundf_ctx libc_feholdsetround_sparc_ctx
|
||||
#define libc_feholdsetroundl_ctx libc_feholdsetround_sparc_ctx
|
||||
|
||||
#endif /* FENV_PRIVATE_H */
|
||||
@@ -1,121 +0,0 @@
|
||||
/* Macros to control TS 18661-3 glibc features on x86.
|
||||
Copyright (C) 2017-2018 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _BITS_FLOATN_H
|
||||
#define _BITS_FLOATN_H
|
||||
|
||||
#include <features.h>
|
||||
|
||||
/* Defined to 1 if the current compiler invocation provides a
|
||||
floating-point type with the IEEE 754 binary128 format, and this
|
||||
glibc includes corresponding *f128 interfaces for it. The required
|
||||
libgcc support was added some time after the basic compiler
|
||||
support, for x86_64 and x86. */
|
||||
#if (defined __x86_64__ \
|
||||
? __GNUC_PREREQ (4, 3) \
|
||||
: (defined __GNU__ ? __GNUC_PREREQ (4, 5) : __GNUC_PREREQ (4, 4)))
|
||||
# define __HAVE_FLOAT128 1
|
||||
#else
|
||||
# define __HAVE_FLOAT128 0
|
||||
#endif
|
||||
|
||||
/* Defined to 1 if __HAVE_FLOAT128 is 1 and the type is ABI-distinct
|
||||
from the default float, double and long double types in this glibc. */
|
||||
#if __HAVE_FLOAT128
|
||||
# define __HAVE_DISTINCT_FLOAT128 1
|
||||
#else
|
||||
# define __HAVE_DISTINCT_FLOAT128 0
|
||||
#endif
|
||||
|
||||
/* Defined to 1 if the current compiler invocation provides a
|
||||
floating-point type with the right format for _Float64x, and this
|
||||
glibc includes corresponding *f64x interfaces for it. */
|
||||
#define __HAVE_FLOAT64X 1
|
||||
|
||||
/* Defined to 1 if __HAVE_FLOAT64X is 1 and _Float64x has the format
|
||||
of long double. Otherwise, if __HAVE_FLOAT64X is 1, _Float64x has
|
||||
the format of _Float128, which must be different from that of long
|
||||
double. */
|
||||
#define __HAVE_FLOAT64X_LONG_DOUBLE 1
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Defined to concatenate the literal suffix to be used with _Float128
|
||||
types, if __HAVE_FLOAT128 is 1. */
|
||||
# if __HAVE_FLOAT128
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
/* The literal suffix f128 exists only since GCC 7.0. */
|
||||
# define __f128(x) x##q
|
||||
# else
|
||||
# define __f128(x) x##f128
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Defined to a complex binary128 type if __HAVE_FLOAT128 is 1. */
|
||||
# if __HAVE_FLOAT128
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
/* Add a typedef for older GCC compilers which don't natively support
|
||||
_Complex _Float128. */
|
||||
typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
|
||||
# define __CFLOAT128 __cfloat128
|
||||
# else
|
||||
# define __CFLOAT128 _Complex _Float128
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* The remaining of this file provides support for older compilers. */
|
||||
# if __HAVE_FLOAT128
|
||||
|
||||
/* The type _Float128 exists only since GCC 7.0. */
|
||||
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
|
||||
typedef __float128 _Float128;
|
||||
# endif
|
||||
|
||||
/* __builtin_huge_valf128 doesn't exist before GCC 7.0. */
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_huge_valf128() ((_Float128) __builtin_huge_val ())
|
||||
# endif
|
||||
|
||||
/* Older GCC has only a subset of built-in functions for _Float128 on
|
||||
x86, and __builtin_infq is not usable in static initializers.
|
||||
Converting a narrower sNaN to _Float128 produces a quiet NaN, so
|
||||
attempts to use _Float128 sNaNs will not work properly with older
|
||||
compilers. */
|
||||
# if !__GNUC_PREREQ (7, 0)
|
||||
# define __builtin_copysignf128 __builtin_copysignq
|
||||
# define __builtin_fabsf128 __builtin_fabsq
|
||||
# define __builtin_inff128() ((_Float128) __builtin_inf ())
|
||||
# define __builtin_nanf128(x) ((_Float128) __builtin_nan (x))
|
||||
# define __builtin_nansf128(x) ((_Float128) __builtin_nans (x))
|
||||
# endif
|
||||
|
||||
/* In math/math.h, __MATH_TG will expand signbit to __builtin_signbit*,
|
||||
e.g.: __builtin_signbitf128, before GCC 6. However, there has never
|
||||
been a __builtin_signbitf128 in GCC and the type-generic builtin is
|
||||
only available since GCC 6. */
|
||||
# if !__GNUC_PREREQ (6, 0)
|
||||
# define __builtin_signbitf128 __signbitf128
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
#endif /* !__ASSEMBLER__. */
|
||||
|
||||
#include <bits/floatn-common.h>
|
||||
|
||||
#endif /* _BITS_FLOATN_H */
|
||||
@@ -1,714 +0,0 @@
|
||||
/* Inline math functions for i387.
|
||||
Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by John C. Bowman <[email protected]>, 1995.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _MATH_H
|
||||
# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef __extern_always_inline
|
||||
# define __MATH_INLINE __inline
|
||||
#else
|
||||
# define __MATH_INLINE __extern_always_inline
|
||||
#endif
|
||||
|
||||
|
||||
#if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2
|
||||
# if __GNUC_PREREQ (2,97)
|
||||
/* GCC 2.97 and up have builtins that actually can be used. */
|
||||
# define isgreater(x, y) __builtin_isgreater (x, y)
|
||||
# define isgreaterequal(x, y) __builtin_isgreaterequal (x, y)
|
||||
# define isless(x, y) __builtin_isless (x, y)
|
||||
# define islessequal(x, y) __builtin_islessequal (x, y)
|
||||
# define islessgreater(x, y) __builtin_islessgreater (x, y)
|
||||
# define isunordered(x, y) __builtin_isunordered (x, y)
|
||||
# else
|
||||
/* ISO C99 defines some macros to perform unordered comparisons. The
|
||||
ix87 FPU supports this with special opcodes and we should use them.
|
||||
These must not be inline functions since we have to be able to handle
|
||||
all floating-point types. */
|
||||
# ifdef __i686__
|
||||
/* For the PentiumPro and more recent processors we can provide
|
||||
better code. */
|
||||
# define isgreater(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; seta %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
|
||||
__result; })
|
||||
# define isgreaterequal(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; setae %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
|
||||
__result; })
|
||||
|
||||
# define isless(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; seta %%al" \
|
||||
: "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
|
||||
__result; })
|
||||
|
||||
# define islessequal(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; setae %%al" \
|
||||
: "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
|
||||
__result; })
|
||||
|
||||
# define islessgreater(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; setne %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
|
||||
__result; })
|
||||
|
||||
# define isunordered(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; setp %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
|
||||
__result; })
|
||||
# else
|
||||
/* This is the dumb, portable code for i386 and above. */
|
||||
# define isgreater(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
|
||||
# define isgreaterequal(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
|
||||
# define isless(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
|
||||
: "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
|
||||
# define islessequal(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
|
||||
: "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
|
||||
# define islessgreater(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
|
||||
# define isunordered(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; sahf; setp %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
# endif /* __i686__ */
|
||||
# endif /* GCC 2.97 */
|
||||
|
||||
/* The gcc, version 2.7 or below, has problems with all this inlining
|
||||
code. So disable it for this version of the compiler. */
|
||||
# if __GNUC_PREREQ (2, 8)
|
||||
/* Test for negative number. Used in the signbit() macro. */
|
||||
__MATH_INLINE int
|
||||
__signbitf (float __x) __THROW
|
||||
{
|
||||
__extension__ union { float __f; int __i; } __u = { __f: __x };
|
||||
return __u.__i < 0;
|
||||
}
|
||||
__MATH_INLINE int
|
||||
__signbit (double __x) __THROW
|
||||
{
|
||||
__extension__ union { double __d; int __i[2]; } __u = { __d: __x };
|
||||
return __u.__i[1] < 0;
|
||||
}
|
||||
__MATH_INLINE int
|
||||
__signbitl (long double __x) __THROW
|
||||
{
|
||||
__extension__ union { long double __l; int __i[3]; } __u = { __l: __x };
|
||||
return (__u.__i[2] & 0x8000) != 0;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* The gcc, version 2.7 or below, has problems with all this inlining
|
||||
code. So disable it for this version of the compiler. */
|
||||
#if __GNUC_PREREQ (2, 8)
|
||||
|
||||
#if ((!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
|
||||
&& defined __OPTIMIZE__)
|
||||
|
||||
/* A macro to define float, double, and long double versions of various
|
||||
math functions for the ix87 FPU. FUNC is the function name (which will
|
||||
be suffixed with f and l for the float and long double version,
|
||||
respectively). OP is the name of the FPU operation.
|
||||
We define two sets of macros. The set with the additional NP
|
||||
doesn't add a prototype declaration. */
|
||||
|
||||
#if defined __USE_MISC || defined __USE_ISOC99
|
||||
# define __inline_mathop(func, op) \
|
||||
__inline_mathop_ (double, func, op) \
|
||||
__inline_mathop_ (float, __CONCAT(func,f), op) \
|
||||
__inline_mathop_ (long double, __CONCAT(func,l), op)
|
||||
# define __inline_mathopNP(func, op) \
|
||||
__inline_mathopNP_ (double, func, op) \
|
||||
__inline_mathopNP_ (float, __CONCAT(func,f), op) \
|
||||
__inline_mathopNP_ (long double, __CONCAT(func,l), op)
|
||||
#else
|
||||
# define __inline_mathop(func, op) \
|
||||
__inline_mathop_ (double, func, op)
|
||||
# define __inline_mathopNP(func, op) \
|
||||
__inline_mathopNP_ (double, func, op)
|
||||
#endif
|
||||
|
||||
#define __inline_mathop_(float_type, func, op) \
|
||||
__inline_mathop_decl_ (float_type, func, op, "0" (__x))
|
||||
#define __inline_mathopNP_(float_type, func, op) \
|
||||
__inline_mathop_declNP_ (float_type, func, op, "0" (__x))
|
||||
|
||||
|
||||
#if defined __USE_MISC || defined __USE_ISOC99
|
||||
# define __inline_mathop_decl(func, op, params...) \
|
||||
__inline_mathop_decl_ (double, func, op, params) \
|
||||
__inline_mathop_decl_ (float, __CONCAT(func,f), op, params) \
|
||||
__inline_mathop_decl_ (long double, __CONCAT(func,l), op, params)
|
||||
# define __inline_mathop_declNP(func, op, params...) \
|
||||
__inline_mathop_declNP_ (double, func, op, params) \
|
||||
__inline_mathop_declNP_ (float, __CONCAT(func,f), op, params) \
|
||||
__inline_mathop_declNP_ (long double, __CONCAT(func,l), op, params)
|
||||
#else
|
||||
# define __inline_mathop_decl(func, op, params...) \
|
||||
__inline_mathop_decl_ (double, func, op, params)
|
||||
# define __inline_mathop_declNP(func, op, params...) \
|
||||
__inline_mathop_declNP_ (double, func, op, params)
|
||||
#endif
|
||||
|
||||
#define __inline_mathop_decl_(float_type, func, op, params...) \
|
||||
__MATH_INLINE float_type func (float_type) __THROW; \
|
||||
__inline_mathop_declNP_ (float_type, func, op, params)
|
||||
|
||||
#define __inline_mathop_declNP_(float_type, func, op, params...) \
|
||||
__MATH_INLINE float_type func (float_type __x) __THROW \
|
||||
{ \
|
||||
register float_type __result; \
|
||||
__asm __volatile__ (op : "=t" (__result) : params); \
|
||||
return __result; \
|
||||
}
|
||||
|
||||
|
||||
#if defined __USE_MISC || defined __USE_ISOC99
|
||||
# define __inline_mathcode(func, arg, code) \
|
||||
__inline_mathcode_ (double, func, arg, code) \
|
||||
__inline_mathcode_ (float, __CONCAT(func,f), arg, code) \
|
||||
__inline_mathcode_ (long double, __CONCAT(func,l), arg, code)
|
||||
# define __inline_mathcodeNP(func, arg, code) \
|
||||
__inline_mathcodeNP_ (double, func, arg, code) \
|
||||
__inline_mathcodeNP_ (float, __CONCAT(func,f), arg, code) \
|
||||
__inline_mathcodeNP_ (long double, __CONCAT(func,l), arg, code)
|
||||
# define __inline_mathcode2(func, arg1, arg2, code) \
|
||||
__inline_mathcode2_ (double, func, arg1, arg2, code) \
|
||||
__inline_mathcode2_ (float, __CONCAT(func,f), arg1, arg2, code) \
|
||||
__inline_mathcode2_ (long double, __CONCAT(func,l), arg1, arg2, code)
|
||||
# define __inline_mathcodeNP2(func, arg1, arg2, code) \
|
||||
__inline_mathcodeNP2_ (double, func, arg1, arg2, code) \
|
||||
__inline_mathcodeNP2_ (float, __CONCAT(func,f), arg1, arg2, code) \
|
||||
__inline_mathcodeNP2_ (long double, __CONCAT(func,l), arg1, arg2, code)
|
||||
# define __inline_mathcode3(func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcode3_ (double, func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcode3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
|
||||
__inline_mathcode3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
|
||||
# define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcodeNP3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
|
||||
__inline_mathcodeNP3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
|
||||
#else
|
||||
# define __inline_mathcode(func, arg, code) \
|
||||
__inline_mathcode_ (double, func, (arg), code)
|
||||
# define __inline_mathcodeNP(func, arg, code) \
|
||||
__inline_mathcodeNP_ (double, func, (arg), code)
|
||||
# define __inline_mathcode2(func, arg1, arg2, code) \
|
||||
__inline_mathcode2_ (double, func, arg1, arg2, code)
|
||||
# define __inline_mathcodeNP2(func, arg1, arg2, code) \
|
||||
__inline_mathcodeNP2_ (double, func, arg1, arg2, code)
|
||||
# define __inline_mathcode3(func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcode3_ (double, func, arg1, arg2, arg3, code)
|
||||
# define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code)
|
||||
#endif
|
||||
|
||||
#define __inline_mathcode_(float_type, func, arg, code) \
|
||||
__MATH_INLINE float_type func (float_type) __THROW; \
|
||||
__inline_mathcodeNP_(float_type, func, arg, code)
|
||||
|
||||
#define __inline_mathcodeNP_(float_type, func, arg, code) \
|
||||
__MATH_INLINE float_type func (float_type arg) __THROW \
|
||||
{ \
|
||||
code; \
|
||||
}
|
||||
|
||||
|
||||
#define __inline_mathcode2_(float_type, func, arg1, arg2, code) \
|
||||
__MATH_INLINE float_type func (float_type, float_type) __THROW; \
|
||||
__inline_mathcodeNP2_ (float_type, func, arg1, arg2, code)
|
||||
|
||||
#define __inline_mathcodeNP2_(float_type, func, arg1, arg2, code) \
|
||||
__MATH_INLINE float_type func (float_type arg1, float_type arg2) __THROW \
|
||||
{ \
|
||||
code; \
|
||||
}
|
||||
|
||||
#define __inline_mathcode3_(float_type, func, arg1, arg2, arg3, code) \
|
||||
__MATH_INLINE float_type func (float_type, float_type, float_type) __THROW; \
|
||||
__inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code)
|
||||
|
||||
#define __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code) \
|
||||
__MATH_INLINE float_type func (float_type arg1, float_type arg2, \
|
||||
float_type arg3) __THROW \
|
||||
{ \
|
||||
code; \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
|
||||
/* Miscellaneous functions */
|
||||
|
||||
__inline_mathcode (__sgn, __x, \
|
||||
return __x == 0.0 ? 0.0 : (__x > 0.0 ? 1.0 : -1.0))
|
||||
|
||||
/* __FAST_MATH__ is defined by gcc -ffast-math. */
|
||||
#ifdef __FAST_MATH__
|
||||
__inline_mathcode (__pow2, __x, \
|
||||
register long double __value; \
|
||||
register long double __exponent; \
|
||||
__extension__ long long int __p = (long long int) __x; \
|
||||
if (__x == (long double) __p) \
|
||||
{ \
|
||||
__asm __volatile__ \
|
||||
("fscale" \
|
||||
: "=t" (__value) : "0" (1.0), "u" (__x)); \
|
||||
return __value; \
|
||||
} \
|
||||
__asm __volatile__ \
|
||||
("fld %%st(0)\n\t" \
|
||||
"frndint # int(x)\n\t" \
|
||||
"fxch\n\t" \
|
||||
"fsub %%st(1) # fract(x)\n\t" \
|
||||
"f2xm1 # 2^(fract(x)) - 1\n\t" \
|
||||
: "=t" (__value), "=u" (__exponent) : "0" (__x)); \
|
||||
__value += 1.0; \
|
||||
__asm __volatile__ \
|
||||
("fscale" \
|
||||
: "=t" (__value) : "0" (__value), "u" (__exponent)); \
|
||||
return __value)
|
||||
|
||||
# ifdef __USE_GNU
|
||||
# define __sincos_code \
|
||||
register long double __cosr; \
|
||||
register long double __sinr; \
|
||||
__asm __volatile__ \
|
||||
("fsincos\n\t" \
|
||||
"fnstsw %%ax\n\t" \
|
||||
"testl $0x400, %%eax\n\t" \
|
||||
"jz 1f\n\t" \
|
||||
"fldpi\n\t" \
|
||||
"fadd %%st(0)\n\t" \
|
||||
"fxch %%st(1)\n\t" \
|
||||
"2: fprem1\n\t" \
|
||||
"fnstsw %%ax\n\t" \
|
||||
"testl $0x400, %%eax\n\t" \
|
||||
"jnz 2b\n\t" \
|
||||
"fstp %%st(1)\n\t" \
|
||||
"fsincos\n\t" \
|
||||
"1:" \
|
||||
: "=t" (__cosr), "=u" (__sinr) : "0" (__x)); \
|
||||
*__sinx = __sinr; \
|
||||
*__cosx = __cosr
|
||||
|
||||
__MATH_INLINE void
|
||||
__sincos (double __x, double *__sinx, double *__cosx) __THROW
|
||||
{
|
||||
__sincos_code;
|
||||
}
|
||||
|
||||
__MATH_INLINE void
|
||||
__sincosf (float __x, float *__sinx, float *__cosx) __THROW
|
||||
{
|
||||
__sincos_code;
|
||||
}
|
||||
|
||||
__MATH_INLINE void
|
||||
__sincosl (long double __x, long double *__sinx, long double *__cosx) __THROW
|
||||
{
|
||||
__sincos_code;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
/* Optimized inline implementation, sometimes with reduced precision
|
||||
and/or argument range. */
|
||||
|
||||
# define __expm1_code \
|
||||
register long double __value; \
|
||||
register long double __exponent; \
|
||||
register long double __temp; \
|
||||
__asm __volatile__ \
|
||||
("fldl2e # e^x - 1 = 2^(x * log2(e)) - 1\n\t" \
|
||||
"fmul %%st(1) # x * log2(e)\n\t" \
|
||||
"fst %%st(1)\n\t" \
|
||||
"frndint # int(x * log2(e))\n\t" \
|
||||
"fxch\n\t" \
|
||||
"fsub %%st(1) # fract(x * log2(e))\n\t" \
|
||||
"f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
|
||||
"fscale # 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" \
|
||||
: "=t" (__value), "=u" (__exponent) : "0" (__x)); \
|
||||
__asm __volatile__ \
|
||||
("fscale # 2^int(x * log2(e))\n\t" \
|
||||
: "=t" (__temp) : "0" (1.0), "u" (__exponent)); \
|
||||
__temp -= 1.0; \
|
||||
return __temp + __value ?: __x
|
||||
__inline_mathcodeNP_ (long double, __expm1l, __x, __expm1_code)
|
||||
|
||||
|
||||
# define __exp_code \
|
||||
register long double __value; \
|
||||
register long double __exponent; \
|
||||
__asm __volatile__ \
|
||||
("fldl2e # e^x = 2^(x * log2(e))\n\t" \
|
||||
"fmul %%st(1) # x * log2(e)\n\t" \
|
||||
"fst %%st(1)\n\t" \
|
||||
"frndint # int(x * log2(e))\n\t" \
|
||||
"fxch\n\t" \
|
||||
"fsub %%st(1) # fract(x * log2(e))\n\t" \
|
||||
"f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
|
||||
: "=t" (__value), "=u" (__exponent) : "0" (__x)); \
|
||||
__value += 1.0; \
|
||||
__asm __volatile__ \
|
||||
("fscale" \
|
||||
: "=t" (__value) : "0" (__value), "u" (__exponent)); \
|
||||
return __value
|
||||
__inline_mathcodeNP (exp, __x, __exp_code)
|
||||
__inline_mathcodeNP_ (long double, __expl, __x, __exp_code)
|
||||
|
||||
|
||||
__inline_mathcodeNP (tan, __x, \
|
||||
register long double __value; \
|
||||
register long double __value2 __attribute__ ((__unused__)); \
|
||||
__asm __volatile__ \
|
||||
("fptan" \
|
||||
: "=t" (__value2), "=u" (__value) : "0" (__x)); \
|
||||
return __value)
|
||||
#endif /* __FAST_MATH__ */
|
||||
|
||||
|
||||
# if __GNUC_PREREQ (3, 4)
|
||||
__inline_mathcodeNP2_ (long double, __atan2l, __y, __x,
|
||||
return __builtin_atan2l (__y, __x))
|
||||
# else
|
||||
#define __atan2_code \
|
||||
register long double __value; \
|
||||
__asm __volatile__ \
|
||||
("fpatan" \
|
||||
: "=t" (__value) : "0" (__x), "u" (__y) : "st(1)"); \
|
||||
return __value
|
||||
# ifdef __FAST_MATH__
|
||||
__inline_mathcodeNP2 (atan2, __y, __x, __atan2_code)
|
||||
# endif
|
||||
__inline_mathcodeNP2_ (long double, __atan2l, __y, __x, __atan2_code)
|
||||
# endif
|
||||
|
||||
|
||||
__inline_mathcodeNP2 (fmod, __x, __y, \
|
||||
register long double __value; \
|
||||
__asm __volatile__ \
|
||||
("1: fprem\n\t" \
|
||||
"fnstsw %%ax\n\t" \
|
||||
"sahf\n\t" \
|
||||
"jp 1b" \
|
||||
: "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc"); \
|
||||
return __value)
|
||||
|
||||
|
||||
__inline_mathopNP (sqrt, "fsqrt")
|
||||
__inline_mathopNP_ (long double, __sqrtl, "fsqrt")
|
||||
|
||||
#if __GNUC_PREREQ (2, 8)
|
||||
__inline_mathcodeNP_ (double, fabs, __x, return __builtin_fabs (__x))
|
||||
__inline_mathcodeNP_ (float, fabsf, __x, return __builtin_fabsf (__x))
|
||||
__inline_mathcodeNP_ (long double, fabsl, __x, return __builtin_fabsl (__x))
|
||||
__inline_mathcodeNP_ (long double, __fabsl, __x, return __builtin_fabsl (__x))
|
||||
#else
|
||||
__inline_mathop (fabs, "fabs")
|
||||
__inline_mathop_ (long double, __fabsl, "fabs")
|
||||
#endif
|
||||
|
||||
#ifdef __FAST_MATH__
|
||||
/* The argument range of this inline version is reduced. */
|
||||
__inline_mathopNP (sin, "fsin")
|
||||
/* The argument range of this inline version is reduced. */
|
||||
__inline_mathopNP (cos, "fcos")
|
||||
|
||||
__inline_mathop_declNP (log, "fldln2; fxch; fyl2x", "0" (__x) : "st(1)")
|
||||
__inline_mathop_declNP (log10, "fldlg2; fxch; fyl2x", "0" (__x) : "st(1)")
|
||||
|
||||
__inline_mathcodeNP (asin, __x, return __atan2l (__x, __sqrtl (1.0 - __x * __x)))
|
||||
__inline_mathcodeNP (acos, __x, return __atan2l (__sqrtl (1.0 - __x * __x), __x))
|
||||
#endif /* __FAST_MATH__ */
|
||||
|
||||
__inline_mathop_declNP (atan, "fld1; fpatan", "0" (__x) : "st(1)")
|
||||
|
||||
__inline_mathcode_ (long double, __sgn1l, __x, \
|
||||
__extension__ union { long double __xld; unsigned int __xi[3]; } __n = \
|
||||
{ __xld: __x }; \
|
||||
__n.__xi[2] = (__n.__xi[2] & 0x8000) | 0x3fff; \
|
||||
__n.__xi[1] = 0x80000000; \
|
||||
__n.__xi[0] = 0; \
|
||||
return __n.__xld)
|
||||
|
||||
|
||||
#ifdef __FAST_MATH__
|
||||
/* The argument range of the inline version of sinhl is slightly reduced. */
|
||||
__inline_mathcodeNP (sinh, __x, \
|
||||
register long double __exm1 = __expm1l (__fabsl (__x)); \
|
||||
return 0.5 * (__exm1 / (__exm1 + 1.0) + __exm1) * __sgn1l (__x))
|
||||
|
||||
__inline_mathcodeNP (cosh, __x, \
|
||||
register long double __ex = __expl (__x); \
|
||||
return 0.5 * (__ex + 1.0 / __ex))
|
||||
|
||||
__inline_mathcodeNP (tanh, __x, \
|
||||
register long double __exm1 = __expm1l (-__fabsl (__x + __x)); \
|
||||
return __exm1 / (__exm1 + 2.0) * __sgn1l (-__x))
|
||||
#endif
|
||||
|
||||
__inline_mathcodeNP (floor, __x, \
|
||||
register long double __value; \
|
||||
__volatile unsigned short int __cw; \
|
||||
__volatile unsigned short int __cwtmp; \
|
||||
__asm __volatile ("fnstcw %0" : "=m" (__cw)); \
|
||||
__cwtmp = (__cw & 0xf3ff) | 0x0400; /* rounding down */ \
|
||||
__asm __volatile ("fldcw %0" : : "m" (__cwtmp)); \
|
||||
__asm __volatile ("frndint" : "=t" (__value) : "0" (__x)); \
|
||||
__asm __volatile ("fldcw %0" : : "m" (__cw)); \
|
||||
return __value)
|
||||
|
||||
__inline_mathcodeNP (ceil, __x, \
|
||||
register long double __value; \
|
||||
__volatile unsigned short int __cw; \
|
||||
__volatile unsigned short int __cwtmp; \
|
||||
__asm __volatile ("fnstcw %0" : "=m" (__cw)); \
|
||||
__cwtmp = (__cw & 0xf3ff) | 0x0800; /* rounding up */ \
|
||||
__asm __volatile ("fldcw %0" : : "m" (__cwtmp)); \
|
||||
__asm __volatile ("frndint" : "=t" (__value) : "0" (__x)); \
|
||||
__asm __volatile ("fldcw %0" : : "m" (__cw)); \
|
||||
return __value)
|
||||
|
||||
#ifdef __FAST_MATH__
|
||||
#define __ldexp_code \
|
||||
register long double __value; \
|
||||
__asm __volatile__ \
|
||||
("fscale" \
|
||||
: "=t" (__value) : "0" (__x), "u" ((long double) __y)); \
|
||||
return __value
|
||||
|
||||
__MATH_INLINE double
|
||||
ldexp (double __x, int __y) __THROW
|
||||
{
|
||||
__ldexp_code;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Optimized versions for some non-standardized functions. */
|
||||
#if defined __USE_ISOC99 || defined __USE_MISC
|
||||
|
||||
# ifdef __FAST_MATH__
|
||||
__inline_mathcodeNP (expm1, __x, __expm1_code)
|
||||
|
||||
/* We cannot rely on M_SQRT being defined. So we do it for ourself
|
||||
here. */
|
||||
# define __M_SQRT2 1.41421356237309504880L /* sqrt(2) */
|
||||
|
||||
__inline_mathcodeNP (log1p, __x, \
|
||||
register long double __value; \
|
||||
if (__fabsl (__x) >= 1.0 - 0.5 * __M_SQRT2) \
|
||||
__value = logl (1.0 + __x); \
|
||||
else \
|
||||
__asm __volatile__ \
|
||||
("fldln2\n\t" \
|
||||
"fxch\n\t" \
|
||||
"fyl2xp1" \
|
||||
: "=t" (__value) : "0" (__x) : "st(1)"); \
|
||||
return __value)
|
||||
|
||||
|
||||
/* The argument range of the inline version of asinhl is slightly reduced. */
|
||||
__inline_mathcodeNP (asinh, __x, \
|
||||
register long double __y = __fabsl (__x); \
|
||||
return (log1pl (__y * __y / (__sqrtl (__y * __y + 1.0) + 1.0) + __y) \
|
||||
* __sgn1l (__x)))
|
||||
|
||||
__inline_mathcodeNP (acosh, __x, \
|
||||
return logl (__x + __sqrtl (__x - 1.0) * __sqrtl (__x + 1.0)))
|
||||
|
||||
__inline_mathcodeNP (atanh, __x, \
|
||||
register long double __y = __fabsl (__x); \
|
||||
return -0.5 * log1pl (-(__y + __y) / (1.0 + __y)) * __sgn1l (__x))
|
||||
|
||||
/* The argument range of the inline version of hypotl is slightly reduced. */
|
||||
__inline_mathcodeNP2 (hypot, __x, __y, return __sqrtl (__x * __x + __y * __y))
|
||||
|
||||
__inline_mathcodeNP(logb, __x, \
|
||||
register long double __value; \
|
||||
register long double __junk; \
|
||||
__asm __volatile__ \
|
||||
("fxtract\n\t" \
|
||||
: "=t" (__junk), "=u" (__value) : "0" (__x)); \
|
||||
return __value)
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __USE_ISOC99
|
||||
#ifdef __FAST_MATH__
|
||||
__inline_mathop_declNP (log2, "fld1; fxch; fyl2x", "0" (__x) : "st(1)")
|
||||
|
||||
__MATH_INLINE float
|
||||
ldexpf (float __x, int __y) __THROW
|
||||
{
|
||||
__ldexp_code;
|
||||
}
|
||||
|
||||
__MATH_INLINE long double
|
||||
ldexpl (long double __x, int __y) __THROW
|
||||
{
|
||||
__ldexp_code;
|
||||
}
|
||||
|
||||
__inline_mathcodeNP3 (fma, __x, __y, __z, return (__x * __y) + __z)
|
||||
|
||||
__inline_mathopNP (rint, "frndint")
|
||||
#endif /* __FAST_MATH__ */
|
||||
|
||||
#define __lrint_code \
|
||||
long int __lrintres; \
|
||||
__asm__ __volatile__ \
|
||||
("fistpl %0" \
|
||||
: "=m" (__lrintres) : "t" (__x) : "st"); \
|
||||
return __lrintres
|
||||
__MATH_INLINE long int
|
||||
lrintf (float __x) __THROW
|
||||
{
|
||||
__lrint_code;
|
||||
}
|
||||
__MATH_INLINE long int
|
||||
lrint (double __x) __THROW
|
||||
{
|
||||
__lrint_code;
|
||||
}
|
||||
__MATH_INLINE long int
|
||||
lrintl (long double __x) __THROW
|
||||
{
|
||||
__lrint_code;
|
||||
}
|
||||
#undef __lrint_code
|
||||
|
||||
#define __llrint_code \
|
||||
long long int __llrintres; \
|
||||
__asm__ __volatile__ \
|
||||
("fistpll %0" \
|
||||
: "=m" (__llrintres) : "t" (__x) : "st"); \
|
||||
return __llrintres
|
||||
__MATH_INLINE long long int
|
||||
llrintf (float __x) __THROW
|
||||
{
|
||||
__llrint_code;
|
||||
}
|
||||
__MATH_INLINE long long int
|
||||
llrint (double __x) __THROW
|
||||
{
|
||||
__llrint_code;
|
||||
}
|
||||
__MATH_INLINE long long int
|
||||
llrintl (long double __x) __THROW
|
||||
{
|
||||
__llrint_code;
|
||||
}
|
||||
#undef __llrint_code
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __USE_MISC
|
||||
|
||||
__inline_mathcodeNP2 (drem, __x, __y, \
|
||||
register double __value; \
|
||||
register int __clobbered; \
|
||||
__asm __volatile__ \
|
||||
("1: fprem1\n\t" \
|
||||
"fstsw %%ax\n\t" \
|
||||
"sahf\n\t" \
|
||||
"jp 1b" \
|
||||
: "=t" (__value), "=&a" (__clobbered) : "0" (__x), "u" (__y) : "cc"); \
|
||||
return __value)
|
||||
|
||||
|
||||
/* This function is used in the `isfinite' macro. */
|
||||
__MATH_INLINE int
|
||||
__finite (double __x) __THROW
|
||||
{
|
||||
return (__extension__
|
||||
(((((union { double __d; int __i[2]; }) {__d: __x}).__i[1]
|
||||
| 0x800fffffu) + 1) >> 31));
|
||||
}
|
||||
|
||||
/* Miscellaneous functions */
|
||||
#ifdef __FAST_MATH__
|
||||
__inline_mathcode (__coshm1, __x, \
|
||||
register long double __exm1 = __expm1l (__fabsl (__x)); \
|
||||
return 0.5 * (__exm1 / (__exm1 + 1.0)) * __exm1)
|
||||
|
||||
__inline_mathcode (__acosh1p, __x, \
|
||||
return log1pl (__x + __sqrtl (__x) * __sqrtl (__x + 2.0)))
|
||||
|
||||
#endif /* __FAST_MATH__ */
|
||||
#endif /* __USE_MISC */
|
||||
|
||||
/* Undefine some of the large macros which are not used anymore. */
|
||||
#undef __atan2_code
|
||||
#ifdef __FAST_MATH__
|
||||
# undef __expm1_code
|
||||
# undef __exp_code
|
||||
# undef __sincos_code
|
||||
#endif /* __FAST_MATH__ */
|
||||
|
||||
#endif /* __NO_MATH_INLINES */
|
||||
|
||||
|
||||
/* This code is used internally in the GNU libc. */
|
||||
#ifdef __LIBC_INTERNAL_MATH_INLINES
|
||||
__inline_mathop (__ieee754_sqrt, "fsqrt")
|
||||
__inline_mathcode2 (__ieee754_atan2, __y, __x,
|
||||
register long double __value;
|
||||
__asm __volatile__ ("fpatan\n\t"
|
||||
: "=t" (__value)
|
||||
: "0" (__x), "u" (__y) : "st(1)");
|
||||
return __value;)
|
||||
#endif
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
@@ -1,922 +0,0 @@
|
||||
/* Optimized, inlined string functions. i386 version.
|
||||
Copyright (C) 1997,1998,1999,2000,2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _STRING_H
|
||||
# error "Never use <bits/string.h> directly; include <string.h> instead."
|
||||
#endif
|
||||
|
||||
/* The ix86 processors can access unaligned multi-byte variables. */
|
||||
#define _STRING_ARCH_unaligned 1
|
||||
|
||||
|
||||
/* We only provide optimizations if the user selects them and if
|
||||
GNU CC is used. */
|
||||
#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
|
||||
&& defined __GNUC__ && __GNUC__ >= 2 && !__BOUNDED_POINTERS__
|
||||
|
||||
#ifndef __STRING_INLINE
|
||||
# ifdef __cplusplus
|
||||
# define __STRING_INLINE inline
|
||||
# else
|
||||
# define __STRING_INLINE extern __inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Copy N bytes of SRC to DEST. */
|
||||
#define _HAVE_STRING_ARCH_memcpy 1
|
||||
#define memcpy(dest, src, n) \
|
||||
(__extension__ (__builtin_constant_p (n) \
|
||||
? __memcpy_c ((dest), (src), (n)) \
|
||||
: memcpy ((dest), (src), (n))))
|
||||
/* This looks horribly ugly, but the compiler can optimize it totally,
|
||||
as the count is constant. */
|
||||
__STRING_INLINE void *__memcpy_c (void *__dest, __const void *__src,
|
||||
size_t __n);
|
||||
|
||||
__STRING_INLINE void *
|
||||
__memcpy_c (void *__dest, __const void *__src, size_t __n)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2;
|
||||
union {
|
||||
unsigned int __ui;
|
||||
unsigned short int __usi;
|
||||
unsigned char __uc;
|
||||
} *__u = __dest;
|
||||
switch (__n)
|
||||
{
|
||||
case 0:
|
||||
return __dest;
|
||||
case 1:
|
||||
__u->__uc = *(const unsigned char *) __src;
|
||||
return __dest;
|
||||
case 2:
|
||||
__u->__usi = *(const unsigned short int *) __src;
|
||||
return __dest;
|
||||
case 3:
|
||||
__u->__usi = *(const unsigned short int *) __src;
|
||||
__u = (void *) __u + 2;
|
||||
__u->__uc = *(2 + (const unsigned char *) __src);
|
||||
return __dest;
|
||||
case 4:
|
||||
__u->__ui = *(const unsigned int *) __src;
|
||||
return __dest;
|
||||
case 6:
|
||||
__u->__ui = *(const unsigned int *) __src;
|
||||
__u = (void *) __u + 4;
|
||||
__u->__usi = *(2 + (const unsigned short int *) __src);
|
||||
return __dest;
|
||||
case 8:
|
||||
__u->__ui = *(const unsigned int *) __src;
|
||||
__u = (void *) __u + 4;
|
||||
__u->__ui = *(1 + (const unsigned int *) __src);
|
||||
return __dest;
|
||||
case 12:
|
||||
__u->__ui = *(const unsigned int *) __src;
|
||||
__u = (void *) __u + 4;
|
||||
__u->__ui = *(1 + (const unsigned int *) __src);
|
||||
__u = (void *) __u + 4;
|
||||
__u->__ui = *(2 + (const unsigned int *) __src);
|
||||
return __dest;
|
||||
case 16:
|
||||
__u->__ui = *(const unsigned int *) __src;
|
||||
__u = (void *) __u + 4;
|
||||
__u->__ui = *(1 + (const unsigned int *) __src);
|
||||
__u = (void *) __u + 4;
|
||||
__u->__ui = *(2 + (const unsigned int *) __src);
|
||||
__u = (void *) __u + 4;
|
||||
__u->__ui = *(3 + (const unsigned int *) __src);
|
||||
return __dest;
|
||||
case 20:
|
||||
__u->__ui = *(const unsigned int *) __src;
|
||||
__u = (void *) __u + 4;
|
||||
__u->__ui = *(1 + (const unsigned int *) __src);
|
||||
__u = (void *) __u + 4;
|
||||
__u->__ui = *(2 + (const unsigned int *) __src);
|
||||
__u = (void *) __u + 4;
|
||||
__u->__ui = *(3 + (const unsigned int *) __src);
|
||||
__u = (void *) __u + 4;
|
||||
__u->__ui = *(4 + (const unsigned int *) __src);
|
||||
return __dest;
|
||||
}
|
||||
#define __COMMON_CODE(x) \
|
||||
__asm__ __volatile__ \
|
||||
("cld\n\t" \
|
||||
"rep; movsl" \
|
||||
x \
|
||||
: "=&c" (__d0), "=&D" (__d1), "=&S" (__d2) \
|
||||
: "0" (__n / 4), "1" (&__u->__uc), "2" (__src) \
|
||||
: "memory");
|
||||
|
||||
switch (__n % 4)
|
||||
{
|
||||
case 0:
|
||||
__COMMON_CODE ("");
|
||||
break;
|
||||
case 1:
|
||||
__COMMON_CODE ("\n\tmovsb");
|
||||
break;
|
||||
case 2:
|
||||
__COMMON_CODE ("\n\tmovsw");
|
||||
break;
|
||||
case 3:
|
||||
__COMMON_CODE ("\n\tmovsw\n\tmovsb");
|
||||
break;
|
||||
}
|
||||
return __dest;
|
||||
#undef __COMMON_CODE
|
||||
}
|
||||
|
||||
|
||||
/* Copy N bytes of SRC to DEST, guaranteeing
|
||||
correct behavior for overlapping strings. */
|
||||
#define _HAVE_STRING_ARCH_memmove 1
|
||||
#ifndef _FORCE_INLINES
|
||||
__STRING_INLINE void *
|
||||
memmove (void *__dest, __const void *__src, size_t __n)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2;
|
||||
if (__dest < __src)
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"rep\n\t"
|
||||
"movsb"
|
||||
: "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
|
||||
: "0" (__n), "1" (__src), "2" (__dest)
|
||||
: "memory");
|
||||
else
|
||||
__asm__ __volatile__
|
||||
("std\n\t"
|
||||
"rep\n\t"
|
||||
"movsb\n\t"
|
||||
"cld"
|
||||
: "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
|
||||
: "0" (__n), "1" (__n - 1 + (const char *) __src),
|
||||
"2" (__n - 1 + (char *) __dest)
|
||||
: "memory");
|
||||
return __dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set N bytes of S to C. */
|
||||
#define _HAVE_STRING_ARCH_memset 1
|
||||
#define _USE_STRING_ARCH_memset 1
|
||||
#define memset(s, c, n) \
|
||||
(__extension__ (__builtin_constant_p (c) \
|
||||
? (__builtin_constant_p (n) \
|
||||
? __memset_cc (s, 0x01010101UL * (unsigned char) (c), n) \
|
||||
: __memset_cg (s, 0x01010101UL * (unsigned char) (c), n))\
|
||||
: __memset_gg (s, c, n)))
|
||||
|
||||
__STRING_INLINE void *__memset_cc (void *__s, unsigned long int __pattern,
|
||||
size_t __n);
|
||||
|
||||
__STRING_INLINE void *
|
||||
__memset_cc (void *__s, unsigned long int __pattern, size_t __n)
|
||||
{
|
||||
register unsigned long int __d0, __d1;
|
||||
union {
|
||||
unsigned int __ui;
|
||||
unsigned short int __usi;
|
||||
unsigned char __uc;
|
||||
} *__u = __s;
|
||||
switch (__n)
|
||||
{
|
||||
case 0:
|
||||
return __s;
|
||||
case 1:
|
||||
__u->__uc = __pattern;
|
||||
return __s;
|
||||
case 2:
|
||||
__u->__usi = __pattern;
|
||||
return __s;
|
||||
case 3:
|
||||
__u->__usi = __pattern;
|
||||
__u = __extension__ ((void *) __u + 2);
|
||||
__u->__uc = __pattern;
|
||||
return __s;
|
||||
case 4:
|
||||
__u->__ui = __pattern;
|
||||
return __s;
|
||||
}
|
||||
#define __COMMON_CODE(x) \
|
||||
__asm__ __volatile__ \
|
||||
("cld\n\t" \
|
||||
"rep; stosl" \
|
||||
x \
|
||||
: "=&c" (__d0), "=&D" (__d1) \
|
||||
: "a" (__pattern), "0" (__n / 4), "1" (&__u->__uc) \
|
||||
: "memory")
|
||||
|
||||
switch (__n % 4)
|
||||
{
|
||||
case 0:
|
||||
__COMMON_CODE ("");
|
||||
break;
|
||||
case 1:
|
||||
__COMMON_CODE ("\n\tstosb");
|
||||
break;
|
||||
case 2:
|
||||
__COMMON_CODE ("\n\tstosw");
|
||||
break;
|
||||
case 3:
|
||||
__COMMON_CODE ("\n\tstosw\n\tstosb");
|
||||
break;
|
||||
}
|
||||
return __s;
|
||||
#undef __COMMON_CODE
|
||||
}
|
||||
|
||||
__STRING_INLINE void *__memset_cg (void *__s, unsigned long __c, size_t __n);
|
||||
|
||||
__STRING_INLINE void *
|
||||
__memset_cg (void *__s, unsigned long __c, size_t __n)
|
||||
{
|
||||
register unsigned long int __d0, __d1;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"rep; stosl\n\t"
|
||||
"testb $2,%b3\n\t"
|
||||
"je 1f\n\t"
|
||||
"stosw\n"
|
||||
"1:\n\t"
|
||||
"testb $1,%b3\n\t"
|
||||
"je 2f\n\t"
|
||||
"stosb\n"
|
||||
"2:"
|
||||
: "=&c" (__d0), "=&D" (__d1)
|
||||
: "a" (__c), "q" (__n), "0" (__n / 4), "1" (__s)
|
||||
: "memory");
|
||||
return __s;
|
||||
}
|
||||
|
||||
__STRING_INLINE void *__memset_gg (void *__s, char __c, size_t __n);
|
||||
|
||||
__STRING_INLINE void *
|
||||
__memset_gg (void *__s, char __c, size_t __n)
|
||||
{
|
||||
register unsigned long int __d0, __d1;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"rep; stosb"
|
||||
: "=&D" (__d0), "=&c" (__d1)
|
||||
: "a" (__c), "0" (__s), "1" (__n)
|
||||
: "memory");
|
||||
return __s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Search N bytes of S for C. */
|
||||
#define _HAVE_STRING_ARCH_memchr 1
|
||||
#ifndef _FORCE_INLINES
|
||||
__STRING_INLINE void *
|
||||
memchr (__const void *__s, int __c, size_t __n)
|
||||
{
|
||||
register unsigned long int __d0;
|
||||
register void *__res;
|
||||
if (__n == 0)
|
||||
return NULL;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"je 1f\n\t"
|
||||
"movl $1,%0\n"
|
||||
"1:"
|
||||
: "=D" (__res), "=&c" (__d0)
|
||||
: "a" (__c), "0" (__s), "1" (__n),
|
||||
"m" ( *(struct { __extension__ char __x[__n]; } *)__s)
|
||||
: "cc");
|
||||
return __res - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define _HAVE_STRING_ARCH_memrchr 1
|
||||
#ifndef _FORCE_INLINES
|
||||
__STRING_INLINE void *
|
||||
__memrchr (__const void *__s, int __c, size_t __n)
|
||||
{
|
||||
register unsigned long int __d0;
|
||||
register void *__res;
|
||||
if (__n == 0)
|
||||
return NULL;
|
||||
__asm__ __volatile__
|
||||
("std\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"je 1f\n\t"
|
||||
"orl $-1,%0\n"
|
||||
"1:\tcld\n\t"
|
||||
"incl %0"
|
||||
: "=D" (__res), "=&c" (__d0)
|
||||
: "a" (__c), "0" (__s + __n - 1), "1" (__n),
|
||||
"m" ( *(struct { __extension__ char __x[__n]; } *)__s)
|
||||
: "cc");
|
||||
return __res;
|
||||
}
|
||||
# ifdef __USE_GNU
|
||||
# define memrchr(s, c, n) __memrchr (s, c, n)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Return the length of S. */
|
||||
#define _HAVE_STRING_ARCH_strlen 1
|
||||
#ifndef _FORCE_INLINES
|
||||
__STRING_INLINE size_t
|
||||
strlen (__const char *__str)
|
||||
{
|
||||
register unsigned long int __d0;
|
||||
register size_t __res;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"notl %0"
|
||||
: "=c" (__res), "=&D" (__d0)
|
||||
: "1" (__str), "a" (0), "0" (0xffffffff),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__str)
|
||||
: "cc");
|
||||
return __res - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Copy SRC to DEST. */
|
||||
#define _HAVE_STRING_ARCH_strcpy 1
|
||||
#ifndef _FORCE_INLINES
|
||||
__STRING_INLINE char *
|
||||
strcpy (char *__dest, __const char *__src)
|
||||
{
|
||||
register unsigned long int __d0, __d1;
|
||||
__asm__ __volatile__
|
||||
("cld\n"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"stosb\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b"
|
||||
: "=&S" (__d0), "=&D" (__d1)
|
||||
: "0" (__src), "1" (__dest)
|
||||
: "ax", "memory", "cc");
|
||||
return __dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Copy no more than N characters of SRC to DEST. */
|
||||
#define _HAVE_STRING_ARCH_strncpy 1
|
||||
#ifndef _FORCE_INLINES
|
||||
__STRING_INLINE char *
|
||||
strncpy (char *__dest, __const char *__src, size_t __n)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2;
|
||||
__asm__ __volatile__
|
||||
("cld\n"
|
||||
"1:\n\t"
|
||||
"decl %2\n\t"
|
||||
"js 2f\n\t"
|
||||
"lodsb\n\t"
|
||||
"stosb\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b\n\t"
|
||||
"rep; stosb\n"
|
||||
"2:"
|
||||
: "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
|
||||
: "0" (__src), "1" (__dest), "2" (__n)
|
||||
: "ax", "memory", "cc");
|
||||
return __dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Append SRC onto DEST. */
|
||||
#define _HAVE_STRING_ARCH_strcat 1
|
||||
#ifndef _FORCE_INLINES
|
||||
__STRING_INLINE char *
|
||||
strcat (char *__dest, __const char *__src)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2, __d3;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"decl %1\n"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"stosb\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b"
|
||||
: "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
|
||||
: "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
|
||||
: "memory", "cc");
|
||||
return __dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Append no more than N characters from SRC onto DEST. */
|
||||
#define _HAVE_STRING_ARCH_strncat 1
|
||||
#ifndef _FORCE_INLINES
|
||||
__STRING_INLINE char *
|
||||
strncat (char *__dest, __const char *__src, size_t __n)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2, __d3;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"decl %1\n\t"
|
||||
"movl %4,%2\n"
|
||||
"1:\n\t"
|
||||
"decl %2\n\t"
|
||||
"js 2f\n\t"
|
||||
"lodsb\n\t"
|
||||
"stosb\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b\n\t"
|
||||
"jmp 3f\n"
|
||||
"2:\n\t"
|
||||
"xorl %3,%3\n\t"
|
||||
"stosb\n"
|
||||
"3:"
|
||||
: "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
|
||||
: "g" (__n), "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
|
||||
: "memory", "cc");
|
||||
return __dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Compare S1 and S2. */
|
||||
#define _HAVE_STRING_ARCH_strcmp 1
|
||||
#ifndef _FORCE_INLINES
|
||||
__STRING_INLINE int
|
||||
strcmp (__const char *__s1, __const char *__s2)
|
||||
{
|
||||
register unsigned long int __d0, __d1;
|
||||
register int __res;
|
||||
__asm__ __volatile__
|
||||
("cld\n"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"scasb\n\t"
|
||||
"jne 2f\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b\n\t"
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"jmp 3f\n"
|
||||
"2:\n\t"
|
||||
"sbbl %%eax,%%eax\n\t"
|
||||
"orb $1,%%al\n"
|
||||
"3:"
|
||||
: "=a" (__res), "=&S" (__d0), "=&D" (__d1)
|
||||
: "1" (__s1), "2" (__s2),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s1),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s2)
|
||||
: "cc");
|
||||
return __res;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Compare N characters of S1 and S2. */
|
||||
#define _HAVE_STRING_ARCH_strncmp 1
|
||||
#ifndef _FORCE_INLINES
|
||||
__STRING_INLINE int
|
||||
strncmp (__const char *__s1, __const char *__s2, size_t __n)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2;
|
||||
register int __res;
|
||||
__asm__ __volatile__
|
||||
("cld\n"
|
||||
"1:\n\t"
|
||||
"decl %3\n\t"
|
||||
"js 2f\n\t"
|
||||
"lodsb\n\t"
|
||||
"scasb\n\t"
|
||||
"jne 3f\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b\n"
|
||||
"2:\n\t"
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"jmp 4f\n"
|
||||
"3:\n\t"
|
||||
"sbbl %%eax,%%eax\n\t"
|
||||
"orb $1,%%al\n"
|
||||
"4:"
|
||||
: "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
|
||||
: "1" (__s1), "2" (__s2), "3" (__n),
|
||||
"m" ( *(struct { __extension__ char __x[__n]; } *)__s1),
|
||||
"m" ( *(struct { __extension__ char __x[__n]; } *)__s2)
|
||||
: "cc");
|
||||
return __res;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Find the first occurrence of C in S. */
|
||||
#define _HAVE_STRING_ARCH_strchr 1
|
||||
#define _USE_STRING_ARCH_strchr 1
|
||||
#define strchr(s, c) \
|
||||
(__extension__ (__builtin_constant_p (c) \
|
||||
? __strchr_c (s, ((c) & 0xff) << 8) \
|
||||
: __strchr_g (s, c)))
|
||||
|
||||
__STRING_INLINE char *__strchr_g (__const char *__s, int __c);
|
||||
|
||||
__STRING_INLINE char *
|
||||
__strchr_g (__const char *__s, int __c)
|
||||
{
|
||||
register unsigned long int __d0;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"movb %%al,%%ah\n"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"cmpb %%ah,%%al\n\t"
|
||||
"je 2f\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b\n\t"
|
||||
"movl $1,%1\n"
|
||||
"2:\n\t"
|
||||
"movl %1,%0"
|
||||
: "=a" (__res), "=&S" (__d0)
|
||||
: "0" (__c), "1" (__s),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
|
||||
: "cc");
|
||||
return __res - 1;
|
||||
}
|
||||
|
||||
__STRING_INLINE char *__strchr_c (__const char *__s, int __c);
|
||||
|
||||
__STRING_INLINE char *
|
||||
__strchr_c (__const char *__s, int __c)
|
||||
{
|
||||
register unsigned long int __d0;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"cmpb %%ah,%%al\n\t"
|
||||
"je 2f\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b\n\t"
|
||||
"movl $1,%1\n"
|
||||
"2:\n\t"
|
||||
"movl %1,%0"
|
||||
: "=a" (__res), "=&S" (__d0)
|
||||
: "0" (__c), "1" (__s),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
|
||||
: "cc");
|
||||
return __res - 1;
|
||||
}
|
||||
|
||||
|
||||
/* Find the first occurrence of C in S or the final NUL byte. */
|
||||
#define _HAVE_STRING_ARCH_strchrnul 1
|
||||
#define __strchrnul(s, c) \
|
||||
(__extension__ (__builtin_constant_p (c) \
|
||||
? ((c) == '\0' \
|
||||
? (char *) __rawmemchr (s, c) \
|
||||
: __strchrnul_c (s, ((c) & 0xff) << 8)) \
|
||||
: __strchrnul_g (s, c)))
|
||||
|
||||
__STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
|
||||
|
||||
__STRING_INLINE char *
|
||||
__strchrnul_g (__const char *__s, int __c)
|
||||
{
|
||||
register unsigned long int __d0;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"movb %%al,%%ah\n"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"cmpb %%ah,%%al\n\t"
|
||||
"je 2f\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b\n\t"
|
||||
"2:\n\t"
|
||||
"movl %1,%0"
|
||||
: "=a" (__res), "=&S" (__d0)
|
||||
: "0" (__c), "1" (__s),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
|
||||
: "cc");
|
||||
return __res - 1;
|
||||
}
|
||||
|
||||
__STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
|
||||
|
||||
__STRING_INLINE char *
|
||||
__strchrnul_c (__const char *__s, int __c)
|
||||
{
|
||||
register unsigned long int __d0;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"cmpb %%ah,%%al\n\t"
|
||||
"je 2f\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b\n\t"
|
||||
"2:\n\t"
|
||||
"movl %1,%0"
|
||||
: "=a" (__res), "=&S" (__d0)
|
||||
: "0" (__c), "1" (__s),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
|
||||
: "cc");
|
||||
return __res - 1;
|
||||
}
|
||||
#ifdef __USE_GNU
|
||||
# define strchrnul(s, c) __strchrnul (s, c)
|
||||
#endif
|
||||
|
||||
|
||||
/* Return the length of the initial segment of S which
|
||||
consists entirely of characters not in REJECT. */
|
||||
#define _HAVE_STRING_ARCH_strcspn 1
|
||||
#ifndef _FORCE_INLINES
|
||||
# ifdef __PIC__
|
||||
__STRING_INLINE size_t
|
||||
strcspn (__const char *__s, __const char *__reject)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("pushl %%ebx\n\t"
|
||||
"cld\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"movl %%ecx,%%ebx\n"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"je 2f\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"movl %%ebx,%%ecx\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"jne 1b\n"
|
||||
"2:\n\t"
|
||||
"popl %%ebx"
|
||||
: "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
|
||||
: "d" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
|
||||
: "cc");
|
||||
return (__res - 1) - __s;
|
||||
}
|
||||
# else
|
||||
__STRING_INLINE size_t
|
||||
strcspn (__const char *__s, __const char *__reject)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2, __d3;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"movl %5,%%edi\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"movl %%ecx,%%edx\n"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"je 2f\n\t"
|
||||
"movl %5,%%edi\n\t"
|
||||
"movl %%edx,%%ecx\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"jne 1b\n"
|
||||
"2:"
|
||||
: "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
|
||||
: "g" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
|
||||
: "cc");
|
||||
return (__res - 1) - __s;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Return the length of the initial segment of S which
|
||||
consists entirely of characters in ACCEPT. */
|
||||
#define _HAVE_STRING_ARCH_strspn 1
|
||||
#ifndef _FORCE_INLINES
|
||||
# ifdef __PIC__
|
||||
__STRING_INLINE size_t
|
||||
strspn (__const char *__s, __const char *__accept)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("pushl %%ebx\n\t"
|
||||
"cld\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"movl %%ecx,%%ebx\n"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"je 2f\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"movl %%ebx,%%ecx\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"je 1b\n"
|
||||
"2:\n\t"
|
||||
"popl %%ebx"
|
||||
: "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
|
||||
: "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
|
||||
: "cc");
|
||||
return (__res - 1) - __s;
|
||||
}
|
||||
# else
|
||||
__STRING_INLINE size_t
|
||||
strspn (__const char *__s, __const char *__accept)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2, __d3;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"movl %5,%%edi\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"movl %%ecx,%%edx\n"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"je 2f\n\t"
|
||||
"movl %5,%%edi\n\t"
|
||||
"movl %%edx,%%ecx\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"je 1b\n"
|
||||
"2:"
|
||||
: "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
|
||||
: "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
|
||||
: "cc");
|
||||
return (__res - 1) - __s;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Find the first occurrence in S of any character in ACCEPT. */
|
||||
#define _HAVE_STRING_ARCH_strpbrk 1
|
||||
#ifndef _FORCE_INLINES
|
||||
# ifdef __PIC__
|
||||
__STRING_INLINE char *
|
||||
strpbrk (__const char *__s, __const char *__accept)
|
||||
{
|
||||
unsigned long int __d0, __d1, __d2;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("pushl %%ebx\n\t"
|
||||
"cld\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"movl %%ecx,%%ebx\n"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"je 2f\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"movl %%ebx,%%ecx\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"jne 1b\n\t"
|
||||
"decl %0\n\t"
|
||||
"jmp 3f\n"
|
||||
"2:\n\t"
|
||||
"xorl %0,%0\n"
|
||||
"3:\n\t"
|
||||
"popl %%ebx"
|
||||
: "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
|
||||
: "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
|
||||
: "cc");
|
||||
return __res;
|
||||
}
|
||||
# else
|
||||
__STRING_INLINE char *
|
||||
strpbrk (__const char *__s, __const char *__accept)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2, __d3;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t"
|
||||
"movl %5,%%edi\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"movl %%ecx,%%edx\n"
|
||||
"1:\n\t"
|
||||
"lodsb\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"je 2f\n\t"
|
||||
"movl %5,%%edi\n\t"
|
||||
"movl %%edx,%%ecx\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"jne 1b\n\t"
|
||||
"decl %0\n\t"
|
||||
"jmp 3f\n"
|
||||
"2:\n\t"
|
||||
"xorl %0,%0\n"
|
||||
"3:"
|
||||
: "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
|
||||
: "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
|
||||
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
|
||||
: "cc");
|
||||
return __res;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Find the first occurrence of NEEDLE in HAYSTACK. */
|
||||
#define _HAVE_STRING_ARCH_strstr 1
|
||||
#ifndef _FORCE_INLINES
|
||||
# ifdef __PIC__
|
||||
__STRING_INLINE char *
|
||||
strstr (__const char *__haystack, __const char *__needle)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("pushl %%ebx\n\t"
|
||||
"cld\n\t" \
|
||||
"movl %4,%%edi\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
|
||||
"movl %%ecx,%%ebx\n"
|
||||
"1:\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"movl %%esi,%%eax\n\t"
|
||||
"movl %%ebx,%%ecx\n\t"
|
||||
"repe; cmpsb\n\t"
|
||||
"je 2f\n\t" /* also works for empty string, see above */
|
||||
"xchgl %%eax,%%esi\n\t"
|
||||
"incl %%esi\n\t"
|
||||
"cmpb $0,-1(%%eax)\n\t"
|
||||
"jne 1b\n\t"
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"2:\n\t"
|
||||
"popl %%ebx"
|
||||
: "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
|
||||
: "r" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
|
||||
: "memory", "cc");
|
||||
return __res;
|
||||
}
|
||||
# else
|
||||
__STRING_INLINE char *
|
||||
strstr (__const char *__haystack, __const char *__needle)
|
||||
{
|
||||
register unsigned long int __d0, __d1, __d2, __d3;
|
||||
register char *__res;
|
||||
__asm__ __volatile__
|
||||
("cld\n\t" \
|
||||
"movl %5,%%edi\n\t"
|
||||
"repne; scasb\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
|
||||
"movl %%ecx,%%edx\n"
|
||||
"1:\n\t"
|
||||
"movl %5,%%edi\n\t"
|
||||
"movl %%esi,%%eax\n\t"
|
||||
"movl %%edx,%%ecx\n\t"
|
||||
"repe; cmpsb\n\t"
|
||||
"je 2f\n\t" /* also works for empty string, see above */
|
||||
"xchgl %%eax,%%esi\n\t"
|
||||
"incl %%esi\n\t"
|
||||
"cmpb $0,-1(%%eax)\n\t"
|
||||
"jne 1b\n\t"
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"2:"
|
||||
: "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&d" (__d2), "=&D" (__d3)
|
||||
: "g" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
|
||||
: "memory", "cc");
|
||||
return __res;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef _FORCE_INLINES
|
||||
# undef __STRING_INLINE
|
||||
#endif
|
||||
|
||||
#endif /* use string inlines && GNU CC */
|
||||
@@ -1,970 +0,0 @@
|
||||
/* Inline math functions for i387 and SSE.
|
||||
Copyright (C) 1995-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _MATH_H
|
||||
# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
|
||||
#endif
|
||||
|
||||
#define __NTH(fct) __attribute__ ((__nothrow__)) fct
|
||||
|
||||
#ifndef __extern_always_inline
|
||||
# define __MATH_INLINE __inline
|
||||
#else
|
||||
# define __MATH_INLINE __extern_always_inline
|
||||
#endif
|
||||
|
||||
|
||||
#if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2
|
||||
/* GCC 2.97 and up have builtins that actually can be used. */
|
||||
# if !__GNUC_PREREQ (2,97)
|
||||
/* ISO C99 defines some macros to perform unordered comparisons. The
|
||||
ix87 FPU supports this with special opcodes and we should use them.
|
||||
These must not be inline functions since we have to be able to handle
|
||||
all floating-point types. */
|
||||
# undef isgreater
|
||||
# undef isgreaterequal
|
||||
# undef isless
|
||||
# undef islessequal
|
||||
# undef islessgreater
|
||||
# undef isunordered
|
||||
# ifdef __i686__
|
||||
/* For the PentiumPro and more recent processors we can provide
|
||||
better code. */
|
||||
# define isgreater(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; seta %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
|
||||
__result; })
|
||||
# define isgreaterequal(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; setae %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
|
||||
__result; })
|
||||
|
||||
# define isless(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; seta %%al" \
|
||||
: "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
|
||||
__result; })
|
||||
|
||||
# define islessequal(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; setae %%al" \
|
||||
: "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
|
||||
__result; })
|
||||
|
||||
# define islessgreater(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; setne %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
|
||||
__result; })
|
||||
|
||||
# define isunordered(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucomip %%st(1), %%st; setp %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
|
||||
__result; })
|
||||
# else
|
||||
/* This is the dumb, portable code for i386 and above. */
|
||||
# define isgreater(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
|
||||
# define isgreaterequal(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
|
||||
# define isless(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
|
||||
: "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
|
||||
# define islessequal(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
|
||||
: "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
|
||||
# define islessgreater(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
|
||||
# define isunordered(x, y) \
|
||||
({ register char __result; \
|
||||
__asm__ ("fucompp; fnstsw; sahf; setp %%al" \
|
||||
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
|
||||
__result; })
|
||||
# endif /* __i686__ */
|
||||
# endif /* GCC 2.97 */
|
||||
|
||||
/* The gcc, version 2.7 or below, has problems with all this inlining
|
||||
code. So disable it for this version of the compiler. */
|
||||
# if __GNUC_PREREQ (2, 8)
|
||||
__BEGIN_NAMESPACE_C99
|
||||
|
||||
/* Test for negative number. Used in the signbit() macro. */
|
||||
__MATH_INLINE int
|
||||
__signbitf (float __x)
|
||||
{
|
||||
# ifdef __SSE2_MATH__
|
||||
int __m;
|
||||
__asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x));
|
||||
return (__m & 0x8) != 0;
|
||||
# else
|
||||
__extension__ union { float __f; int __i; } __u = { __f: __x };
|
||||
return __u.__i < 0;
|
||||
# endif
|
||||
}
|
||||
__MATH_INLINE int
|
||||
__signbit (double __x)
|
||||
{
|
||||
# ifdef __SSE2_MATH__
|
||||
int __m;
|
||||
__asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x));
|
||||
return (__m & 0x80) != 0;
|
||||
# else
|
||||
__extension__ union { double __d; int __i[2]; } __u = { __d: __x };
|
||||
return __u.__i[1] < 0;
|
||||
# endif
|
||||
}
|
||||
__MATH_INLINE int
|
||||
__signbitl (long double __x)
|
||||
{
|
||||
__extension__ union { long double __l; int __i[3]; } __u = { __l: __x };
|
||||
return (__u.__i[2] & 0x8000) != 0;
|
||||
}
|
||||
|
||||
__END_NAMESPACE_C99
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* The gcc, version 2.7 or below, has problems with all this inlining
|
||||
code. So disable it for this version of the compiler. */
|
||||
#if __GNUC_PREREQ (2, 8)
|
||||
# if !__GNUC_PREREQ (3, 4) && !defined __NO_MATH_INLINES \
|
||||
&& defined __OPTIMIZE__
|
||||
/* GCC 3.4 introduced builtins for all functions below, so
|
||||
there's no need to define any of these inline functions. */
|
||||
|
||||
# ifdef __USE_ISOC99
|
||||
__BEGIN_NAMESPACE_C99
|
||||
|
||||
/* Round to nearest integer. */
|
||||
# ifdef __SSE_MATH__
|
||||
__MATH_INLINE long int
|
||||
__NTH (lrintf (float __x))
|
||||
{
|
||||
long int __res;
|
||||
/* Mark as volatile since the result is dependent on the state of
|
||||
the SSE control register (the rounding mode). Otherwise GCC might
|
||||
remove these assembler instructions since it does not know about
|
||||
the rounding mode change and cannot currently be told. */
|
||||
__asm __volatile__ ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
# endif
|
||||
# ifdef __SSE2_MATH__
|
||||
__MATH_INLINE long int
|
||||
__NTH (lrint (double __x))
|
||||
{
|
||||
long int __res;
|
||||
/* Mark as volatile since the result is dependent on the state of
|
||||
the SSE control register (the rounding mode). Otherwise GCC might
|
||||
remove these assembler instructions since it does not know about
|
||||
the rounding mode change and cannot currently be told. */
|
||||
__asm __volatile__ ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
# endif
|
||||
# ifdef __x86_64__
|
||||
__MATH_INLINE long long int
|
||||
__NTH (llrintf (float __x))
|
||||
{
|
||||
long long int __res;
|
||||
/* Mark as volatile since the result is dependent on the state of
|
||||
the SSE control register (the rounding mode). Otherwise GCC might
|
||||
remove these assembler instructions since it does not know about
|
||||
the rounding mode change and cannot currently be told. */
|
||||
__asm __volatile__ ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
__MATH_INLINE long long int
|
||||
__NTH (llrint (double __x))
|
||||
{
|
||||
long long int __res;
|
||||
/* Mark as volatile since the result is dependent on the state of
|
||||
the SSE control register (the rounding mode). Otherwise GCC might
|
||||
remove these assembler instructions since it does not know about
|
||||
the rounding mode change and cannot currently be told. */
|
||||
__asm __volatile__ ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
# endif
|
||||
|
||||
# if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0 \
|
||||
&& defined __SSE2_MATH__
|
||||
/* Determine maximum of two values. */
|
||||
__MATH_INLINE float
|
||||
__NTH (fmaxf (float __x, float __y))
|
||||
{
|
||||
# ifdef __AVX__
|
||||
float __res;
|
||||
__asm ("vmaxss %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y));
|
||||
return __res;
|
||||
# else
|
||||
__asm ("maxss %1, %0" : "+x" (__x) : "xm" (__y));
|
||||
return __x;
|
||||
# endif
|
||||
}
|
||||
__MATH_INLINE double
|
||||
__NTH (fmax (double __x, double __y))
|
||||
{
|
||||
# ifdef __AVX__
|
||||
float __res;
|
||||
__asm ("vmaxsd %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y));
|
||||
return __res;
|
||||
# else
|
||||
__asm ("maxsd %1, %0" : "+x" (__x) : "xm" (__y));
|
||||
return __x;
|
||||
# endif
|
||||
}
|
||||
|
||||
/* Determine minimum of two values. */
|
||||
__MATH_INLINE float
|
||||
__NTH (fminf (float __x, float __y))
|
||||
{
|
||||
# ifdef __AVX__
|
||||
float __res;
|
||||
__asm ("vminss %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y));
|
||||
return __res;
|
||||
# else
|
||||
__asm ("minss %1, %0" : "+x" (__x) : "xm" (__y));
|
||||
return __x;
|
||||
# endif
|
||||
}
|
||||
__MATH_INLINE double
|
||||
__NTH (fmin (double __x, double __y))
|
||||
{
|
||||
# ifdef __AVX__
|
||||
float __res;
|
||||
__asm ("vminsd %2, %1, %0" : "=x" (__res) : "x" (x), "xm" (__y));
|
||||
return __res;
|
||||
# else
|
||||
__asm ("minsd %1, %0" : "+x" (__x) : "xm" (__y));
|
||||
return __x;
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
|
||||
__END_NAMESPACE_C99
|
||||
# endif
|
||||
|
||||
# if defined __SSE4_1__ && defined __SSE2_MATH__
|
||||
# if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
|
||||
__BEGIN_NAMESPACE_C99
|
||||
|
||||
/* Round to nearest integer. */
|
||||
__MATH_INLINE double
|
||||
__NTH (rint (double __x))
|
||||
{
|
||||
double __res;
|
||||
/* Mark as volatile since the result is dependent on the state of
|
||||
the SSE control register (the rounding mode). Otherwise GCC might
|
||||
remove these assembler instructions since it does not know about
|
||||
the rounding mode change and cannot currently be told. */
|
||||
__asm __volatile__ ("roundsd $4, %1, %0" : "=x" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
__MATH_INLINE float
|
||||
__NTH (rintf (float __x))
|
||||
{
|
||||
float __res;
|
||||
/* Mark as volatile since the result is dependent on the state of
|
||||
the SSE control register (the rounding mode). Otherwise GCC might
|
||||
remove these assembler instructions since it does not know about
|
||||
the rounding mode change and cannot currently be told. */
|
||||
__asm __volatile__ ("roundss $4, %1, %0" : "=x" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
|
||||
# ifdef __USE_ISOC99
|
||||
/* Round to nearest integer without raising inexact exception. */
|
||||
__MATH_INLINE double
|
||||
__NTH (nearbyint (double __x))
|
||||
{
|
||||
double __res;
|
||||
/* Mark as volatile since the result is dependent on the state of
|
||||
the SSE control register (the rounding mode). Otherwise GCC might
|
||||
remove these assembler instructions since it does not know about
|
||||
the rounding mode change and cannot currently be told. */
|
||||
__asm __volatile__ ("roundsd $0xc, %1, %0" : "=x" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
__MATH_INLINE float
|
||||
__NTH (nearbyintf (float __x))
|
||||
{
|
||||
float __res;
|
||||
/* Mark as volatile since the result is dependent on the state of
|
||||
the SSE control register (the rounding mode). Otherwise GCC might
|
||||
remove these assembler instructions since it does not know about
|
||||
the rounding mode change and cannot currently be told. */
|
||||
__asm __volatile__ ("roundss $0xc, %1, %0" : "=x" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
# endif
|
||||
|
||||
__END_NAMESPACE_C99
|
||||
# endif
|
||||
|
||||
__BEGIN_NAMESPACE_STD
|
||||
/* Smallest integral value not less than X. */
|
||||
__MATH_INLINE double
|
||||
__NTH (ceil (double __x))
|
||||
{
|
||||
double __res;
|
||||
__asm ("roundsd $2, %1, %0" : "=x" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
__END_NAMESPACE_STD
|
||||
|
||||
__BEGIN_NAMESPACE_C99
|
||||
__MATH_INLINE float
|
||||
__NTH (ceilf (float __x))
|
||||
{
|
||||
float __res;
|
||||
__asm ("roundss $2, %1, %0" : "=x" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
__END_NAMESPACE_C99
|
||||
|
||||
__BEGIN_NAMESPACE_STD
|
||||
/* Largest integer not greater than X. */
|
||||
__MATH_INLINE double
|
||||
__NTH (floor (double __x))
|
||||
{
|
||||
double __res;
|
||||
__asm ("roundsd $1, %1, %0" : "=x" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
__END_NAMESPACE_STD
|
||||
|
||||
__BEGIN_NAMESPACE_C99
|
||||
__MATH_INLINE float
|
||||
__NTH (floorf (float __x))
|
||||
{
|
||||
float __res;
|
||||
__asm ("roundss $1, %1, %0" : "=x" (__res) : "xm" (__x));
|
||||
return __res;
|
||||
}
|
||||
__END_NAMESPACE_C99
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef __x86_64__
|
||||
# if ((!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
|
||||
&& defined __OPTIMIZE__)
|
||||
|
||||
/* The inline functions do not set errno or raise necessarily the
|
||||
correct exceptions. */
|
||||
# undef math_errhandling
|
||||
|
||||
/* A macro to define float, double, and long double versions of various
|
||||
math functions for the ix87 FPU. FUNC is the function name (which will
|
||||
be suffixed with f and l for the float and long double version,
|
||||
respectively). OP is the name of the FPU operation.
|
||||
We define two sets of macros. The set with the additional NP
|
||||
doesn't add a prototype declaration. */
|
||||
|
||||
# if defined __USE_MISC || defined __USE_ISOC99
|
||||
# define __inline_mathop(func, op) \
|
||||
__inline_mathop_ (double, func, op) \
|
||||
__inline_mathop_ (float, __CONCAT(func,f), op) \
|
||||
__inline_mathop_ (long double, __CONCAT(func,l), op)
|
||||
# define __inline_mathopNP(func, op) \
|
||||
__inline_mathopNP_ (double, func, op) \
|
||||
__inline_mathopNP_ (float, __CONCAT(func,f), op) \
|
||||
__inline_mathopNP_ (long double, __CONCAT(func,l), op)
|
||||
# else
|
||||
# define __inline_mathop(func, op) \
|
||||
__inline_mathop_ (double, func, op)
|
||||
# define __inline_mathopNP(func, op) \
|
||||
__inline_mathopNP_ (double, func, op)
|
||||
# endif
|
||||
|
||||
# define __inline_mathop_(float_type, func, op) \
|
||||
__inline_mathop_decl_ (float_type, func, op, "0" (__x))
|
||||
# define __inline_mathopNP_(float_type, func, op) \
|
||||
__inline_mathop_declNP_ (float_type, func, op, "0" (__x))
|
||||
|
||||
|
||||
# if defined __USE_MISC || defined __USE_ISOC99
|
||||
# define __inline_mathop_decl(func, op, params...) \
|
||||
__inline_mathop_decl_ (double, func, op, params) \
|
||||
__inline_mathop_decl_ (float, __CONCAT(func,f), op, params) \
|
||||
__inline_mathop_decl_ (long double, __CONCAT(func,l), op, params)
|
||||
# define __inline_mathop_declNP(func, op, params...) \
|
||||
__inline_mathop_declNP_ (double, func, op, params) \
|
||||
__inline_mathop_declNP_ (float, __CONCAT(func,f), op, params) \
|
||||
__inline_mathop_declNP_ (long double, __CONCAT(func,l), op, params)
|
||||
# else
|
||||
# define __inline_mathop_decl(func, op, params...) \
|
||||
__inline_mathop_decl_ (double, func, op, params)
|
||||
# define __inline_mathop_declNP(func, op, params...) \
|
||||
__inline_mathop_declNP_ (double, func, op, params)
|
||||
# endif
|
||||
|
||||
# define __inline_mathop_decl_(float_type, func, op, params...) \
|
||||
__MATH_INLINE float_type func (float_type) __THROW; \
|
||||
__inline_mathop_declNP_ (float_type, func, op, params)
|
||||
|
||||
# define __inline_mathop_declNP_(float_type, func, op, params...) \
|
||||
__MATH_INLINE float_type __NTH (func (float_type __x)) \
|
||||
{ \
|
||||
register float_type __result; \
|
||||
__asm __volatile__ (op : "=t" (__result) : params); \
|
||||
return __result; \
|
||||
}
|
||||
|
||||
|
||||
# if defined __USE_MISC || defined __USE_ISOC99
|
||||
# define __inline_mathcode(func, arg, code) \
|
||||
__inline_mathcode_ (double, func, arg, code) \
|
||||
__inline_mathcode_ (float, __CONCAT(func,f), arg, code) \
|
||||
__inline_mathcode_ (long double, __CONCAT(func,l), arg, code)
|
||||
# define __inline_mathcodeNP(func, arg, code) \
|
||||
__inline_mathcodeNP_ (double, func, arg, code) \
|
||||
__inline_mathcodeNP_ (float, __CONCAT(func,f), arg, code) \
|
||||
__inline_mathcodeNP_ (long double, __CONCAT(func,l), arg, code)
|
||||
# define __inline_mathcode2(func, arg1, arg2, code) \
|
||||
__inline_mathcode2_ (double, func, arg1, arg2, code) \
|
||||
__inline_mathcode2_ (float, __CONCAT(func,f), arg1, arg2, code) \
|
||||
__inline_mathcode2_ (long double, __CONCAT(func,l), arg1, arg2, code)
|
||||
# define __inline_mathcodeNP2(func, arg1, arg2, code) \
|
||||
__inline_mathcodeNP2_ (double, func, arg1, arg2, code) \
|
||||
__inline_mathcodeNP2_ (float, __CONCAT(func,f), arg1, arg2, code) \
|
||||
__inline_mathcodeNP2_ (long double, __CONCAT(func,l), arg1, arg2, code)
|
||||
# define __inline_mathcode3(func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcode3_ (double, func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcode3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
|
||||
__inline_mathcode3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
|
||||
# define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcodeNP3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
|
||||
__inline_mathcodeNP3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
|
||||
# else
|
||||
# define __inline_mathcode(func, arg, code) \
|
||||
__inline_mathcode_ (double, func, (arg), code)
|
||||
# define __inline_mathcodeNP(func, arg, code) \
|
||||
__inline_mathcodeNP_ (double, func, (arg), code)
|
||||
# define __inline_mathcode2(func, arg1, arg2, code) \
|
||||
__inline_mathcode2_ (double, func, arg1, arg2, code)
|
||||
# define __inline_mathcodeNP2(func, arg1, arg2, code) \
|
||||
__inline_mathcodeNP2_ (double, func, arg1, arg2, code)
|
||||
# define __inline_mathcode3(func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcode3_ (double, func, arg1, arg2, arg3, code)
|
||||
# define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
|
||||
__inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code)
|
||||
# endif
|
||||
|
||||
# define __inline_mathcode_(float_type, func, arg, code) \
|
||||
__MATH_INLINE float_type func (float_type) __THROW; \
|
||||
__inline_mathcodeNP_(float_type, func, arg, code)
|
||||
|
||||
# define __inline_mathcodeNP_(float_type, func, arg, code) \
|
||||
__MATH_INLINE float_type __NTH (func (float_type arg)) \
|
||||
{ \
|
||||
code; \
|
||||
}
|
||||
|
||||
|
||||
# define __inline_mathcode2_(float_type, func, arg1, arg2, code) \
|
||||
__MATH_INLINE float_type func (float_type, float_type) __THROW; \
|
||||
__inline_mathcodeNP2_ (float_type, func, arg1, arg2, code)
|
||||
|
||||
# define __inline_mathcodeNP2_(float_type, func, arg1, arg2, code) \
|
||||
__MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2)) \
|
||||
{ \
|
||||
code; \
|
||||
}
|
||||
|
||||
# define __inline_mathcode3_(float_type, func, arg1, arg2, arg3, code) \
|
||||
__MATH_INLINE float_type func (float_type, float_type, float_type) __THROW; \
|
||||
__inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code)
|
||||
|
||||
# define __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code) \
|
||||
__MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2, \
|
||||
float_type arg3)) \
|
||||
{ \
|
||||
code; \
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
# if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
|
||||
/* Miscellaneous functions */
|
||||
|
||||
/* __FAST_MATH__ is defined by gcc -ffast-math. */
|
||||
# ifdef __FAST_MATH__
|
||||
# ifdef __USE_GNU
|
||||
# define __sincos_code \
|
||||
register long double __cosr; \
|
||||
register long double __sinr; \
|
||||
register unsigned int __swtmp; \
|
||||
__asm __volatile__ \
|
||||
("fsincos\n\t" \
|
||||
"fnstsw %w2\n\t" \
|
||||
"testl $0x400, %2\n\t" \
|
||||
"jz 1f\n\t" \
|
||||
"fldpi\n\t" \
|
||||
"fadd %%st(0)\n\t" \
|
||||
"fxch %%st(1)\n\t" \
|
||||
"2: fprem1\n\t" \
|
||||
"fnstsw %w2\n\t" \
|
||||
"testl $0x400, %2\n\t" \
|
||||
"jnz 2b\n\t" \
|
||||
"fstp %%st(1)\n\t" \
|
||||
"fsincos\n\t" \
|
||||
"1:" \
|
||||
: "=t" (__cosr), "=u" (__sinr), "=a" (__swtmp) : "0" (__x)); \
|
||||
*__sinx = __sinr; \
|
||||
*__cosx = __cosr
|
||||
|
||||
__MATH_INLINE void
|
||||
__NTH (__sincos (double __x, double *__sinx, double *__cosx))
|
||||
{
|
||||
__sincos_code;
|
||||
}
|
||||
|
||||
__MATH_INLINE void
|
||||
__NTH (__sincosf (float __x, float *__sinx, float *__cosx))
|
||||
{
|
||||
__sincos_code;
|
||||
}
|
||||
|
||||
__MATH_INLINE void
|
||||
__NTH (__sincosl (long double __x, long double *__sinx, long double *__cosx))
|
||||
{
|
||||
__sincos_code;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
/* Optimized inline implementation, sometimes with reduced precision
|
||||
and/or argument range. */
|
||||
|
||||
# if __GNUC_PREREQ (3, 5)
|
||||
# define __expm1_code \
|
||||
register long double __temp; \
|
||||
__temp = __builtin_expm1l (__x); \
|
||||
return __temp ? __temp : __x
|
||||
# else
|
||||
# define __expm1_code \
|
||||
register long double __value; \
|
||||
register long double __exponent; \
|
||||
register long double __temp; \
|
||||
__asm __volatile__ \
|
||||
("fldl2e # e^x - 1 = 2^(x * log2(e)) - 1\n\t" \
|
||||
"fmul %%st(1) # x * log2(e)\n\t" \
|
||||
"fst %%st(1)\n\t" \
|
||||
"frndint # int(x * log2(e))\n\t" \
|
||||
"fxch\n\t" \
|
||||
"fsub %%st(1) # fract(x * log2(e))\n\t" \
|
||||
"f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
|
||||
"fscale # 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" \
|
||||
: "=t" (__value), "=u" (__exponent) : "0" (__x)); \
|
||||
__asm __volatile__ \
|
||||
("fscale # 2^int(x * log2(e))\n\t" \
|
||||
: "=t" (__temp) : "0" (1.0), "u" (__exponent)); \
|
||||
__temp -= 1.0; \
|
||||
__temp += __value; \
|
||||
return __temp ? __temp : __x
|
||||
# endif
|
||||
__inline_mathcodeNP_ (long double, __expm1l, __x, __expm1_code)
|
||||
|
||||
# if __GNUC_PREREQ (3, 4)
|
||||
__inline_mathcodeNP_ (long double, __expl, __x, return __builtin_expl (__x))
|
||||
# else
|
||||
# define __exp_code \
|
||||
register long double __value; \
|
||||
register long double __exponent; \
|
||||
__asm __volatile__ \
|
||||
("fldl2e # e^x = 2^(x * log2(e))\n\t" \
|
||||
"fmul %%st(1) # x * log2(e)\n\t" \
|
||||
"fst %%st(1)\n\t" \
|
||||
"frndint # int(x * log2(e))\n\t" \
|
||||
"fxch\n\t" \
|
||||
"fsub %%st(1) # fract(x * log2(e))\n\t" \
|
||||
"f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
|
||||
: "=t" (__value), "=u" (__exponent) : "0" (__x)); \
|
||||
__value += 1.0; \
|
||||
__asm __volatile__ \
|
||||
("fscale" \
|
||||
: "=t" (__value) : "0" (__value), "u" (__exponent)); \
|
||||
return __value
|
||||
__inline_mathcodeNP (exp, __x, __exp_code)
|
||||
__inline_mathcodeNP_ (long double, __expl, __x, __exp_code)
|
||||
# endif
|
||||
|
||||
|
||||
# if !__GNUC_PREREQ (3, 5)
|
||||
__inline_mathcodeNP (tan, __x, \
|
||||
register long double __value; \
|
||||
register long double __value2 __attribute__ ((__unused__)); \
|
||||
__asm __volatile__ \
|
||||
("fptan" \
|
||||
: "=t" (__value2), "=u" (__value) : "0" (__x)); \
|
||||
return __value)
|
||||
# endif
|
||||
# endif /* __FAST_MATH__ */
|
||||
|
||||
|
||||
# if __GNUC_PREREQ (3, 4)
|
||||
__inline_mathcodeNP2_ (long double, __atan2l, __y, __x,
|
||||
return __builtin_atan2l (__y, __x))
|
||||
# else
|
||||
# define __atan2_code \
|
||||
register long double __value; \
|
||||
__asm __volatile__ \
|
||||
("fpatan" \
|
||||
: "=t" (__value) : "0" (__x), "u" (__y) : "st(1)"); \
|
||||
return __value
|
||||
# ifdef __FAST_MATH__
|
||||
__inline_mathcodeNP2 (atan2, __y, __x, __atan2_code)
|
||||
# endif
|
||||
__inline_mathcodeNP2_ (long double, __atan2l, __y, __x, __atan2_code)
|
||||
# endif
|
||||
|
||||
|
||||
# if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
|
||||
__inline_mathcodeNP2 (fmod, __x, __y, \
|
||||
register long double __value; \
|
||||
__asm __volatile__ \
|
||||
("1: fprem\n\t" \
|
||||
"fnstsw %%ax\n\t" \
|
||||
"sahf\n\t" \
|
||||
"jp 1b" \
|
||||
: "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc"); \
|
||||
return __value)
|
||||
# endif
|
||||
|
||||
|
||||
# ifdef __FAST_MATH__
|
||||
# if !__GNUC_PREREQ (3,3)
|
||||
__inline_mathopNP (sqrt, "fsqrt")
|
||||
__inline_mathopNP_ (long double, __sqrtl, "fsqrt")
|
||||
# define __libc_sqrtl(n) __sqrtl (n)
|
||||
# else
|
||||
# define __libc_sqrtl(n) __builtin_sqrtl (n)
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if __GNUC_PREREQ (2, 8)
|
||||
__inline_mathcodeNP_ (double, fabs, __x, return __builtin_fabs (__x))
|
||||
# if defined __USE_MISC || defined __USE_ISOC99
|
||||
__inline_mathcodeNP_ (float, fabsf, __x, return __builtin_fabsf (__x))
|
||||
__inline_mathcodeNP_ (long double, fabsl, __x, return __builtin_fabsl (__x))
|
||||
# endif
|
||||
__inline_mathcodeNP_ (long double, __fabsl, __x, return __builtin_fabsl (__x))
|
||||
# else
|
||||
__inline_mathop (fabs, "fabs")
|
||||
__inline_mathop_ (long double, __fabsl, "fabs")
|
||||
# endif
|
||||
|
||||
# ifdef __FAST_MATH__
|
||||
# if !__GNUC_PREREQ (3, 4)
|
||||
/* The argument range of this inline version is reduced. */
|
||||
__inline_mathopNP (sin, "fsin")
|
||||
/* The argument range of this inline version is reduced. */
|
||||
__inline_mathopNP (cos, "fcos")
|
||||
|
||||
__inline_mathop_declNP (log, "fldln2; fxch; fyl2x", "0" (__x) : "st(1)")
|
||||
# endif
|
||||
|
||||
# if !__GNUC_PREREQ (3, 5)
|
||||
__inline_mathop_declNP (log10, "fldlg2; fxch; fyl2x", "0" (__x) : "st(1)")
|
||||
|
||||
__inline_mathcodeNP (asin, __x, return __atan2l (__x, __libc_sqrtl (1.0 - __x * __x)))
|
||||
__inline_mathcodeNP (acos, __x, return __atan2l (__libc_sqrtl (1.0 - __x * __x), __x))
|
||||
# endif
|
||||
|
||||
# if !__GNUC_PREREQ (3, 4)
|
||||
__inline_mathop_declNP (atan, "fld1; fpatan", "0" (__x) : "st(1)")
|
||||
# endif
|
||||
# endif /* __FAST_MATH__ */
|
||||
|
||||
__inline_mathcode_ (long double, __sgn1l, __x, \
|
||||
__extension__ union { long double __xld; unsigned int __xi[3]; } __n = \
|
||||
{ __xld: __x }; \
|
||||
__n.__xi[2] = (__n.__xi[2] & 0x8000) | 0x3fff; \
|
||||
__n.__xi[1] = 0x80000000; \
|
||||
__n.__xi[0] = 0; \
|
||||
return __n.__xld)
|
||||
|
||||
|
||||
# ifdef __FAST_MATH__
|
||||
/* The argument range of the inline version of sinhl is slightly reduced. */
|
||||
__inline_mathcodeNP (sinh, __x, \
|
||||
register long double __exm1 = __expm1l (__fabsl (__x)); \
|
||||
return 0.5 * (__exm1 / (__exm1 + 1.0) + __exm1) * __sgn1l (__x))
|
||||
|
||||
__inline_mathcodeNP (cosh, __x, \
|
||||
register long double __ex = __expl (__x); \
|
||||
return 0.5 * (__ex + 1.0 / __ex))
|
||||
|
||||
__inline_mathcodeNP (tanh, __x, \
|
||||
register long double __exm1 = __expm1l (-__fabsl (__x + __x)); \
|
||||
return __exm1 / (__exm1 + 2.0) * __sgn1l (-__x))
|
||||
# endif
|
||||
|
||||
__inline_mathcodeNP (floor, __x, \
|
||||
register long double __value; \
|
||||
register int __ignore; \
|
||||
unsigned short int __cw; \
|
||||
unsigned short int __cwtmp; \
|
||||
__asm __volatile ("fnstcw %3\n\t" \
|
||||
"movzwl %3, %1\n\t" \
|
||||
"andl $0xf3ff, %1\n\t" \
|
||||
"orl $0x0400, %1\n\t" /* rounding down */ \
|
||||
"movw %w1, %2\n\t" \
|
||||
"fldcw %2\n\t" \
|
||||
"frndint\n\t" \
|
||||
"fldcw %3" \
|
||||
: "=t" (__value), "=&q" (__ignore), "=m" (__cwtmp), \
|
||||
"=m" (__cw) \
|
||||
: "0" (__x)); \
|
||||
return __value)
|
||||
|
||||
__inline_mathcodeNP (ceil, __x, \
|
||||
register long double __value; \
|
||||
register int __ignore; \
|
||||
unsigned short int __cw; \
|
||||
unsigned short int __cwtmp; \
|
||||
__asm __volatile ("fnstcw %3\n\t" \
|
||||
"movzwl %3, %1\n\t" \
|
||||
"andl $0xf3ff, %1\n\t" \
|
||||
"orl $0x0800, %1\n\t" /* rounding up */ \
|
||||
"movw %w1, %2\n\t" \
|
||||
"fldcw %2\n\t" \
|
||||
"frndint\n\t" \
|
||||
"fldcw %3" \
|
||||
: "=t" (__value), "=&q" (__ignore), "=m" (__cwtmp), \
|
||||
"=m" (__cw) \
|
||||
: "0" (__x)); \
|
||||
return __value)
|
||||
|
||||
# ifdef __FAST_MATH__
|
||||
# define __ldexp_code \
|
||||
register long double __value; \
|
||||
__asm __volatile__ \
|
||||
("fscale" \
|
||||
: "=t" (__value) : "0" (__x), "u" ((long double) __y)); \
|
||||
return __value
|
||||
|
||||
__MATH_INLINE double
|
||||
__NTH (ldexp (double __x, int __y))
|
||||
{
|
||||
__ldexp_code;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
/* Optimized versions for some non-standardized functions. */
|
||||
# if defined __USE_ISOC99 || defined __USE_MISC
|
||||
|
||||
# ifdef __FAST_MATH__
|
||||
__inline_mathcodeNP (expm1, __x, __expm1_code)
|
||||
|
||||
/* We cannot rely on M_SQRT being defined. So we do it for ourself
|
||||
here. */
|
||||
# define __M_SQRT2 1.41421356237309504880L /* sqrt(2) */
|
||||
|
||||
# if !__GNUC_PREREQ (3, 5)
|
||||
__inline_mathcodeNP (log1p, __x, \
|
||||
register long double __value; \
|
||||
if (__fabsl (__x) >= 1.0 - 0.5 * __M_SQRT2) \
|
||||
__value = logl (1.0 + __x); \
|
||||
else \
|
||||
__asm __volatile__ \
|
||||
("fldln2\n\t" \
|
||||
"fxch\n\t" \
|
||||
"fyl2xp1" \
|
||||
: "=t" (__value) : "0" (__x) : "st(1)"); \
|
||||
return __value)
|
||||
# endif
|
||||
|
||||
|
||||
/* The argument range of the inline version of asinhl is slightly reduced. */
|
||||
__inline_mathcodeNP (asinh, __x, \
|
||||
register long double __y = __fabsl (__x); \
|
||||
return (log1pl (__y * __y / (__libc_sqrtl (__y * __y + 1.0) + 1.0) + __y) \
|
||||
* __sgn1l (__x)))
|
||||
|
||||
__inline_mathcodeNP (acosh, __x, \
|
||||
return logl (__x + __libc_sqrtl (__x - 1.0) * __libc_sqrtl (__x + 1.0)))
|
||||
|
||||
__inline_mathcodeNP (atanh, __x, \
|
||||
register long double __y = __fabsl (__x); \
|
||||
return -0.5 * log1pl (-(__y + __y) / (1.0 + __y)) * __sgn1l (__x))
|
||||
|
||||
/* The argument range of the inline version of hypotl is slightly reduced. */
|
||||
__inline_mathcodeNP2 (hypot, __x, __y,
|
||||
return __libc_sqrtl (__x * __x + __y * __y))
|
||||
|
||||
# if !__GNUC_PREREQ (3, 5)
|
||||
__inline_mathcodeNP(logb, __x, \
|
||||
register long double __value; \
|
||||
register long double __junk; \
|
||||
__asm __volatile__ \
|
||||
("fxtract\n\t" \
|
||||
: "=t" (__junk), "=u" (__value) : "0" (__x)); \
|
||||
return __value)
|
||||
# endif
|
||||
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef __USE_ISOC99
|
||||
# ifdef __FAST_MATH__
|
||||
|
||||
# if !__GNUC_PREREQ (3, 5)
|
||||
__inline_mathop_declNP (log2, "fld1; fxch; fyl2x", "0" (__x) : "st(1)")
|
||||
# endif
|
||||
|
||||
__MATH_INLINE float
|
||||
__NTH (ldexpf (float __x, int __y))
|
||||
{
|
||||
__ldexp_code;
|
||||
}
|
||||
|
||||
__MATH_INLINE long double
|
||||
__NTH (ldexpl (long double __x, int __y))
|
||||
{
|
||||
__ldexp_code;
|
||||
}
|
||||
|
||||
__inline_mathopNP (rint, "frndint")
|
||||
# endif /* __FAST_MATH__ */
|
||||
|
||||
# define __lrint_code \
|
||||
long int __lrintres; \
|
||||
__asm__ __volatile__ \
|
||||
("fistpl %0" \
|
||||
: "=m" (__lrintres) : "t" (__x) : "st"); \
|
||||
return __lrintres
|
||||
__MATH_INLINE long int
|
||||
__NTH (lrintf (float __x))
|
||||
{
|
||||
__lrint_code;
|
||||
}
|
||||
__MATH_INLINE long int
|
||||
__NTH (lrint (double __x))
|
||||
{
|
||||
__lrint_code;
|
||||
}
|
||||
__MATH_INLINE long int
|
||||
__NTH (lrintl (long double __x))
|
||||
{
|
||||
__lrint_code;
|
||||
}
|
||||
# undef __lrint_code
|
||||
|
||||
# define __llrint_code \
|
||||
long long int __llrintres; \
|
||||
__asm__ __volatile__ \
|
||||
("fistpll %0" \
|
||||
: "=m" (__llrintres) : "t" (__x) : "st"); \
|
||||
return __llrintres
|
||||
__MATH_INLINE long long int
|
||||
__NTH (llrintf (float __x))
|
||||
{
|
||||
__llrint_code;
|
||||
}
|
||||
__MATH_INLINE long long int
|
||||
__NTH (llrint (double __x))
|
||||
{
|
||||
__llrint_code;
|
||||
}
|
||||
__MATH_INLINE long long int
|
||||
__NTH (llrintl (long double __x))
|
||||
{
|
||||
__llrint_code;
|
||||
}
|
||||
# undef __llrint_code
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
# ifdef __USE_MISC
|
||||
|
||||
# if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
|
||||
__inline_mathcodeNP2 (drem, __x, __y, \
|
||||
register double __value; \
|
||||
register int __clobbered; \
|
||||
__asm __volatile__ \
|
||||
("1: fprem1\n\t" \
|
||||
"fstsw %%ax\n\t" \
|
||||
"sahf\n\t" \
|
||||
"jp 1b" \
|
||||
: "=t" (__value), "=&a" (__clobbered) : "0" (__x), "u" (__y) : "cc"); \
|
||||
return __value)
|
||||
# endif
|
||||
|
||||
|
||||
/* This function is used in the `isfinite' macro. */
|
||||
__MATH_INLINE int
|
||||
__NTH (__finite (double __x))
|
||||
{
|
||||
return (__extension__
|
||||
(((((union { double __d; int __i[2]; }) {__d: __x}).__i[1]
|
||||
| 0x800fffffu) + 1) >> 31));
|
||||
}
|
||||
|
||||
# endif /* __USE_MISC */
|
||||
|
||||
/* Undefine some of the large macros which are not used anymore. */
|
||||
# undef __atan2_code
|
||||
# ifdef __FAST_MATH__
|
||||
# undef __expm1_code
|
||||
# undef __exp_code
|
||||
# undef __sincos_code
|
||||
# endif /* __FAST_MATH__ */
|
||||
|
||||
# endif /* __NO_MATH_INLINES */
|
||||
|
||||
|
||||
/* This code is used internally in the GNU libc. */
|
||||
# ifdef __LIBC_INTERNAL_MATH_INLINES
|
||||
__inline_mathop (__ieee754_sqrt, "fsqrt")
|
||||
__inline_mathcode2 (__ieee754_atan2, __y, __x,
|
||||
register long double __value;
|
||||
__asm __volatile__ ("fpatan\n\t"
|
||||
: "=t" (__value)
|
||||
: "0" (__x), "u" (__y) : "st(1)");
|
||||
return __value;)
|
||||
# endif
|
||||
|
||||
#endif /* !__x86_64__ */
|
||||
@@ -1,39 +0,0 @@
|
||||
/* Properties of long double type.
|
||||
Copyright (C) 2016-2018 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This header is included by <sys/cdefs.h>.
|
||||
|
||||
If long double is ABI-compatible with double, it should define
|
||||
__NO_LONG_DOUBLE_MATH to 1; otherwise, it should leave
|
||||
__NO_LONG_DOUBLE_MATH undefined.
|
||||
|
||||
If this build of the GNU C Library supports both long double
|
||||
ABI-compatible with double and some other long double format not
|
||||
ABI-compatible with double, it should define
|
||||
__LONG_DOUBLE_MATH_OPTIONAL to 1; otherwise, it should leave
|
||||
__LONG_DOUBLE_MATH_OPTIONAL undefined.
|
||||
|
||||
If __NO_LONG_DOUBLE_MATH is already defined, this header must not
|
||||
define anything; this is needed to work with the definition of
|
||||
__NO_LONG_DOUBLE_MATH in nldbl-compat.h. */
|
||||
|
||||
/* In the default version of this header, long double is
|
||||
ABI-compatible with double. */
|
||||
#ifndef __NO_LONG_DOUBLE_MATH
|
||||
# define __NO_LONG_DOUBLE_MATH 1
|
||||
#endif
|
||||
@@ -441,12 +441,6 @@ extern int matherr (struct exception *__exc);
|
||||
# define __NO_MATH_INLINES 1
|
||||
#endif
|
||||
|
||||
/* Get machine-dependent inline versions (if there are any). */
|
||||
#ifdef __USE_EXTERN_INLINES
|
||||
# include <bits/mathinline.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if __USE_ISOC99
|
||||
/* ISO C99 defines some macros to compare number while taking care
|
||||
for unordered numbers. Since many FPUs provide special
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user