URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/gnu-old/gcc-4.2.2/gcc/config/soft-fp
- from Rev 154 to Rev 816
- ↔ Reverse comparison
Rev 154 → Rev 816
/quad.h
0,0 → 1,271
/* Software floating-point emulation. |
Definitions for IEEE Quad Precision. |
Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com), |
Jakub Jelinek (jj@ultra.linux.cz), |
David S. Miller (davem@redhat.com) and |
Peter Maydell (pmaydell@chiark.greenend.org.uk). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#if _FP_W_TYPE_SIZE < 32 |
#error "Here's a nickel, kid. Go buy yourself a real computer." |
#endif |
|
#if _FP_W_TYPE_SIZE < 64 |
#define _FP_FRACTBITS_Q (4*_FP_W_TYPE_SIZE) |
#else |
#define _FP_FRACTBITS_Q (2*_FP_W_TYPE_SIZE) |
#endif |
|
#define _FP_FRACBITS_Q 113 |
#define _FP_FRACXBITS_Q (_FP_FRACTBITS_Q - _FP_FRACBITS_Q) |
#define _FP_WFRACBITS_Q (_FP_WORKBITS + _FP_FRACBITS_Q) |
#define _FP_WFRACXBITS_Q (_FP_FRACTBITS_Q - _FP_WFRACBITS_Q) |
#define _FP_EXPBITS_Q 15 |
#define _FP_EXPBIAS_Q 16383 |
#define _FP_EXPMAX_Q 32767 |
|
#define _FP_QNANBIT_Q \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE) |
#define _FP_QNANBIT_SH_Q \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) |
#define _FP_IMPLBIT_Q \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE) |
#define _FP_IMPLBIT_SH_Q \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) |
#define _FP_OVERFLOW_Q \ |
((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE)) |
|
typedef float TFtype __attribute__((mode(TF))); |
|
#if _FP_W_TYPE_SIZE < 64 |
|
union _FP_UNION_Q |
{ |
TFtype flt; |
struct |
{ |
#if __BYTE_ORDER == __BIG_ENDIAN |
unsigned sign : 1; |
unsigned exp : _FP_EXPBITS_Q; |
unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); |
unsigned long frac2 : _FP_W_TYPE_SIZE; |
unsigned long frac1 : _FP_W_TYPE_SIZE; |
unsigned long frac0 : _FP_W_TYPE_SIZE; |
#else |
unsigned long frac0 : _FP_W_TYPE_SIZE; |
unsigned long frac1 : _FP_W_TYPE_SIZE; |
unsigned long frac2 : _FP_W_TYPE_SIZE; |
unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); |
unsigned exp : _FP_EXPBITS_Q; |
unsigned sign : 1; |
#endif /* not bigendian */ |
} bits __attribute__((packed)); |
}; |
|
|
#define FP_DECL_Q(X) _FP_DECL(4,X) |
#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_4(Q,X,val) |
#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_4_P(Q,X,val) |
#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_4(Q,val,X) |
#define FP_PACK_RAW_QP(val,X) \ |
do { \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_4_P(Q,val,X); \ |
} while (0) |
|
#define FP_UNPACK_Q(X,val) \ |
do { \ |
_FP_UNPACK_RAW_4(Q,X,val); \ |
_FP_UNPACK_CANONICAL(Q,4,X); \ |
} while (0) |
|
#define FP_UNPACK_QP(X,val) \ |
do { \ |
_FP_UNPACK_RAW_4_P(Q,X,val); \ |
_FP_UNPACK_CANONICAL(Q,4,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_Q(X,val) \ |
do { \ |
_FP_UNPACK_RAW_4(Q,X,val); \ |
_FP_UNPACK_SEMIRAW(Q,4,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_QP(X,val) \ |
do { \ |
_FP_UNPACK_RAW_4_P(Q,X,val); \ |
_FP_UNPACK_SEMIRAW(Q,4,X); \ |
} while (0) |
|
#define FP_PACK_Q(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(Q,4,X); \ |
_FP_PACK_RAW_4(Q,val,X); \ |
} while (0) |
|
#define FP_PACK_QP(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(Q,4,X); \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_4_P(Q,val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_Q(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(Q,4,X); \ |
_FP_PACK_RAW_4(Q,val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_QP(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(Q,4,X); \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_4_P(Q,val,X); \ |
} while (0) |
|
#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,4,X) |
#define FP_NEG_Q(R,X) _FP_NEG(Q,4,R,X) |
#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,4,R,X,Y) |
#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,4,R,X,Y) |
#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,4,R,X,Y) |
#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,4,R,X,Y) |
#define FP_SQRT_Q(R,X) _FP_SQRT(Q,4,R,X) |
#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_4(R,S,T,X,Q) |
|
#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,4,r,X,Y,un) |
#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,4,r,X,Y) |
#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,4,r,X,Y) |
|
#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,4,r,X,rsz,rsg) |
#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,4,X,r,rs,rt) |
|
#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_4(X) |
#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_4(X) |
|
#else /* not _FP_W_TYPE_SIZE < 64 */ |
union _FP_UNION_Q |
{ |
TFtype flt /* __attribute__((mode(TF))) */ ; |
struct { |
_FP_W_TYPE a, b; |
} longs; |
struct { |
#if __BYTE_ORDER == __BIG_ENDIAN |
unsigned sign : 1; |
unsigned exp : _FP_EXPBITS_Q; |
_FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; |
_FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; |
#else |
_FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; |
_FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; |
unsigned exp : _FP_EXPBITS_Q; |
unsigned sign : 1; |
#endif |
} bits; |
}; |
|
#define FP_DECL_Q(X) _FP_DECL(2,X) |
#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_2(Q,X,val) |
#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_2_P(Q,X,val) |
#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_2(Q,val,X) |
#define FP_PACK_RAW_QP(val,X) \ |
do { \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_2_P(Q,val,X); \ |
} while (0) |
|
#define FP_UNPACK_Q(X,val) \ |
do { \ |
_FP_UNPACK_RAW_2(Q,X,val); \ |
_FP_UNPACK_CANONICAL(Q,2,X); \ |
} while (0) |
|
#define FP_UNPACK_QP(X,val) \ |
do { \ |
_FP_UNPACK_RAW_2_P(Q,X,val); \ |
_FP_UNPACK_CANONICAL(Q,2,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_Q(X,val) \ |
do { \ |
_FP_UNPACK_RAW_2(Q,X,val); \ |
_FP_UNPACK_SEMIRAW(Q,2,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_QP(X,val) \ |
do { \ |
_FP_UNPACK_RAW_2_P(Q,X,val); \ |
_FP_UNPACK_SEMIRAW(Q,2,X); \ |
} while (0) |
|
#define FP_PACK_Q(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(Q,2,X); \ |
_FP_PACK_RAW_2(Q,val,X); \ |
} while (0) |
|
#define FP_PACK_QP(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(Q,2,X); \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_2_P(Q,val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_Q(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(Q,2,X); \ |
_FP_PACK_RAW_2(Q,val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_QP(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(Q,2,X); \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_2_P(Q,val,X); \ |
} while (0) |
|
#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,2,X) |
#define FP_NEG_Q(R,X) _FP_NEG(Q,2,R,X) |
#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,2,R,X,Y) |
#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,2,R,X,Y) |
#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,2,R,X,Y) |
#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,2,R,X,Y) |
#define FP_SQRT_Q(R,X) _FP_SQRT(Q,2,R,X) |
#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) |
|
#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,2,r,X,Y,un) |
#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,2,r,X,Y) |
#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,2,r,X,Y) |
|
#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,2,r,X,rsz,rsg) |
#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,2,X,r,rs,rt) |
|
#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_2(X) |
#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_2(X) |
|
#endif /* not _FP_W_TYPE_SIZE < 64 */ |
/unordsf2.c
0,0 → 1,46
/* Software floating-point emulation. |
Return 1 iff a or b is a NaN, 0 otherwise. |
Copyright (C) 2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Joseph Myers (joseph@codesourcery.com). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
int |
__unordsf2(SFtype a, SFtype b) |
{ |
FP_DECL_S(A); |
FP_DECL_S(B); |
int r; |
|
FP_UNPACK_RAW_S(A, a); |
FP_UNPACK_RAW_S(B, b); |
FP_CMP_UNORD_S(r, A, B); |
|
return r; |
} |
/fixunstfsi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 32bit unsigned integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
USItype __fixunstfsi(TFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); |
USItype r; |
|
FP_UNPACK_RAW_Q(A, a); |
FP_TO_INT_Q(r, A, SI_BITS, 0); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/unordtf2.c
0,0 → 1,46
/* Software floating-point emulation. |
Return 1 iff a or b is a NaN, 0 otherwise. |
Copyright (C) 2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Joseph Myers (joseph@codesourcery.com). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
int |
__unordtf2(TFtype a, TFtype b) |
{ |
FP_DECL_Q(A); |
FP_DECL_Q(B); |
int r; |
|
FP_UNPACK_RAW_Q(A, a); |
FP_UNPACK_RAW_Q(B, b); |
FP_CMP_UNORD_Q(r, A, B); |
|
return r; |
} |
/floatdisf.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a 64bit signed integer to IEEE single |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
SFtype __floatdisf(DItype i) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); |
SFtype a; |
|
FP_FROM_INT_S(A, i, DI_BITS, UDItype); |
FP_PACK_RAW_S(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/lesf2.c
0,0 → 1,51
/* Software floating-point emulation. |
Return 0 iff a == b, 1 iff a > b, 2 iff a ? b, -1 iff a < b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
int __lesf2(SFtype a, SFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); FP_DECL_S(B); |
int r; |
|
FP_UNPACK_RAW_S(A, a); |
FP_UNPACK_RAW_S(B, b); |
FP_CMP_S(r, A, B, 2); |
if (r == 2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B))) |
FP_SET_EXCEPTION(FP_EX_INVALID); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
|
strong_alias(__lesf2, __ltsf2); |
/fixtfsi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 32bit signed integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
SItype __fixtfsi(TFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); |
USItype r; |
|
FP_UNPACK_RAW_Q(A, a); |
FP_TO_INT_Q(r, A, SI_BITS, 1); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/extendsfdf2.c
0,0 → 1,54
/* Software floating-point emulation. |
Return a converted to IEEE double |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
#include "double.h" |
|
DFtype __extendsfdf2(SFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); |
FP_DECL_D(R); |
DFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_RAW_S(A, a); |
#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D |
FP_EXTEND(D,S,2,1,R,A); |
#else |
FP_EXTEND(D,S,1,1,R,A); |
#endif |
FP_PACK_RAW_D(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/letf2.c
0,0 → 1,51
/* Software floating-point emulation. |
Return 0 iff a == b, 1 iff a > b, 2 iff a ? b, -1 iff a < b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
int __letf2(TFtype a, TFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); FP_DECL_Q(B); |
int r; |
|
FP_UNPACK_RAW_Q(A, a); |
FP_UNPACK_RAW_Q(B, b); |
FP_CMP_Q(r, A, B, 2); |
if (r == 2 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) |
FP_SET_EXCEPTION(FP_EX_INVALID); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
|
strong_alias(__letf2, __lttf2); |
/floatunsidf.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a 32bit unsigned integer to IEEE double |
Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
DFtype __floatunsidf(USItype i) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); |
DFtype a; |
|
FP_FROM_INT_D(A, i, SI_BITS, USItype); |
FP_PACK_RAW_D(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/divdf3.c
0,0 → 1,49
/* Software floating-point emulation. |
Return a / b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
DFtype __divdf3(DFtype a, DFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); |
DFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_D(A, a); |
FP_UNPACK_D(B, b); |
FP_DIV_D(R, A, B); |
FP_PACK_D(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/truncdfsf2.c
0,0 → 1,54
/* Software floating-point emulation. |
Truncate IEEE double into IEEE single |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
#include "double.h" |
|
SFtype __truncdfsf2(DFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); |
FP_DECL_S(R); |
SFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_SEMIRAW_D(A, a); |
#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D |
FP_TRUNC(S,D,1,2,R,A); |
#else |
FP_TRUNC(S,D,1,1,R,A); |
#endif |
FP_PACK_SEMIRAW_S(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/trunctfdf2.c
0,0 → 1,54
/* Software floating-point emulation. |
Truncate IEEE quad into IEEE double |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
#include "quad.h" |
|
DFtype __trunctfdf2(TFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); |
FP_DECL_D(R); |
DFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_SEMIRAW_Q(A, a); |
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q |
FP_TRUNC(D,Q,2,4,R,A); |
#else |
FP_TRUNC(D,Q,1,2,R,A); |
#endif |
FP_PACK_SEMIRAW_D(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/op-1.h
0,0 → 1,302
/* Software floating-point emulation. |
Basic one-word fraction declaration and manipulation. |
Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com), |
Jakub Jelinek (jj@ultra.linux.cz), |
David S. Miller (davem@redhat.com) and |
Peter Maydell (pmaydell@chiark.greenend.org.uk). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#define _FP_FRAC_DECL_1(X) _FP_W_TYPE X##_f |
#define _FP_FRAC_COPY_1(D,S) (D##_f = S##_f) |
#define _FP_FRAC_SET_1(X,I) (X##_f = I) |
#define _FP_FRAC_HIGH_1(X) (X##_f) |
#define _FP_FRAC_LOW_1(X) (X##_f) |
#define _FP_FRAC_WORD_1(X,w) (X##_f) |
|
#define _FP_FRAC_ADDI_1(X,I) (X##_f += I) |
#define _FP_FRAC_SLL_1(X,N) \ |
do { \ |
if (__builtin_constant_p(N) && (N) == 1) \ |
X##_f += X##_f; \ |
else \ |
X##_f <<= (N); \ |
} while (0) |
#define _FP_FRAC_SRL_1(X,N) (X##_f >>= N) |
|
/* Right shift with sticky-lsb. */ |
#define _FP_FRAC_SRST_1(X,S,N,sz) __FP_FRAC_SRST_1(X##_f, S, N, sz) |
#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz) |
|
#define __FP_FRAC_SRST_1(X,S,N,sz) \ |
do { \ |
S = (__builtin_constant_p(N) && (N) == 1 \ |
? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \ |
X = X >> (N); \ |
} while (0) |
|
#define __FP_FRAC_SRS_1(X,N,sz) \ |
(X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \ |
? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0))) |
|
#define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f) |
#define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f) |
#define _FP_FRAC_DEC_1(X,Y) (X##_f -= Y##_f) |
#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ(z, X##_f) |
|
/* Predicates */ |
#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE)X##_f < 0) |
#define _FP_FRAC_ZEROP_1(X) (X##_f == 0) |
#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs) |
#define _FP_FRAC_CLEAR_OVERP_1(fs,X) (X##_f &= ~_FP_OVERFLOW_##fs) |
#define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f) |
#define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f) |
#define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f) |
|
#define _FP_ZEROFRAC_1 0 |
#define _FP_MINFRAC_1 1 |
#define _FP_MAXFRAC_1 (~(_FP_WS_TYPE)0) |
|
/* |
* Unpack the raw bits of a native fp value. Do not classify or |
* normalize the data. |
*/ |
|
#define _FP_UNPACK_RAW_1(fs, X, val) \ |
do { \ |
union _FP_UNION_##fs _flo; _flo.flt = (val); \ |
\ |
X##_f = _flo.bits.frac; \ |
X##_e = _flo.bits.exp; \ |
X##_s = _flo.bits.sign; \ |
} while (0) |
|
#define _FP_UNPACK_RAW_1_P(fs, X, val) \ |
do { \ |
union _FP_UNION_##fs *_flo = \ |
(union _FP_UNION_##fs *)(val); \ |
\ |
X##_f = _flo->bits.frac; \ |
X##_e = _flo->bits.exp; \ |
X##_s = _flo->bits.sign; \ |
} while (0) |
|
/* |
* Repack the raw bits of a native fp value. |
*/ |
|
#define _FP_PACK_RAW_1(fs, val, X) \ |
do { \ |
union _FP_UNION_##fs _flo; \ |
\ |
_flo.bits.frac = X##_f; \ |
_flo.bits.exp = X##_e; \ |
_flo.bits.sign = X##_s; \ |
\ |
(val) = _flo.flt; \ |
} while (0) |
|
#define _FP_PACK_RAW_1_P(fs, val, X) \ |
do { \ |
union _FP_UNION_##fs *_flo = \ |
(union _FP_UNION_##fs *)(val); \ |
\ |
_flo->bits.frac = X##_f; \ |
_flo->bits.exp = X##_e; \ |
_flo->bits.sign = X##_s; \ |
} while (0) |
|
|
/* |
* Multiplication algorithms: |
*/ |
|
/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the |
multiplication immediately. */ |
|
#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y) \ |
do { \ |
R##_f = X##_f * Y##_f; \ |
/* Normalize since we know where the msb of the multiplicands \ |
were (bit B), we know that the msb of the of the product is \ |
at either 2B or 2B-1. */ \ |
_FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits); \ |
} while (0) |
|
/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ |
|
#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit) \ |
do { \ |
_FP_W_TYPE _Z_f0, _Z_f1; \ |
doit(_Z_f1, _Z_f0, X##_f, Y##_f); \ |
/* Normalize since we know where the msb of the multiplicands \ |
were (bit B), we know that the msb of the of the product is \ |
at either 2B or 2B-1. */ \ |
_FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits); \ |
R##_f = _Z_f0; \ |
} while (0) |
|
/* Finally, a simple widening multiply algorithm. What fun! */ |
|
#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \ |
do { \ |
_FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1; \ |
\ |
/* split the words in half */ \ |
_xh = X##_f >> (_FP_W_TYPE_SIZE/2); \ |
_xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ |
_yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \ |
_yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ |
\ |
/* multiply the pieces */ \ |
_z_f0 = _xl * _yl; \ |
_a_f0 = _xh * _yl; \ |
_a_f1 = _xl * _yh; \ |
_z_f1 = _xh * _yh; \ |
\ |
/* reassemble into two full words */ \ |
if ((_a_f0 += _a_f1) < _a_f1) \ |
_z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \ |
_a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \ |
_a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \ |
_FP_FRAC_ADD_2(_z, _z, _a); \ |
\ |
/* normalize */ \ |
_FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits); \ |
R##_f = _z_f0; \ |
} while (0) |
|
|
/* |
* Division algorithms: |
*/ |
|
/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the |
division immediately. Give this macro either _FP_DIV_HELP_imm for |
C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you |
choose will depend on what the compiler does with divrem4. */ |
|
#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \ |
do { \ |
_FP_W_TYPE _q, _r; \ |
X##_f <<= (X##_f < Y##_f \ |
? R##_e--, _FP_WFRACBITS_##fs \ |
: _FP_WFRACBITS_##fs - 1); \ |
doit(_q, _r, X##_f, Y##_f); \ |
R##_f = _q | (_r != 0); \ |
} while (0) |
|
/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd |
that may be useful in this situation. This first is for a primitive |
that requires normalization, the second for one that does not. Look |
for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */ |
|
#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \ |
do { \ |
_FP_W_TYPE _nh, _nl, _q, _r, _y; \ |
\ |
/* Normalize Y -- i.e. make the most significant bit set. */ \ |
_y = Y##_f << _FP_WFRACXBITS_##fs; \ |
\ |
/* Shift X op correspondingly high, that is, up one full word. */ \ |
if (X##_f < Y##_f) \ |
{ \ |
R##_e--; \ |
_nl = 0; \ |
_nh = X##_f; \ |
} \ |
else \ |
{ \ |
_nl = X##_f << (_FP_W_TYPE_SIZE - 1); \ |
_nh = X##_f >> 1; \ |
} \ |
\ |
udiv_qrnnd(_q, _r, _nh, _nl, _y); \ |
R##_f = _q | (_r != 0); \ |
} while (0) |
|
#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \ |
do { \ |
_FP_W_TYPE _nh, _nl, _q, _r; \ |
if (X##_f < Y##_f) \ |
{ \ |
R##_e--; \ |
_nl = X##_f << _FP_WFRACBITS_##fs; \ |
_nh = X##_f >> _FP_WFRACXBITS_##fs; \ |
} \ |
else \ |
{ \ |
_nl = X##_f << (_FP_WFRACBITS_##fs - 1); \ |
_nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \ |
} \ |
udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \ |
R##_f = _q | (_r != 0); \ |
} while (0) |
|
|
/* |
* Square root algorithms: |
* We have just one right now, maybe Newton approximation |
* should be added for those machines where division is fast. |
*/ |
|
#define _FP_SQRT_MEAT_1(R, S, T, X, q) \ |
do { \ |
while (q != _FP_WORK_ROUND) \ |
{ \ |
T##_f = S##_f + q; \ |
if (T##_f <= X##_f) \ |
{ \ |
S##_f = T##_f + q; \ |
X##_f -= T##_f; \ |
R##_f += q; \ |
} \ |
_FP_FRAC_SLL_1(X, 1); \ |
q >>= 1; \ |
} \ |
if (X##_f) \ |
{ \ |
if (S##_f < X##_f) \ |
R##_f |= _FP_WORK_ROUND; \ |
R##_f |= _FP_WORK_STICKY; \ |
} \ |
} while (0) |
|
/* |
* Assembly/disassembly for converting to/from integral types. |
* No shifting or overflow handled here. |
*/ |
|
#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f) |
#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r) |
|
|
/* |
* Convert FP values between word sizes |
*/ |
|
#define _FP_FRAC_COPY_1_1(D, S) (D##_f = S##_f) |
/extendsftf2.c
0,0 → 1,54
/* Software floating-point emulation. |
Return a converted to IEEE quad |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
#include "quad.h" |
|
TFtype __extendsftf2(SFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); |
FP_DECL_Q(R); |
TFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_RAW_S(A, a); |
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q |
FP_EXTEND(Q,S,4,1,R,A); |
#else |
FP_EXTEND(Q,S,2,1,R,A); |
#endif |
FP_PACK_RAW_Q(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/floatunsitf.c
0,0 → 1,47
/* Software floating-point emulation. |
Convert a 32bit unsigned integer to IEEE quad |
Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
TFtype |
__floatunsitf(USItype i) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); |
TFtype a; |
|
FP_FROM_INT_Q(A, i, SI_BITS, USItype); |
FP_PACK_RAW_Q(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/divsf3.c
0,0 → 1,49
/* Software floating-point emulation. |
Return a / b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
SFtype __divsf3(SFtype a, SFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); |
SFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_S(A, a); |
FP_UNPACK_S(B, b); |
FP_DIV_S(R, A, B); |
FP_PACK_S(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/floatundidf.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a 64bit unsigned integer to IEEE double |
Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
DFtype __floatundidf(UDItype i) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); |
DFtype a; |
|
FP_FROM_INT_D(A, i, DI_BITS, UDItype); |
FP_PACK_RAW_D(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/divtf3.c
0,0 → 1,49
/* Software floating-point emulation. |
Return a / b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
TFtype __divtf3(TFtype a, TFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); |
TFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_Q(A, a); |
FP_UNPACK_Q(B, b); |
FP_DIV_Q(R, A, B); |
FP_PACK_Q(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/trunctfsf2.c
0,0 → 1,54
/* Software floating-point emulation. |
Truncate IEEE quad into IEEE single |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
#include "quad.h" |
|
SFtype __trunctfsf2(TFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); |
FP_DECL_S(R); |
SFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_SEMIRAW_Q(A, a); |
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q |
FP_TRUNC(S,Q,1,4,R,A); |
#else |
FP_TRUNC(S,Q,1,2,R,A); |
#endif |
FP_PACK_SEMIRAW_S(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/negdf2.c
0,0 → 1,48
/* Software floating-point emulation. |
Return -a |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
DFtype __negdf2(DFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); FP_DECL_D(R); |
DFtype r; |
|
FP_UNPACK_D(A, a); |
FP_NEG_D(R, A); |
FP_PACK_D(r, R); |
FP_CLEAR_EXCEPTIONS; |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/extended.h
0,0 → 1,431
/* Software floating-point emulation. |
Definitions for IEEE Extended Precision. |
Copyright (C) 1999,2006,2007 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#if _FP_W_TYPE_SIZE < 32 |
#error "Here's a nickel, kid. Go buy yourself a real computer." |
#endif |
|
#if _FP_W_TYPE_SIZE < 64 |
#define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE) |
#else |
#define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE) |
#endif |
|
#define _FP_FRACBITS_E 64 |
#define _FP_FRACXBITS_E (_FP_FRACTBITS_E - _FP_FRACBITS_E) |
#define _FP_WFRACBITS_E (_FP_WORKBITS + _FP_FRACBITS_E) |
#define _FP_WFRACXBITS_E (_FP_FRACTBITS_E - _FP_WFRACBITS_E) |
#define _FP_EXPBITS_E 15 |
#define _FP_EXPBIAS_E 16383 |
#define _FP_EXPMAX_E 32767 |
|
#define _FP_QNANBIT_E \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE) |
#define _FP_QNANBIT_SH_E \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) |
#define _FP_IMPLBIT_E \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE) |
#define _FP_IMPLBIT_SH_E \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) |
#define _FP_OVERFLOW_E \ |
((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE)) |
|
typedef float XFtype __attribute__((mode(XF))); |
|
#if _FP_W_TYPE_SIZE < 64 |
|
union _FP_UNION_E |
{ |
XFtype flt; |
struct |
{ |
#if __BYTE_ORDER == __BIG_ENDIAN |
unsigned long pad1 : _FP_W_TYPE_SIZE; |
unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); |
unsigned long sign : 1; |
unsigned long exp : _FP_EXPBITS_E; |
unsigned long frac1 : _FP_W_TYPE_SIZE; |
unsigned long frac0 : _FP_W_TYPE_SIZE; |
#else |
unsigned long frac0 : _FP_W_TYPE_SIZE; |
unsigned long frac1 : _FP_W_TYPE_SIZE; |
unsigned exp : _FP_EXPBITS_E; |
unsigned sign : 1; |
#endif /* not bigendian */ |
} bits __attribute__((packed)); |
}; |
|
|
#define FP_DECL_E(X) _FP_DECL(4,X) |
|
#define FP_UNPACK_RAW_E(X, val) \ |
do { \ |
union _FP_UNION_E _flo; _flo.flt = (val); \ |
\ |
X##_f[2] = 0; X##_f[3] = 0; \ |
X##_f[0] = _flo.bits.frac0; \ |
X##_f[1] = _flo.bits.frac1; \ |
X##_e = _flo.bits.exp; \ |
X##_s = _flo.bits.sign; \ |
} while (0) |
|
#define FP_UNPACK_RAW_EP(X, val) \ |
do { \ |
union _FP_UNION_E *_flo = \ |
(union _FP_UNION_E *)(val); \ |
\ |
X##_f[2] = 0; X##_f[3] = 0; \ |
X##_f[0] = _flo->bits.frac0; \ |
X##_f[1] = _flo->bits.frac1; \ |
X##_e = _flo->bits.exp; \ |
X##_s = _flo->bits.sign; \ |
} while (0) |
|
#define FP_PACK_RAW_E(val, X) \ |
do { \ |
union _FP_UNION_E _flo; \ |
\ |
if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ |
else X##_f[1] &= ~(_FP_IMPLBIT_E); \ |
_flo.bits.frac0 = X##_f[0]; \ |
_flo.bits.frac1 = X##_f[1]; \ |
_flo.bits.exp = X##_e; \ |
_flo.bits.sign = X##_s; \ |
\ |
(val) = _flo.flt; \ |
} while (0) |
|
#define FP_PACK_RAW_EP(val, X) \ |
do { \ |
if (!FP_INHIBIT_RESULTS) \ |
{ \ |
union _FP_UNION_E *_flo = \ |
(union _FP_UNION_E *)(val); \ |
\ |
if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ |
else X##_f[1] &= ~(_FP_IMPLBIT_E); \ |
_flo->bits.frac0 = X##_f[0]; \ |
_flo->bits.frac1 = X##_f[1]; \ |
_flo->bits.exp = X##_e; \ |
_flo->bits.sign = X##_s; \ |
} \ |
} while (0) |
|
#define FP_UNPACK_E(X,val) \ |
do { \ |
FP_UNPACK_RAW_E(X,val); \ |
_FP_UNPACK_CANONICAL(E,4,X); \ |
} while (0) |
|
#define FP_UNPACK_EP(X,val) \ |
do { \ |
FP_UNPACK_RAW_EP(X,val); \ |
_FP_UNPACK_CANONICAL(E,4,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_E(X,val) \ |
do { \ |
FP_UNPACK_RAW_E(X,val); \ |
_FP_UNPACK_SEMIRAW(E,4,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_EP(X,val) \ |
do { \ |
FP_UNPACK_RAW_EP(X,val); \ |
_FP_UNPACK_SEMIRAW(E,4,X); \ |
} while (0) |
|
#define FP_PACK_E(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(E,4,X); \ |
FP_PACK_RAW_E(val,X); \ |
} while (0) |
|
#define FP_PACK_EP(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(E,4,X); \ |
FP_PACK_RAW_EP(val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_E(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(E,4,X); \ |
FP_PACK_RAW_E(val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_EP(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(E,4,X); \ |
FP_PACK_RAW_EP(val,X); \ |
} while (0) |
|
#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X) |
#define FP_NEG_E(R,X) _FP_NEG(E,4,R,X) |
#define FP_ADD_E(R,X,Y) _FP_ADD(E,4,R,X,Y) |
#define FP_SUB_E(R,X,Y) _FP_SUB(E,4,R,X,Y) |
#define FP_MUL_E(R,X,Y) _FP_MUL(E,4,R,X,Y) |
#define FP_DIV_E(R,X,Y) _FP_DIV(E,4,R,X,Y) |
#define FP_SQRT_E(R,X) _FP_SQRT(E,4,R,X) |
|
/* |
* Square root algorithms: |
* We have just one right now, maybe Newton approximation |
* should be added for those machines where division is fast. |
* This has special _E version because standard _4 square |
* root would not work (it has to start normally with the |
* second word and not the first), but as we have to do it |
* anyway, we optimize it by doing most of the calculations |
* in two UWtype registers instead of four. |
*/ |
|
#define _FP_SQRT_MEAT_E(R, S, T, X, q) \ |
do { \ |
q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ |
_FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \ |
while (q) \ |
{ \ |
T##_f[1] = S##_f[1] + q; \ |
if (T##_f[1] <= X##_f[1]) \ |
{ \ |
S##_f[1] = T##_f[1] + q; \ |
X##_f[1] -= T##_f[1]; \ |
R##_f[1] += q; \ |
} \ |
_FP_FRAC_SLL_2(X, 1); \ |
q >>= 1; \ |
} \ |
q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ |
while (q) \ |
{ \ |
T##_f[0] = S##_f[0] + q; \ |
T##_f[1] = S##_f[1]; \ |
if (T##_f[1] < X##_f[1] || \ |
(T##_f[1] == X##_f[1] && \ |
T##_f[0] <= X##_f[0])) \ |
{ \ |
S##_f[0] = T##_f[0] + q; \ |
S##_f[1] += (T##_f[0] > S##_f[0]); \ |
_FP_FRAC_DEC_2(X, T); \ |
R##_f[0] += q; \ |
} \ |
_FP_FRAC_SLL_2(X, 1); \ |
q >>= 1; \ |
} \ |
_FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \ |
if (X##_f[0] | X##_f[1]) \ |
{ \ |
if (S##_f[1] < X##_f[1] || \ |
(S##_f[1] == X##_f[1] && \ |
S##_f[0] < X##_f[0])) \ |
R##_f[0] |= _FP_WORK_ROUND; \ |
R##_f[0] |= _FP_WORK_STICKY; \ |
} \ |
} while (0) |
|
#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un) |
#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y) |
#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,4,r,X,Y) |
|
#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg) |
#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt) |
|
#define _FP_FRAC_HIGH_E(X) (X##_f[2]) |
#define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1]) |
|
#else /* not _FP_W_TYPE_SIZE < 64 */ |
union _FP_UNION_E |
{ |
XFtype flt; |
struct { |
#if __BYTE_ORDER == __BIG_ENDIAN |
_FP_W_TYPE pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); |
unsigned sign : 1; |
unsigned exp : _FP_EXPBITS_E; |
_FP_W_TYPE frac : _FP_W_TYPE_SIZE; |
#else |
_FP_W_TYPE frac : _FP_W_TYPE_SIZE; |
unsigned exp : _FP_EXPBITS_E; |
unsigned sign : 1; |
#endif |
} bits; |
}; |
|
#define FP_DECL_E(X) _FP_DECL(2,X) |
|
#define FP_UNPACK_RAW_E(X, val) \ |
do { \ |
union _FP_UNION_E _flo; _flo.flt = (val); \ |
\ |
X##_f0 = _flo.bits.frac; \ |
X##_f1 = 0; \ |
X##_e = _flo.bits.exp; \ |
X##_s = _flo.bits.sign; \ |
} while (0) |
|
#define FP_UNPACK_RAW_EP(X, val) \ |
do { \ |
union _FP_UNION_E *_flo = \ |
(union _FP_UNION_E *)(val); \ |
\ |
X##_f0 = _flo->bits.frac; \ |
X##_f1 = 0; \ |
X##_e = _flo->bits.exp; \ |
X##_s = _flo->bits.sign; \ |
} while (0) |
|
#define FP_PACK_RAW_E(val, X) \ |
do { \ |
union _FP_UNION_E _flo; \ |
\ |
if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ |
else X##_f0 &= ~(_FP_IMPLBIT_E); \ |
_flo.bits.frac = X##_f0; \ |
_flo.bits.exp = X##_e; \ |
_flo.bits.sign = X##_s; \ |
\ |
(val) = _flo.flt; \ |
} while (0) |
|
#define FP_PACK_RAW_EP(fs, val, X) \ |
do { \ |
if (!FP_INHIBIT_RESULTS) \ |
{ \ |
union _FP_UNION_E *_flo = \ |
(union _FP_UNION_E *)(val); \ |
\ |
if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ |
else X##_f0 &= ~(_FP_IMPLBIT_E); \ |
_flo->bits.frac = X##_f0; \ |
_flo->bits.exp = X##_e; \ |
_flo->bits.sign = X##_s; \ |
} \ |
} while (0) |
|
|
#define FP_UNPACK_E(X,val) \ |
do { \ |
FP_UNPACK_RAW_E(X,val); \ |
_FP_UNPACK_CANONICAL(E,2,X); \ |
} while (0) |
|
#define FP_UNPACK_EP(X,val) \ |
do { \ |
FP_UNPACK_RAW_EP(X,val); \ |
_FP_UNPACK_CANONICAL(E,2,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_E(X,val) \ |
do { \ |
FP_UNPACK_RAW_E(X,val); \ |
_FP_UNPACK_SEMIRAW(E,2,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_EP(X,val) \ |
do { \ |
FP_UNPACK_RAW_EP(X,val); \ |
_FP_UNPACK_SEMIRAW(E,2,X); \ |
} while (0) |
|
#define FP_PACK_E(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(E,2,X); \ |
FP_PACK_RAW_E(val,X); \ |
} while (0) |
|
#define FP_PACK_EP(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(E,2,X); \ |
FP_PACK_RAW_EP(val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_E(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(E,2,X); \ |
FP_PACK_RAW_E(val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_EP(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(E,2,X); \ |
FP_PACK_RAW_EP(val,X); \ |
} while (0) |
|
#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X) |
#define FP_NEG_E(R,X) _FP_NEG(E,2,R,X) |
#define FP_ADD_E(R,X,Y) _FP_ADD(E,2,R,X,Y) |
#define FP_SUB_E(R,X,Y) _FP_SUB(E,2,R,X,Y) |
#define FP_MUL_E(R,X,Y) _FP_MUL(E,2,R,X,Y) |
#define FP_DIV_E(R,X,Y) _FP_DIV(E,2,R,X,Y) |
#define FP_SQRT_E(R,X) _FP_SQRT(E,2,R,X) |
|
/* |
* Square root algorithms: |
* We have just one right now, maybe Newton approximation |
* should be added for those machines where division is fast. |
* We optimize it by doing most of the calculations |
* in one UWtype registers instead of two, although we don't |
* have to. |
*/ |
#define _FP_SQRT_MEAT_E(R, S, T, X, q) \ |
do { \ |
q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ |
_FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \ |
while (q) \ |
{ \ |
T##_f0 = S##_f0 + q; \ |
if (T##_f0 <= X##_f0) \ |
{ \ |
S##_f0 = T##_f0 + q; \ |
X##_f0 -= T##_f0; \ |
R##_f0 += q; \ |
} \ |
_FP_FRAC_SLL_1(X, 1); \ |
q >>= 1; \ |
} \ |
_FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \ |
if (X##_f0) \ |
{ \ |
if (S##_f0 < X##_f0) \ |
R##_f0 |= _FP_WORK_ROUND; \ |
R##_f0 |= _FP_WORK_STICKY; \ |
} \ |
} while (0) |
|
#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un) |
#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y) |
#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,2,r,X,Y) |
|
#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg) |
#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt) |
|
#define _FP_FRAC_HIGH_E(X) (X##_f1) |
#define _FP_FRAC_HIGH_RAW_E(X) (X##_f0) |
|
#endif /* not _FP_W_TYPE_SIZE < 64 */ |
/floatunditf.c
0,0 → 1,47
/* Software floating-point emulation. |
Convert a 64bit unsigned integer to IEEE quad |
Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
TFtype |
__floatunditf(UDItype i) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); |
TFtype a; |
|
FP_FROM_INT_Q(A, i, DI_BITS, UDItype); |
FP_PACK_RAW_Q(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/fixunssfdi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 64bit unsigned integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
UDItype __fixunssfdi(SFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); |
UDItype r; |
|
FP_UNPACK_RAW_S(A, a); |
FP_TO_INT_S(r, A, DI_BITS, 0); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/negsf2.c
0,0 → 1,48
/* Software floating-point emulation. |
Return -a |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
SFtype __negsf2(SFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); FP_DECL_S(R); |
SFtype r; |
|
FP_UNPACK_S(A, a); |
FP_NEG_S(R, A); |
FP_PACK_S(r, R); |
FP_CLEAR_EXCEPTIONS; |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/negtf2.c
0,0 → 1,48
/* Software floating-point emulation. |
Return -a |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
TFtype __negtf2(TFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); FP_DECL_Q(R); |
TFtype r; |
|
FP_UNPACK_Q(A, a); |
FP_NEG_Q(R, A); |
FP_PACK_Q(r, R); |
FP_CLEAR_EXCEPTIONS; |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/subdf3.c
0,0 → 1,49
/* Software floating-point emulation. |
Return a - b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
DFtype __subdf3(DFtype a, DFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); |
DFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_SEMIRAW_D(A, a); |
FP_UNPACK_SEMIRAW_D(B, b); |
FP_SUB_D(R, A, B); |
FP_PACK_SEMIRAW_D(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/single.h
0,0 → 1,151
/* Software floating-point emulation. |
Definitions for IEEE Single Precision. |
Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com), |
Jakub Jelinek (jj@ultra.linux.cz), |
David S. Miller (davem@redhat.com) and |
Peter Maydell (pmaydell@chiark.greenend.org.uk). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#if _FP_W_TYPE_SIZE < 32 |
#error "Here's a nickel kid. Go buy yourself a real computer." |
#endif |
|
#define _FP_FRACTBITS_S _FP_W_TYPE_SIZE |
|
#define _FP_FRACBITS_S 24 |
#define _FP_FRACXBITS_S (_FP_FRACTBITS_S - _FP_FRACBITS_S) |
#define _FP_WFRACBITS_S (_FP_WORKBITS + _FP_FRACBITS_S) |
#define _FP_WFRACXBITS_S (_FP_FRACTBITS_S - _FP_WFRACBITS_S) |
#define _FP_EXPBITS_S 8 |
#define _FP_EXPBIAS_S 127 |
#define _FP_EXPMAX_S 255 |
#define _FP_QNANBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2)) |
#define _FP_QNANBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2+_FP_WORKBITS)) |
#define _FP_IMPLBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1)) |
#define _FP_IMPLBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1+_FP_WORKBITS)) |
#define _FP_OVERFLOW_S ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S)) |
|
/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be |
chosen by the target machine. */ |
|
typedef float SFtype __attribute__((mode(SF))); |
|
union _FP_UNION_S |
{ |
SFtype flt; |
struct { |
#if __BYTE_ORDER == __BIG_ENDIAN |
unsigned sign : 1; |
unsigned exp : _FP_EXPBITS_S; |
unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0); |
#else |
unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0); |
unsigned exp : _FP_EXPBITS_S; |
unsigned sign : 1; |
#endif |
} bits __attribute__((packed)); |
}; |
|
#define FP_DECL_S(X) _FP_DECL(1,X) |
#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val) |
#define FP_UNPACK_RAW_SP(X,val) _FP_UNPACK_RAW_1_P(S,X,val) |
#define FP_PACK_RAW_S(val,X) _FP_PACK_RAW_1(S,val,X) |
#define FP_PACK_RAW_SP(val,X) \ |
do { \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_1_P(S,val,X); \ |
} while (0) |
|
#define FP_UNPACK_S(X,val) \ |
do { \ |
_FP_UNPACK_RAW_1(S,X,val); \ |
_FP_UNPACK_CANONICAL(S,1,X); \ |
} while (0) |
|
#define FP_UNPACK_SP(X,val) \ |
do { \ |
_FP_UNPACK_RAW_1_P(S,X,val); \ |
_FP_UNPACK_CANONICAL(S,1,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_S(X,val) \ |
do { \ |
_FP_UNPACK_RAW_1(S,X,val); \ |
_FP_UNPACK_SEMIRAW(S,1,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_SP(X,val) \ |
do { \ |
_FP_UNPACK_RAW_1_P(S,X,val); \ |
_FP_UNPACK_SEMIRAW(S,1,X); \ |
} while (0) |
|
#define FP_PACK_S(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(S,1,X); \ |
_FP_PACK_RAW_1(S,val,X); \ |
} while (0) |
|
#define FP_PACK_SP(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(S,1,X); \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_1_P(S,val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_S(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(S,1,X); \ |
_FP_PACK_RAW_1(S,val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_SP(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(S,1,X); \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_1_P(S,val,X); \ |
} while (0) |
|
#define FP_ISSIGNAN_S(X) _FP_ISSIGNAN(S,1,X) |
#define FP_NEG_S(R,X) _FP_NEG(S,1,R,X) |
#define FP_ADD_S(R,X,Y) _FP_ADD(S,1,R,X,Y) |
#define FP_SUB_S(R,X,Y) _FP_SUB(S,1,R,X,Y) |
#define FP_MUL_S(R,X,Y) _FP_MUL(S,1,R,X,Y) |
#define FP_DIV_S(R,X,Y) _FP_DIV(S,1,R,X,Y) |
#define FP_SQRT_S(R,X) _FP_SQRT(S,1,R,X) |
#define _FP_SQRT_MEAT_S(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) |
|
#define FP_CMP_S(r,X,Y,un) _FP_CMP(S,1,r,X,Y,un) |
#define FP_CMP_EQ_S(r,X,Y) _FP_CMP_EQ(S,1,r,X,Y) |
#define FP_CMP_UNORD_S(r,X,Y) _FP_CMP_UNORD(S,1,r,X,Y) |
|
#define FP_TO_INT_S(r,X,rsz,rsg) _FP_TO_INT(S,1,r,X,rsz,rsg) |
#define FP_FROM_INT_S(X,r,rs,rt) _FP_FROM_INT(S,1,X,r,rs,rt) |
|
#define _FP_FRAC_HIGH_S(X) _FP_FRAC_HIGH_1(X) |
#define _FP_FRAC_HIGH_RAW_S(X) _FP_FRAC_HIGH_1(X) |
/gedf2.c
0,0 → 1,51
/* Software floating-point emulation. |
Return 0 iff a == b, 1 iff a > b, -2 iff a ? b, -1 iff a < b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
int __gedf2(DFtype a, DFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); FP_DECL_D(B); |
int r; |
|
FP_UNPACK_RAW_D(A, a); |
FP_UNPACK_RAW_D(B, b); |
FP_CMP_D(r, A, B, -2); |
if (r == -2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))) |
FP_SET_EXCEPTION(FP_EX_INVALID); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
|
strong_alias(__gedf2, __gtdf2); |
/muldf3.c
0,0 → 1,49
/* Software floating-point emulation. |
Return a * b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
DFtype __muldf3(DFtype a, DFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); |
DFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_D(A, a); |
FP_UNPACK_D(B, b); |
FP_MUL_D(R, A, B); |
FP_PACK_D(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/fixsfdi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 64bit signed integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
DItype __fixsfdi(SFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); |
UDItype r; |
|
FP_UNPACK_RAW_S(A, a); |
FP_TO_INT_S(r, A, DI_BITS, 1); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/floatunsisf.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a 32bit unsigned integer to IEEE single |
Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
SFtype __floatunsisf(USItype i) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); |
SFtype a; |
|
FP_FROM_INT_S(A, i, SI_BITS, USItype); |
FP_PACK_RAW_S(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/eqdf2.c
0,0 → 1,51
/* Software floating-point emulation. |
Return 0 iff a == b, 1 otherwise |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
int __eqdf2(DFtype a, DFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); FP_DECL_D(B); |
int r; |
|
FP_UNPACK_RAW_D(A, a); |
FP_UNPACK_RAW_D(B, b); |
FP_CMP_EQ_D(r, A, B); |
if (r && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))) |
FP_SET_EXCEPTION(FP_EX_INVALID); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
|
strong_alias(__eqdf2, __nedf2); |
/fixunsdfdi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 64bit unsigned integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
UDItype __fixunsdfdi(DFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); |
UDItype r; |
|
FP_UNPACK_RAW_D(A, a); |
FP_TO_INT_D(r, A, DI_BITS, 0); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/subsf3.c
0,0 → 1,49
/* Software floating-point emulation. |
Return a - b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
SFtype __subsf3(SFtype a, SFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); |
SFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_SEMIRAW_S(A, a); |
FP_UNPACK_SEMIRAW_S(B, b); |
FP_SUB_S(R, A, B); |
FP_PACK_SEMIRAW_S(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/gesf2.c
0,0 → 1,51
/* Software floating-point emulation. |
Return 0 iff a == b, 1 iff a > b, -2 iff a ? b, -1 iff a < b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
int __gesf2(SFtype a, SFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); FP_DECL_S(B); |
int r; |
|
FP_UNPACK_RAW_S(A, a); |
FP_UNPACK_RAW_S(B, b); |
FP_CMP_S(r, A, B, -2); |
if (r == -2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B))) |
FP_SET_EXCEPTION(FP_EX_INVALID); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
|
strong_alias(__gesf2, __gtsf2); |
/subtf3.c
0,0 → 1,49
/* Software floating-point emulation. |
Return a - b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
TFtype __subtf3(TFtype a, TFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); |
TFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_SEMIRAW_Q(A, a); |
FP_UNPACK_SEMIRAW_Q(B, b); |
FP_SUB_Q(R, A, B); |
FP_PACK_SEMIRAW_Q(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/getf2.c
0,0 → 1,51
/* Software floating-point emulation. |
Return 0 iff a == b, 1 iff a > b, -2 iff a ? b, -1 iff a < b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
int __getf2(TFtype a, TFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); FP_DECL_Q(B); |
int r; |
|
FP_UNPACK_RAW_Q(A, a); |
FP_UNPACK_RAW_Q(B, b); |
FP_CMP_Q(r, A, B, -2); |
if (r == -2 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) |
FP_SET_EXCEPTION(FP_EX_INVALID); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
|
strong_alias(__getf2, __gttf2); |
/mulsf3.c
0,0 → 1,49
/* Software floating-point emulation. |
Return a * b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
SFtype __mulsf3(SFtype a, SFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); |
SFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_S(A, a); |
FP_UNPACK_S(B, b); |
FP_MUL_S(R, A, B); |
FP_PACK_S(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/op-common.h
0,0 → 1,1359
/* Software floating-point emulation. Common operations. |
Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com), |
Jakub Jelinek (jj@ultra.linux.cz), |
David S. Miller (davem@redhat.com) and |
Peter Maydell (pmaydell@chiark.greenend.org.uk). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#define _FP_DECL(wc, X) \ |
_FP_I_TYPE X##_c __attribute__((unused)), X##_s, X##_e; \ |
_FP_FRAC_DECL_##wc(X) |
|
/* |
* Finish truely unpacking a native fp value by classifying the kind |
* of fp value and normalizing both the exponent and the fraction. |
*/ |
|
#define _FP_UNPACK_CANONICAL(fs, wc, X) \ |
do { \ |
switch (X##_e) \ |
{ \ |
default: \ |
_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ |
_FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ |
X##_e -= _FP_EXPBIAS_##fs; \ |
X##_c = FP_CLS_NORMAL; \ |
break; \ |
\ |
case 0: \ |
if (_FP_FRAC_ZEROP_##wc(X)) \ |
X##_c = FP_CLS_ZERO; \ |
else \ |
{ \ |
/* a denormalized number */ \ |
_FP_I_TYPE _shift; \ |
_FP_FRAC_CLZ_##wc(_shift, X); \ |
_shift -= _FP_FRACXBITS_##fs; \ |
_FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \ |
X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ |
X##_c = FP_CLS_NORMAL; \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
} \ |
break; \ |
\ |
case _FP_EXPMAX_##fs: \ |
if (_FP_FRAC_ZEROP_##wc(X)) \ |
X##_c = FP_CLS_INF; \ |
else \ |
{ \ |
X##_c = FP_CLS_NAN; \ |
/* Check for signaling NaN */ \ |
if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \ |
FP_SET_EXCEPTION(FP_EX_INVALID); \ |
} \ |
break; \ |
} \ |
} while (0) |
|
/* Finish unpacking an fp value in semi-raw mode: the mantissa is |
shifted by _FP_WORKBITS but the implicit MSB is not inserted and |
other classification is not done. */ |
#define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS) |
|
/* A semi-raw value has overflowed to infinity. Adjust the mantissa |
and exponent appropriately. */ |
#define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \ |
do { \ |
if (FP_ROUNDMODE == FP_RND_NEAREST \ |
|| (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \ |
|| (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \ |
{ \ |
X##_e = _FP_EXPMAX_##fs; \ |
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ |
} \ |
else \ |
{ \ |
X##_e = _FP_EXPMAX_##fs - 1; \ |
_FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ |
} \ |
FP_SET_EXCEPTION(FP_EX_INEXACT); \ |
FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ |
} while (0) |
|
/* Check for a semi-raw value being a signaling NaN and raise the |
invalid exception if so. */ |
#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \ |
do { \ |
if (X##_e == _FP_EXPMAX_##fs \ |
&& !_FP_FRAC_ZEROP_##wc(X) \ |
&& !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \ |
FP_SET_EXCEPTION(FP_EX_INVALID); \ |
} while (0) |
|
/* Choose a NaN result from an operation on two semi-raw NaN |
values. */ |
#define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \ |
do { \ |
/* _FP_CHOOSENAN expects raw values, so shift as required. */ \ |
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ |
_FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \ |
_FP_CHOOSENAN(fs, wc, R, X, Y, OP); \ |
_FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ |
} while (0) |
|
/* Test whether a biased exponent is normal (not zero or maximum). */ |
#define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1) |
|
/* Prepare to pack an fp value in semi-raw mode: the mantissa is |
rounded and shifted right, with the rounding possibly increasing |
the exponent (including changing a finite value to infinity). */ |
#define _FP_PACK_SEMIRAW(fs, wc, X) \ |
do { \ |
_FP_ROUND(wc, X); \ |
if (_FP_FRAC_HIGH_##fs(X) \ |
& (_FP_OVERFLOW_##fs >> 1)) \ |
{ \ |
_FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \ |
X##_e++; \ |
if (X##_e == _FP_EXPMAX_##fs) \ |
_FP_OVERFLOW_SEMIRAW(fs, wc, X); \ |
} \ |
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ |
if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X)) \ |
{ \ |
if (X##_e == 0) \ |
FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ |
else \ |
{ \ |
if (!_FP_KEEPNANFRACP) \ |
{ \ |
_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ |
X##_s = _FP_NANSIGN_##fs; \ |
} \ |
else \ |
_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ |
} \ |
} \ |
} while (0) |
|
/* |
* Before packing the bits back into the native fp result, take care |
* of such mundane things as rounding and overflow. Also, for some |
* kinds of fp values, the original parts may not have been fully |
* extracted -- but that is ok, we can regenerate them now. |
*/ |
|
#define _FP_PACK_CANONICAL(fs, wc, X) \ |
do { \ |
switch (X##_c) \ |
{ \ |
case FP_CLS_NORMAL: \ |
X##_e += _FP_EXPBIAS_##fs; \ |
if (X##_e > 0) \ |
{ \ |
_FP_ROUND(wc, X); \ |
if (_FP_FRAC_OVERP_##wc(fs, X)) \ |
{ \ |
_FP_FRAC_CLEAR_OVERP_##wc(fs, X); \ |
X##_e++; \ |
} \ |
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ |
if (X##_e >= _FP_EXPMAX_##fs) \ |
{ \ |
/* overflow */ \ |
switch (FP_ROUNDMODE) \ |
{ \ |
case FP_RND_NEAREST: \ |
X##_c = FP_CLS_INF; \ |
break; \ |
case FP_RND_PINF: \ |
if (!X##_s) X##_c = FP_CLS_INF; \ |
break; \ |
case FP_RND_MINF: \ |
if (X##_s) X##_c = FP_CLS_INF; \ |
break; \ |
} \ |
if (X##_c == FP_CLS_INF) \ |
{ \ |
/* Overflow to infinity */ \ |
X##_e = _FP_EXPMAX_##fs; \ |
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ |
} \ |
else \ |
{ \ |
/* Overflow to maximum normal */ \ |
X##_e = _FP_EXPMAX_##fs - 1; \ |
_FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ |
} \ |
FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ |
FP_SET_EXCEPTION(FP_EX_INEXACT); \ |
} \ |
} \ |
else \ |
{ \ |
/* we've got a denormalized number */ \ |
X##_e = -X##_e + 1; \ |
if (X##_e <= _FP_WFRACBITS_##fs) \ |
{ \ |
_FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \ |
_FP_ROUND(wc, X); \ |
if (_FP_FRAC_HIGH_##fs(X) \ |
& (_FP_OVERFLOW_##fs >> 1)) \ |
{ \ |
X##_e = 1; \ |
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ |
} \ |
else \ |
{ \ |
X##_e = 0; \ |
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ |
FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ |
} \ |
} \ |
else \ |
{ \ |
/* underflow to zero */ \ |
X##_e = 0; \ |
if (!_FP_FRAC_ZEROP_##wc(X)) \ |
{ \ |
_FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ |
_FP_ROUND(wc, X); \ |
_FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \ |
} \ |
FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ |
} \ |
} \ |
break; \ |
\ |
case FP_CLS_ZERO: \ |
X##_e = 0; \ |
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ |
break; \ |
\ |
case FP_CLS_INF: \ |
X##_e = _FP_EXPMAX_##fs; \ |
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ |
break; \ |
\ |
case FP_CLS_NAN: \ |
X##_e = _FP_EXPMAX_##fs; \ |
if (!_FP_KEEPNANFRACP) \ |
{ \ |
_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ |
X##_s = _FP_NANSIGN_##fs; \ |
} \ |
else \ |
_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ |
break; \ |
} \ |
} while (0) |
|
/* This one accepts raw argument and not cooked, returns |
* 1 if X is a signaling NaN. |
*/ |
#define _FP_ISSIGNAN(fs, wc, X) \ |
({ \ |
int __ret = 0; \ |
if (X##_e == _FP_EXPMAX_##fs) \ |
{ \ |
if (!_FP_FRAC_ZEROP_##wc(X) \ |
&& !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \ |
__ret = 1; \ |
} \ |
__ret; \ |
}) |
|
|
|
|
|
/* Addition on semi-raw values. */ |
#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \ |
do { \ |
if (X##_s == Y##_s) \ |
{ \ |
/* Addition. */ \ |
R##_s = X##_s; \ |
int ediff = X##_e - Y##_e; \ |
if (ediff > 0) \ |
{ \ |
R##_e = X##_e; \ |
if (Y##_e == 0) \ |
{ \ |
/* Y is zero or denormalized. */ \ |
if (_FP_FRAC_ZEROP_##wc(Y)) \ |
{ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ |
_FP_FRAC_COPY_##wc(R, X); \ |
goto add_done; \ |
} \ |
else \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
ediff--; \ |
if (ediff == 0) \ |
{ \ |
_FP_FRAC_ADD_##wc(R, X, Y); \ |
goto add3; \ |
} \ |
if (X##_e == _FP_EXPMAX_##fs) \ |
{ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ |
_FP_FRAC_COPY_##wc(R, X); \ |
goto add_done; \ |
} \ |
goto add1; \ |
} \ |
} \ |
else if (X##_e == _FP_EXPMAX_##fs) \ |
{ \ |
/* X is NaN or Inf, Y is normal. */ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ |
_FP_FRAC_COPY_##wc(R, X); \ |
goto add_done; \ |
} \ |
\ |
/* Insert implicit MSB of Y. */ \ |
_FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ |
\ |
add1: \ |
/* Shift the mantissa of Y to the right EDIFF steps; \ |
remember to account later for the implicit MSB of X. */ \ |
if (ediff <= _FP_WFRACBITS_##fs) \ |
_FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ |
else if (!_FP_FRAC_ZEROP_##wc(Y)) \ |
_FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ |
_FP_FRAC_ADD_##wc(R, X, Y); \ |
} \ |
else if (ediff < 0) \ |
{ \ |
ediff = -ediff; \ |
R##_e = Y##_e; \ |
if (X##_e == 0) \ |
{ \ |
/* X is zero or denormalized. */ \ |
if (_FP_FRAC_ZEROP_##wc(X)) \ |
{ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
goto add_done; \ |
} \ |
else \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
ediff--; \ |
if (ediff == 0) \ |
{ \ |
_FP_FRAC_ADD_##wc(R, Y, X); \ |
goto add3; \ |
} \ |
if (Y##_e == _FP_EXPMAX_##fs) \ |
{ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
goto add_done; \ |
} \ |
goto add2; \ |
} \ |
} \ |
else if (Y##_e == _FP_EXPMAX_##fs) \ |
{ \ |
/* Y is NaN or Inf, X is normal. */ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
goto add_done; \ |
} \ |
\ |
/* Insert implicit MSB of X. */ \ |
_FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ |
\ |
add2: \ |
/* Shift the mantissa of X to the right EDIFF steps; \ |
remember to account later for the implicit MSB of Y. */ \ |
if (ediff <= _FP_WFRACBITS_##fs) \ |
_FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ |
else if (!_FP_FRAC_ZEROP_##wc(X)) \ |
_FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ |
_FP_FRAC_ADD_##wc(R, Y, X); \ |
} \ |
else \ |
{ \ |
/* ediff == 0. */ \ |
if (!_FP_EXP_NORMAL(fs, wc, X)) \ |
{ \ |
if (X##_e == 0) \ |
{ \ |
/* X and Y are zero or denormalized. */ \ |
R##_e = 0; \ |
if (_FP_FRAC_ZEROP_##wc(X)) \ |
{ \ |
if (!_FP_FRAC_ZEROP_##wc(Y)) \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
goto add_done; \ |
} \ |
else if (_FP_FRAC_ZEROP_##wc(Y)) \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
_FP_FRAC_COPY_##wc(R, X); \ |
goto add_done; \ |
} \ |
else \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
_FP_FRAC_ADD_##wc(R, X, Y); \ |
if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ |
{ \ |
/* Normalized result. */ \ |
_FP_FRAC_HIGH_##fs(R) \ |
&= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ |
R##_e = 1; \ |
} \ |
goto add_done; \ |
} \ |
} \ |
else \ |
{ \ |
/* X and Y are NaN or Inf. */ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ |
R##_e = _FP_EXPMAX_##fs; \ |
if (_FP_FRAC_ZEROP_##wc(X)) \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
else if (_FP_FRAC_ZEROP_##wc(Y)) \ |
_FP_FRAC_COPY_##wc(R, X); \ |
else \ |
_FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ |
goto add_done; \ |
} \ |
} \ |
/* The exponents of X and Y, both normal, are equal. The \ |
implicit MSBs will always add to increase the \ |
exponent. */ \ |
_FP_FRAC_ADD_##wc(R, X, Y); \ |
R##_e = X##_e + 1; \ |
_FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ |
if (R##_e == _FP_EXPMAX_##fs) \ |
/* Overflow to infinity (depending on rounding mode). */ \ |
_FP_OVERFLOW_SEMIRAW(fs, wc, R); \ |
goto add_done; \ |
} \ |
add3: \ |
if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ |
{ \ |
/* Overflow. */ \ |
_FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ |
R##_e++; \ |
_FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ |
if (R##_e == _FP_EXPMAX_##fs) \ |
/* Overflow to infinity (depending on rounding mode). */ \ |
_FP_OVERFLOW_SEMIRAW(fs, wc, R); \ |
} \ |
add_done: ; \ |
} \ |
else \ |
{ \ |
/* Subtraction. */ \ |
int ediff = X##_e - Y##_e; \ |
if (ediff > 0) \ |
{ \ |
R##_e = X##_e; \ |
R##_s = X##_s; \ |
if (Y##_e == 0) \ |
{ \ |
/* Y is zero or denormalized. */ \ |
if (_FP_FRAC_ZEROP_##wc(Y)) \ |
{ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ |
_FP_FRAC_COPY_##wc(R, X); \ |
goto sub_done; \ |
} \ |
else \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
ediff--; \ |
if (ediff == 0) \ |
{ \ |
_FP_FRAC_SUB_##wc(R, X, Y); \ |
goto sub3; \ |
} \ |
if (X##_e == _FP_EXPMAX_##fs) \ |
{ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ |
_FP_FRAC_COPY_##wc(R, X); \ |
goto sub_done; \ |
} \ |
goto sub1; \ |
} \ |
} \ |
else if (X##_e == _FP_EXPMAX_##fs) \ |
{ \ |
/* X is NaN or Inf, Y is normal. */ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ |
_FP_FRAC_COPY_##wc(R, X); \ |
goto sub_done; \ |
} \ |
\ |
/* Insert implicit MSB of Y. */ \ |
_FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ |
\ |
sub1: \ |
/* Shift the mantissa of Y to the right EDIFF steps; \ |
remember to account later for the implicit MSB of X. */ \ |
if (ediff <= _FP_WFRACBITS_##fs) \ |
_FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ |
else if (!_FP_FRAC_ZEROP_##wc(Y)) \ |
_FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ |
_FP_FRAC_SUB_##wc(R, X, Y); \ |
} \ |
else if (ediff < 0) \ |
{ \ |
ediff = -ediff; \ |
R##_e = Y##_e; \ |
R##_s = Y##_s; \ |
if (X##_e == 0) \ |
{ \ |
/* X is zero or denormalized. */ \ |
if (_FP_FRAC_ZEROP_##wc(X)) \ |
{ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
goto sub_done; \ |
} \ |
else \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
ediff--; \ |
if (ediff == 0) \ |
{ \ |
_FP_FRAC_SUB_##wc(R, Y, X); \ |
goto sub3; \ |
} \ |
if (Y##_e == _FP_EXPMAX_##fs) \ |
{ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
goto sub_done; \ |
} \ |
goto sub2; \ |
} \ |
} \ |
else if (Y##_e == _FP_EXPMAX_##fs) \ |
{ \ |
/* Y is NaN or Inf, X is normal. */ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
goto sub_done; \ |
} \ |
\ |
/* Insert implicit MSB of X. */ \ |
_FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ |
\ |
sub2: \ |
/* Shift the mantissa of X to the right EDIFF steps; \ |
remember to account later for the implicit MSB of Y. */ \ |
if (ediff <= _FP_WFRACBITS_##fs) \ |
_FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ |
else if (!_FP_FRAC_ZEROP_##wc(X)) \ |
_FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ |
_FP_FRAC_SUB_##wc(R, Y, X); \ |
} \ |
else \ |
{ \ |
/* ediff == 0. */ \ |
if (!_FP_EXP_NORMAL(fs, wc, X)) \ |
{ \ |
if (X##_e == 0) \ |
{ \ |
/* X and Y are zero or denormalized. */ \ |
R##_e = 0; \ |
if (_FP_FRAC_ZEROP_##wc(X)) \ |
{ \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
if (_FP_FRAC_ZEROP_##wc(Y)) \ |
R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ |
else \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
R##_s = Y##_s; \ |
} \ |
goto sub_done; \ |
} \ |
else if (_FP_FRAC_ZEROP_##wc(Y)) \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
_FP_FRAC_COPY_##wc(R, X); \ |
R##_s = X##_s; \ |
goto sub_done; \ |
} \ |
else \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
_FP_FRAC_SUB_##wc(R, X, Y); \ |
R##_s = X##_s; \ |
if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ |
{ \ |
/* |X| < |Y|, negate result. */ \ |
_FP_FRAC_SUB_##wc(R, Y, X); \ |
R##_s = Y##_s; \ |
} \ |
else if (_FP_FRAC_ZEROP_##wc(R)) \ |
R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ |
goto sub_done; \ |
} \ |
} \ |
else \ |
{ \ |
/* X and Y are NaN or Inf, of opposite signs. */ \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ |
_FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ |
R##_e = _FP_EXPMAX_##fs; \ |
if (_FP_FRAC_ZEROP_##wc(X)) \ |
{ \ |
if (_FP_FRAC_ZEROP_##wc(Y)) \ |
{ \ |
/* Inf - Inf. */ \ |
R##_s = _FP_NANSIGN_##fs; \ |
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ |
_FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ |
FP_SET_EXCEPTION(FP_EX_INVALID); \ |
} \ |
else \ |
{ \ |
/* Inf - NaN. */ \ |
R##_s = Y##_s; \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
} \ |
} \ |
else \ |
{ \ |
if (_FP_FRAC_ZEROP_##wc(Y)) \ |
{ \ |
/* NaN - Inf. */ \ |
R##_s = X##_s; \ |
_FP_FRAC_COPY_##wc(R, X); \ |
} \ |
else \ |
{ \ |
/* NaN - NaN. */ \ |
_FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ |
} \ |
} \ |
goto sub_done; \ |
} \ |
} \ |
/* The exponents of X and Y, both normal, are equal. The \ |
implicit MSBs cancel. */ \ |
R##_e = X##_e; \ |
_FP_FRAC_SUB_##wc(R, X, Y); \ |
R##_s = X##_s; \ |
if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ |
{ \ |
/* |X| < |Y|, negate result. */ \ |
_FP_FRAC_SUB_##wc(R, Y, X); \ |
R##_s = Y##_s; \ |
} \ |
else if (_FP_FRAC_ZEROP_##wc(R)) \ |
{ \ |
R##_e = 0; \ |
R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ |
goto sub_done; \ |
} \ |
goto norm; \ |
} \ |
sub3: \ |
if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ |
{ \ |
int diff; \ |
/* Carry into most significant bit of larger one of X and Y, \ |
canceling it; renormalize. */ \ |
_FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \ |
norm: \ |
_FP_FRAC_CLZ_##wc(diff, R); \ |
diff -= _FP_WFRACXBITS_##fs; \ |
_FP_FRAC_SLL_##wc(R, diff); \ |
if (R##_e <= diff) \ |
{ \ |
/* R is denormalized. */ \ |
diff = diff - R##_e + 1; \ |
_FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \ |
R##_e = 0; \ |
} \ |
else \ |
{ \ |
R##_e -= diff; \ |
_FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ |
} \ |
} \ |
sub_done: ; \ |
} \ |
} while (0) |
|
#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+') |
#define _FP_SUB(fs, wc, R, X, Y) \ |
do { \ |
if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \ |
_FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \ |
} while (0) |
|
|
/* |
* Main negation routine. FIXME -- when we care about setting exception |
* bits reliably, this will not do. We should examine all of the fp classes. |
*/ |
|
#define _FP_NEG(fs, wc, R, X) \ |
do { \ |
_FP_FRAC_COPY_##wc(R, X); \ |
R##_c = X##_c; \ |
R##_e = X##_e; \ |
R##_s = 1 ^ X##_s; \ |
} while (0) |
|
|
/* |
* Main multiplication routine. The input values should be cooked. |
*/ |
|
#define _FP_MUL(fs, wc, R, X, Y) \ |
do { \ |
R##_s = X##_s ^ Y##_s; \ |
switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ |
{ \ |
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ |
R##_c = FP_CLS_NORMAL; \ |
R##_e = X##_e + Y##_e + 1; \ |
\ |
_FP_MUL_MEAT_##fs(R,X,Y); \ |
\ |
if (_FP_FRAC_OVERP_##wc(fs, R)) \ |
_FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ |
else \ |
R##_e--; \ |
break; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ |
_FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \ |
break; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ |
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ |
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ |
R##_s = X##_s; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ |
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ |
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ |
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ |
_FP_FRAC_COPY_##wc(R, X); \ |
R##_c = X##_c; \ |
break; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ |
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ |
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ |
R##_s = Y##_s; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ |
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
R##_c = Y##_c; \ |
break; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ |
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ |
R##_s = _FP_NANSIGN_##fs; \ |
R##_c = FP_CLS_NAN; \ |
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ |
FP_SET_EXCEPTION(FP_EX_INVALID); \ |
break; \ |
\ |
default: \ |
abort(); \ |
} \ |
} while (0) |
|
|
/* |
* Main division routine. The input values should be cooked. |
*/ |
|
#define _FP_DIV(fs, wc, R, X, Y) \ |
do { \ |
R##_s = X##_s ^ Y##_s; \ |
switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ |
{ \ |
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ |
R##_c = FP_CLS_NORMAL; \ |
R##_e = X##_e - Y##_e; \ |
\ |
_FP_DIV_MEAT_##fs(R,X,Y); \ |
break; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ |
_FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \ |
break; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ |
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ |
case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ |
R##_s = X##_s; \ |
_FP_FRAC_COPY_##wc(R, X); \ |
R##_c = X##_c; \ |
break; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ |
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ |
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ |
R##_s = Y##_s; \ |
_FP_FRAC_COPY_##wc(R, Y); \ |
R##_c = Y##_c; \ |
break; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ |
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ |
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ |
R##_c = FP_CLS_ZERO; \ |
break; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ |
FP_SET_EXCEPTION(FP_EX_DIVZERO); \ |
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ |
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ |
R##_c = FP_CLS_INF; \ |
break; \ |
\ |
case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ |
case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ |
R##_s = _FP_NANSIGN_##fs; \ |
R##_c = FP_CLS_NAN; \ |
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ |
FP_SET_EXCEPTION(FP_EX_INVALID); \ |
break; \ |
\ |
default: \ |
abort(); \ |
} \ |
} while (0) |
|
|
/* |
* Main differential comparison routine. The inputs should be raw not |
* cooked. The return is -1,0,1 for normal values, 2 otherwise. |
*/ |
|
#define _FP_CMP(fs, wc, ret, X, Y, un) \ |
do { \ |
/* NANs are unordered */ \ |
if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ |
|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ |
{ \ |
ret = un; \ |
} \ |
else \ |
{ \ |
int __is_zero_x; \ |
int __is_zero_y; \ |
\ |
__is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \ |
__is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \ |
\ |
if (__is_zero_x && __is_zero_y) \ |
ret = 0; \ |
else if (__is_zero_x) \ |
ret = Y##_s ? 1 : -1; \ |
else if (__is_zero_y) \ |
ret = X##_s ? -1 : 1; \ |
else if (X##_s != Y##_s) \ |
ret = X##_s ? -1 : 1; \ |
else if (X##_e > Y##_e) \ |
ret = X##_s ? -1 : 1; \ |
else if (X##_e < Y##_e) \ |
ret = X##_s ? 1 : -1; \ |
else if (_FP_FRAC_GT_##wc(X, Y)) \ |
ret = X##_s ? -1 : 1; \ |
else if (_FP_FRAC_GT_##wc(Y, X)) \ |
ret = X##_s ? 1 : -1; \ |
else \ |
ret = 0; \ |
} \ |
} while (0) |
|
|
/* Simplification for strict equality. */ |
|
#define _FP_CMP_EQ(fs, wc, ret, X, Y) \ |
do { \ |
/* NANs are unordered */ \ |
if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ |
|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ |
{ \ |
ret = 1; \ |
} \ |
else \ |
{ \ |
ret = !(X##_e == Y##_e \ |
&& _FP_FRAC_EQ_##wc(X, Y) \ |
&& (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \ |
} \ |
} while (0) |
|
/* Version to test unordered. */ |
|
#define _FP_CMP_UNORD(fs, wc, ret, X, Y) \ |
do { \ |
ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ |
|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \ |
} while (0) |
|
/* |
* Main square root routine. The input value should be cooked. |
*/ |
|
#define _FP_SQRT(fs, wc, R, X) \ |
do { \ |
_FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \ |
_FP_W_TYPE q; \ |
switch (X##_c) \ |
{ \ |
case FP_CLS_NAN: \ |
_FP_FRAC_COPY_##wc(R, X); \ |
R##_s = X##_s; \ |
R##_c = FP_CLS_NAN; \ |
break; \ |
case FP_CLS_INF: \ |
if (X##_s) \ |
{ \ |
R##_s = _FP_NANSIGN_##fs; \ |
R##_c = FP_CLS_NAN; /* NAN */ \ |
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ |
FP_SET_EXCEPTION(FP_EX_INVALID); \ |
} \ |
else \ |
{ \ |
R##_s = 0; \ |
R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ |
} \ |
break; \ |
case FP_CLS_ZERO: \ |
R##_s = X##_s; \ |
R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ |
break; \ |
case FP_CLS_NORMAL: \ |
R##_s = 0; \ |
if (X##_s) \ |
{ \ |
R##_c = FP_CLS_NAN; /* sNAN */ \ |
R##_s = _FP_NANSIGN_##fs; \ |
_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ |
FP_SET_EXCEPTION(FP_EX_INVALID); \ |
break; \ |
} \ |
R##_c = FP_CLS_NORMAL; \ |
if (X##_e & 1) \ |
_FP_FRAC_SLL_##wc(X, 1); \ |
R##_e = X##_e >> 1; \ |
_FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \ |
_FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ |
q = _FP_OVERFLOW_##fs >> 1; \ |
_FP_SQRT_MEAT_##wc(R, S, T, X, q); \ |
} \ |
} while (0) |
|
/* |
* Convert from FP to integer. Input is raw. |
*/ |
|
/* RSIGNED can have following values: |
* 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus |
* the result is either 0 or (2^rsize)-1 depending on the sign in such |
* case. |
* 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, |
* NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 |
* depending on the sign in such case. |
* -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is |
* set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 |
* depending on the sign in such case. |
*/ |
#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ |
do { \ |
if (X##_e < _FP_EXPBIAS_##fs) \ |
{ \ |
r = 0; \ |
if (X##_e == 0) \ |
{ \ |
if (!_FP_FRAC_ZEROP_##wc(X)) \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_INEXACT); \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
} \ |
} \ |
else \ |
FP_SET_EXCEPTION(FP_EX_INEXACT); \ |
} \ |
else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \ |
|| (!rsigned && X##_s)) \ |
{ \ |
/* Overflow or converting to the most negative integer. */ \ |
if (rsigned) \ |
{ \ |
r = 1; \ |
r <<= rsize - 1; \ |
r -= 1 - X##_s; \ |
} else { \ |
r = 0; \ |
if (X##_s) \ |
r = ~r; \ |
} \ |
\ |
if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \ |
{ \ |
/* Possibly converting to most negative integer; check the \ |
mantissa. */ \ |
int inexact = 0; \ |
(void)((_FP_FRACBITS_##fs > rsize) \ |
? ({ _FP_FRAC_SRST_##wc(X, inexact, \ |
_FP_FRACBITS_##fs - rsize, \ |
_FP_FRACBITS_##fs); 0; }) \ |
: 0); \ |
if (!_FP_FRAC_ZEROP_##wc(X)) \ |
FP_SET_EXCEPTION(FP_EX_INVALID); \ |
else if (inexact) \ |
FP_SET_EXCEPTION(FP_EX_INEXACT); \ |
} \ |
else \ |
FP_SET_EXCEPTION(FP_EX_INVALID); \ |
} \ |
else \ |
{ \ |
_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ |
if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ |
{ \ |
_FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ |
r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ |
} \ |
else \ |
{ \ |
int inexact; \ |
_FP_FRAC_SRST_##wc(X, inexact, \ |
(_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ |
- X##_e), \ |
_FP_FRACBITS_##fs); \ |
if (inexact) \ |
FP_SET_EXCEPTION(FP_EX_INEXACT); \ |
_FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ |
} \ |
if (rsigned && X##_s) \ |
r = -r; \ |
} \ |
} while (0) |
|
/* Convert integer to fp. Output is raw. RTYPE is unsigned even if |
input is signed. */ |
#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ |
do { \ |
if (r) \ |
{ \ |
rtype ur_; \ |
\ |
if ((X##_s = (r < 0))) \ |
r = -(rtype)r; \ |
\ |
ur_ = (rtype) r; \ |
(void)((rsize <= _FP_W_TYPE_SIZE) \ |
? ({ \ |
int lz_; \ |
__FP_CLZ(lz_, (_FP_W_TYPE)ur_); \ |
X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \ |
}) \ |
: ((rsize <= 2 * _FP_W_TYPE_SIZE) \ |
? ({ \ |
int lz_; \ |
__FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \ |
(_FP_W_TYPE)ur_); \ |
X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ |
- lz_); \ |
}) \ |
: (abort(), 0))); \ |
\ |
if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ |
&& X##_e >= _FP_EXPMAX_##fs) \ |
{ \ |
/* Exponent too big; overflow to infinity. (May also \ |
happen after rounding below.) */ \ |
_FP_OVERFLOW_SEMIRAW(fs, wc, X); \ |
goto pack_semiraw; \ |
} \ |
\ |
if (rsize <= _FP_FRACBITS_##fs \ |
|| X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \ |
{ \ |
/* Exactly representable; shift left. */ \ |
_FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ |
_FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ |
+ _FP_FRACBITS_##fs - 1 - X##_e)); \ |
} \ |
else \ |
{ \ |
/* More bits in integer than in floating type; need to \ |
round. */ \ |
if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \ |
ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \ |
- _FP_WFRACBITS_##fs + 1)) \ |
| ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \ |
- _FP_WFRACBITS_##fs + 1))) \ |
!= 0)); \ |
_FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ |
if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \ |
_FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ |
+ _FP_WFRACBITS_##fs - 1 - X##_e)); \ |
_FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ |
pack_semiraw: \ |
_FP_PACK_SEMIRAW(fs, wc, X); \ |
} \ |
} \ |
else \ |
{ \ |
X##_s = 0; \ |
X##_e = 0; \ |
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ |
} \ |
} while (0) |
|
|
/* Extend from a narrower floating-point format to a wider one. Input |
and output are raw. */ |
#define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \ |
do { \ |
if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ |
|| (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ |
< _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ |
|| (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ |
&& _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ |
abort(); \ |
D##_s = S##_s; \ |
_FP_FRAC_COPY_##dwc##_##swc(D, S); \ |
if (_FP_EXP_NORMAL(sfs, swc, S)) \ |
{ \ |
D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ |
_FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \ |
} \ |
else \ |
{ \ |
if (S##_e == 0) \ |
{ \ |
if (_FP_FRAC_ZEROP_##swc(S)) \ |
D##_e = 0; \ |
else if (_FP_EXPBIAS_##dfs \ |
< _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
_FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ |
- _FP_FRACBITS_##sfs)); \ |
D##_e = 0; \ |
} \ |
else \ |
{ \ |
int _lz; \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
_FP_FRAC_CLZ_##swc(_lz, S); \ |
_FP_FRAC_SLL_##dwc(D, \ |
_lz + _FP_FRACBITS_##dfs \ |
- _FP_FRACTBITS_##sfs); \ |
D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \ |
+ _FP_FRACXBITS_##sfs - _lz); \ |
} \ |
} \ |
else \ |
{ \ |
D##_e = _FP_EXPMAX_##dfs; \ |
if (!_FP_FRAC_ZEROP_##swc(S)) \ |
{ \ |
if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \ |
FP_SET_EXCEPTION(FP_EX_INVALID); \ |
_FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ |
- _FP_FRACBITS_##sfs)); \ |
} \ |
} \ |
} \ |
} while (0) |
|
/* Truncate from a wider floating-point format to a narrower one. |
Input and output are semi-raw. */ |
#define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \ |
do { \ |
if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ |
|| (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ |
&& _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ |
abort(); \ |
D##_s = S##_s; \ |
if (_FP_EXP_NORMAL(sfs, swc, S)) \ |
{ \ |
D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ |
if (D##_e >= _FP_EXPMAX_##dfs) \ |
_FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \ |
else \ |
{ \ |
if (D##_e <= 0) \ |
{ \ |
if (D##_e < 1 - _FP_FRACBITS_##dfs) \ |
{ \ |
_FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \ |
_FP_FRAC_LOW_##swc(S) |= 1; \ |
} \ |
else \ |
{ \ |
_FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \ |
_FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ |
- _FP_WFRACBITS_##dfs + 1 - D##_e), \ |
_FP_WFRACBITS_##sfs); \ |
} \ |
D##_e = 0; \ |
} \ |
else \ |
_FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ |
- _FP_WFRACBITS_##dfs), \ |
_FP_WFRACBITS_##sfs); \ |
_FP_FRAC_COPY_##dwc##_##swc(D, S); \ |
} \ |
} \ |
else \ |
{ \ |
if (S##_e == 0) \ |
{ \ |
D##_e = 0; \ |
if (_FP_FRAC_ZEROP_##swc(S)) \ |
_FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ |
else \ |
{ \ |
FP_SET_EXCEPTION(FP_EX_DENORM); \ |
if (_FP_EXPBIAS_##sfs \ |
< _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ |
{ \ |
_FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ |
- _FP_WFRACBITS_##dfs), \ |
_FP_WFRACBITS_##sfs); \ |
_FP_FRAC_COPY_##dwc##_##swc(D, S); \ |
} \ |
else \ |
{ \ |
_FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ |
_FP_FRAC_LOW_##dwc(D) |= 1; \ |
} \ |
} \ |
} \ |
else \ |
{ \ |
D##_e = _FP_EXPMAX_##dfs; \ |
if (_FP_FRAC_ZEROP_##swc(S)) \ |
_FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ |
else \ |
{ \ |
_FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \ |
_FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \ |
- _FP_WFRACBITS_##dfs)); \ |
_FP_FRAC_COPY_##dwc##_##swc(D, S); \ |
/* Semi-raw NaN must have all workbits cleared. */ \ |
_FP_FRAC_LOW_##dwc(D) \ |
&= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \ |
_FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \ |
} \ |
} \ |
} \ |
} while (0) |
|
/* |
* Helper primitives. |
*/ |
|
/* Count leading zeros in a word. */ |
|
#ifndef __FP_CLZ |
/* GCC 3.4 and later provide the builtins for us. */ |
#define __FP_CLZ(r, x) \ |
do { \ |
if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ |
r = __builtin_clz (x); \ |
else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ |
r = __builtin_clzl (x); \ |
else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \ |
r = __builtin_clzll (x); \ |
else \ |
abort (); \ |
} while (0) |
#endif /* ndef __FP_CLZ */ |
|
#define _FP_DIV_HELP_imm(q, r, n, d) \ |
do { \ |
q = n / d, r = n % d; \ |
} while (0) |
|
|
/* A restoring bit-by-bit division primitive. */ |
|
#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \ |
do { \ |
int count = _FP_WFRACBITS_##fs; \ |
_FP_FRAC_DECL_##wc (u); \ |
_FP_FRAC_DECL_##wc (v); \ |
_FP_FRAC_COPY_##wc (u, X); \ |
_FP_FRAC_COPY_##wc (v, Y); \ |
_FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ |
/* Normalize U and V. */ \ |
_FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \ |
_FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \ |
/* First round. Since the operands are normalized, either the \ |
first or second bit will be set in the fraction. Produce a \ |
normalized result by checking which and adjusting the loop \ |
count and exponent accordingly. */ \ |
if (_FP_FRAC_GE_1 (u, v)) \ |
{ \ |
_FP_FRAC_SUB_##wc (u, u, v); \ |
_FP_FRAC_LOW_##wc (R) |= 1; \ |
count--; \ |
} \ |
else \ |
R##_e--; \ |
/* Subsequent rounds. */ \ |
do { \ |
int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \ |
_FP_FRAC_SLL_##wc (u, 1); \ |
_FP_FRAC_SLL_##wc (R, 1); \ |
if (msb || _FP_FRAC_GE_1 (u, v)) \ |
{ \ |
_FP_FRAC_SUB_##wc (u, u, v); \ |
_FP_FRAC_LOW_##wc (R) |= 1; \ |
} \ |
} while (--count > 0); \ |
/* If there's anything left in U, the result is inexact. */ \ |
_FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \ |
} while (0) |
|
#define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y) |
#define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y) |
#define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y) |
/multf3.c
0,0 → 1,49
/* Software floating-point emulation. |
Return a * b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
TFtype __multf3(TFtype a, TFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); |
TFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_Q(A, a); |
FP_UNPACK_Q(B, b); |
FP_MUL_Q(R, A, B); |
FP_PACK_Q(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/floatsidf.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a 32bit signed integer to IEEE double |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
DFtype __floatsidf(SItype i) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); |
DFtype a; |
|
FP_FROM_INT_D(A, i, SI_BITS, USItype); |
FP_PACK_RAW_D(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/extenddftf2.c
0,0 → 1,54
/* Software floating-point emulation. |
Return a converted to IEEE quad |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
#include "quad.h" |
|
TFtype __extenddftf2(DFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); |
FP_DECL_Q(R); |
TFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_RAW_D(A, a); |
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q |
FP_EXTEND(Q,D,4,2,R,A); |
#else |
FP_EXTEND(Q,D,2,1,R,A); |
#endif |
FP_PACK_RAW_Q(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/fixdfdi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 64bit signed integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
DItype __fixdfdi(DFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); |
UDItype r; |
|
FP_UNPACK_RAW_D(A, a); |
FP_TO_INT_D(r, A, DI_BITS, 1); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/floatundisf.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a 64bit unsigned integer to IEEE single |
Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
SFtype __floatundisf(UDItype i) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); |
SFtype a; |
|
FP_FROM_INT_S(A, i, DI_BITS, UDItype); |
FP_PACK_RAW_S(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/eqsf2.c
0,0 → 1,51
/* Software floating-point emulation. |
Return 0 iff a == b, 1 otherwise |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
int __eqsf2(SFtype a, SFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); FP_DECL_S(B); |
int r; |
|
FP_UNPACK_RAW_S(A, a); |
FP_UNPACK_RAW_S(B, b); |
FP_CMP_EQ_S(r, A, B); |
if (r && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B))) |
FP_SET_EXCEPTION(FP_EX_INVALID); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
|
strong_alias(__eqsf2, __nesf2); |
/eqtf2.c
0,0 → 1,51
/* Software floating-point emulation. |
Return 0 iff a == b, 1 otherwise |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
int __eqtf2(TFtype a, TFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); FP_DECL_Q(B); |
int r; |
|
FP_UNPACK_RAW_Q(A, a); |
FP_UNPACK_RAW_Q(B, b); |
FP_CMP_EQ_Q(r, A, B); |
if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) |
FP_SET_EXCEPTION(FP_EX_INVALID); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
|
strong_alias(__eqtf2, __netf2); |
/t-softfp
0,0 → 1,107
# Copyright (C) 2006, 2007 Free Software Foundation, Inc. |
|
# This file is part of GCC. |
|
# GCC is free software; you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation; either version 3, or (at your option) |
# any later version. |
|
# GCC 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 General Public License for more details. |
|
# You should have received a copy of the GNU General Public License |
# along with GCC; see the file COPYING3. If not see |
# <http://www.gnu.org/licenses/>. |
|
# Targets using soft-fp should define the following variables: |
# |
# softfp_float_modes: a list of soft-float floating-point modes, |
# e.g. sf df |
# softfp_int_modes: a list of integer modes for which to define conversions, |
# e.g. si di |
# softfp_extensions: a list of extensions between floating-point modes, |
# e.g. sfdf |
# softfp_truncations: a list of truncations between floating-point modes, |
# e.g. dfsf |
# softfp_machine_header: the target sfp-machine.h file (relative to config/), |
# e.g. rs6000/sfp-machine.h |
# |
# Extensions and truncations should include those where only one mode |
# is a soft-float mode; for example, sftf where sf is hard-float and |
# tf is soft-float. |
# |
# If the libgcc2.c functions should not be replaced, also define: |
# |
# softfp_exclude_libgcc2 := y |
# |
# Avoiding replacing the libgcc2.c functions is a temporary measure |
# for targets with both hard-float and soft-float multilibs, since |
# these variables apply for all multilibs. With toplevel libgcc, |
# soft-fp can be used conditionally on the multilib instead. |
# |
# If the code should not be compiled at all for some multilibs, define: |
# |
# softfp_wrap_start: text to put at the start of wrapper source files, |
# output with echo |
# e.g. '#ifndef __powerpc64__' |
# softfp_wrap_end: text to put at the end of wrapper source files, |
# e.g. '#endif' |
# |
# This is another temporary measure. |
|
softfp_float_funcs = add$(m)3 div$(m)3 eq$(m)2 ge$(m)2 le$(m)2 mul$(m)3 \ |
neg$(m)2 sub$(m)3 unord$(m)2 |
softfp_floatint_funcs = fix$(m)$(i) fixuns$(m)$(i) \ |
float$(i)$(m) floatun$(i)$(m) |
|
softfp_func_list := \ |
$(foreach m,$(softfp_float_modes), \ |
$(softfp_float_funcs) \ |
$(foreach i,$(softfp_int_modes), \ |
$(softfp_floatint_funcs))) \ |
$(foreach e,$(softfp_extensions),extend$(e)2) \ |
$(foreach t,$(softfp_truncations),trunc$(t)2) |
|
ifeq ($(softfp_exclude_libgcc2),y) |
# This list is taken from mklibgcc.in and doesn't presently allow for |
# 64-bit targets where si should become di and di should become ti. |
softfp_func_list := $(filter-out floatdidf floatdisf fixunsdfsi fixunssfsi \ |
fixunsdfdi fixdfdi fixunssfdi fixsfdi fixxfdi fixunsxfdi \ |
floatdixf fixunsxfsi fixtfdi fixunstfdi floatditf \ |
floatundidf floatundisf floatundixf floatunditf,$(softfp_func_list)) |
endif |
|
ifeq ($(softfp_wrap_start),) |
softfp_file_list := \ |
$(addsuffix .c,$(addprefix $(srcdir)/config/soft-fp/,$(softfp_func_list))) |
else |
softfp_file_list := $(addsuffix .c,$(softfp_func_list)) |
|
$(softfp_file_list): |
echo $(softfp_wrap_start) > $@ |
echo '#include "config/soft-fp/$@"' >> $@ |
echo $(softfp_wrap_end) >> $@ |
endif |
|
LIB2FUNCS_EXTRA += $(softfp_file_list) |
|
ifneq ($(softfp_exclude_libgcc2),y) |
# Functions in libgcc2.c are excluded for each soft-float mode (a |
# target may have both soft-float and hard-float modes), for the fixed |
# list of integer modes (si and di) for which libgcc2.c defines any |
# such functions. Depending on the target, the si and di symbols may |
# in fact define di and ti functions. |
|
LIB2FUNCS_EXCLUDE += \ |
$(addprefix _,$(foreach m,$(softfp_float_modes), \ |
$(foreach i,si di, \ |
$(softfp_floatint_funcs)))) |
endif |
|
SFP_MACHINE := sfp-machine.h |
|
$(SFP_MACHINE): $(srcdir)/config/$(softfp_machine_header) |
cp $(srcdir)/config/$(softfp_machine_header) $(SFP_MACHINE) |
/op-2.h
0,0 → 1,617
/* Software floating-point emulation. |
Basic two-word fraction declaration and manipulation. |
Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com), |
Jakub Jelinek (jj@ultra.linux.cz), |
David S. Miller (davem@redhat.com) and |
Peter Maydell (pmaydell@chiark.greenend.org.uk). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1 |
#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1) |
#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I) |
#define _FP_FRAC_HIGH_2(X) (X##_f1) |
#define _FP_FRAC_LOW_2(X) (X##_f0) |
#define _FP_FRAC_WORD_2(X,w) (X##_f##w) |
|
#define _FP_FRAC_SLL_2(X,N) \ |
(void)(((N) < _FP_W_TYPE_SIZE) \ |
? ({ \ |
if (__builtin_constant_p(N) && (N) == 1) \ |
{ \ |
X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \ |
X##_f0 += X##_f0; \ |
} \ |
else \ |
{ \ |
X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \ |
X##_f0 <<= (N); \ |
} \ |
0; \ |
}) \ |
: ({ \ |
X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \ |
X##_f0 = 0; \ |
})) |
|
|
#define _FP_FRAC_SRL_2(X,N) \ |
(void)(((N) < _FP_W_TYPE_SIZE) \ |
? ({ \ |
X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \ |
X##_f1 >>= (N); \ |
}) \ |
: ({ \ |
X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \ |
X##_f1 = 0; \ |
})) |
|
/* Right shift with sticky-lsb. */ |
#define _FP_FRAC_SRST_2(X,S, N,sz) \ |
(void)(((N) < _FP_W_TYPE_SIZE) \ |
? ({ \ |
S = (__builtin_constant_p(N) && (N) == 1 \ |
? X##_f0 & 1 \ |
: (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0); \ |
X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N)); \ |
X##_f1 >>= (N); \ |
}) \ |
: ({ \ |
S = ((((N) == _FP_W_TYPE_SIZE \ |
? 0 \ |
: (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ |
| X##_f0) != 0); \ |
X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE)); \ |
X##_f1 = 0; \ |
})) |
|
#define _FP_FRAC_SRS_2(X,N,sz) \ |
(void)(((N) < _FP_W_TYPE_SIZE) \ |
? ({ \ |
X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \ |
(__builtin_constant_p(N) && (N) == 1 \ |
? X##_f0 & 1 \ |
: (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \ |
X##_f1 >>= (N); \ |
}) \ |
: ({ \ |
X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \ |
((((N) == _FP_W_TYPE_SIZE \ |
? 0 \ |
: (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ |
| X##_f0) != 0)); \ |
X##_f1 = 0; \ |
})) |
|
#define _FP_FRAC_ADDI_2(X,I) \ |
__FP_FRAC_ADDI_2(X##_f1, X##_f0, I) |
|
#define _FP_FRAC_ADD_2(R,X,Y) \ |
__FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) |
|
#define _FP_FRAC_SUB_2(R,X,Y) \ |
__FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) |
|
#define _FP_FRAC_DEC_2(X,Y) \ |
__FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0) |
|
#define _FP_FRAC_CLZ_2(R,X) \ |
do { \ |
if (X##_f1) \ |
__FP_CLZ(R,X##_f1); \ |
else \ |
{ \ |
__FP_CLZ(R,X##_f0); \ |
R += _FP_W_TYPE_SIZE; \ |
} \ |
} while(0) |
|
/* Predicates */ |
#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0) |
#define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0) |
#define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs) |
#define _FP_FRAC_CLEAR_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs) |
#define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0) |
#define _FP_FRAC_GT_2(X, Y) \ |
(X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0)) |
#define _FP_FRAC_GE_2(X, Y) \ |
(X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0)) |
|
#define _FP_ZEROFRAC_2 0, 0 |
#define _FP_MINFRAC_2 0, 1 |
#define _FP_MAXFRAC_2 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0) |
|
/* |
* Internals |
*/ |
|
#define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1) |
|
#define __FP_CLZ_2(R, xh, xl) \ |
do { \ |
if (xh) \ |
__FP_CLZ(R,xh); \ |
else \ |
{ \ |
__FP_CLZ(R,xl); \ |
R += _FP_W_TYPE_SIZE; \ |
} \ |
} while(0) |
|
#if 0 |
|
#ifndef __FP_FRAC_ADDI_2 |
#define __FP_FRAC_ADDI_2(xh, xl, i) \ |
(xh += ((xl += i) < i)) |
#endif |
#ifndef __FP_FRAC_ADD_2 |
#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \ |
(rh = xh + yh + ((rl = xl + yl) < xl)) |
#endif |
#ifndef __FP_FRAC_SUB_2 |
#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \ |
(rh = xh - yh - ((rl = xl - yl) > xl)) |
#endif |
#ifndef __FP_FRAC_DEC_2 |
#define __FP_FRAC_DEC_2(xh, xl, yh, yl) \ |
do { \ |
UWtype _t = xl; \ |
xh -= yh + ((xl -= yl) > _t); \ |
} while (0) |
#endif |
|
#else |
|
#undef __FP_FRAC_ADDI_2 |
#define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i) |
#undef __FP_FRAC_ADD_2 |
#define __FP_FRAC_ADD_2 add_ssaaaa |
#undef __FP_FRAC_SUB_2 |
#define __FP_FRAC_SUB_2 sub_ddmmss |
#undef __FP_FRAC_DEC_2 |
#define __FP_FRAC_DEC_2(xh, xl, yh, yl) sub_ddmmss(xh, xl, xh, xl, yh, yl) |
|
#endif |
|
/* |
* Unpack the raw bits of a native fp value. Do not classify or |
* normalize the data. |
*/ |
|
#define _FP_UNPACK_RAW_2(fs, X, val) \ |
do { \ |
union _FP_UNION_##fs _flo; _flo.flt = (val); \ |
\ |
X##_f0 = _flo.bits.frac0; \ |
X##_f1 = _flo.bits.frac1; \ |
X##_e = _flo.bits.exp; \ |
X##_s = _flo.bits.sign; \ |
} while (0) |
|
#define _FP_UNPACK_RAW_2_P(fs, X, val) \ |
do { \ |
union _FP_UNION_##fs *_flo = \ |
(union _FP_UNION_##fs *)(val); \ |
\ |
X##_f0 = _flo->bits.frac0; \ |
X##_f1 = _flo->bits.frac1; \ |
X##_e = _flo->bits.exp; \ |
X##_s = _flo->bits.sign; \ |
} while (0) |
|
|
/* |
* Repack the raw bits of a native fp value. |
*/ |
|
#define _FP_PACK_RAW_2(fs, val, X) \ |
do { \ |
union _FP_UNION_##fs _flo; \ |
\ |
_flo.bits.frac0 = X##_f0; \ |
_flo.bits.frac1 = X##_f1; \ |
_flo.bits.exp = X##_e; \ |
_flo.bits.sign = X##_s; \ |
\ |
(val) = _flo.flt; \ |
} while (0) |
|
#define _FP_PACK_RAW_2_P(fs, val, X) \ |
do { \ |
union _FP_UNION_##fs *_flo = \ |
(union _FP_UNION_##fs *)(val); \ |
\ |
_flo->bits.frac0 = X##_f0; \ |
_flo->bits.frac1 = X##_f1; \ |
_flo->bits.exp = X##_e; \ |
_flo->bits.sign = X##_s; \ |
} while (0) |
|
|
/* |
* Multiplication algorithms: |
*/ |
|
/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ |
|
#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \ |
do { \ |
_FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ |
\ |
doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ |
doit(_b_f1, _b_f0, X##_f0, Y##_f1); \ |
doit(_c_f1, _c_f0, X##_f1, Y##_f0); \ |
doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \ |
\ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ |
_FP_FRAC_WORD_4(_z,1), 0, _b_f1, _b_f0, \ |
_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ |
_FP_FRAC_WORD_4(_z,1)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ |
_FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0, \ |
_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ |
_FP_FRAC_WORD_4(_z,1)); \ |
\ |
/* Normalize since we know where the msb of the multiplicands \ |
were (bit B), we know that the msb of the of the product is \ |
at either 2B or 2B-1. */ \ |
_FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ |
R##_f0 = _FP_FRAC_WORD_4(_z,0); \ |
R##_f1 = _FP_FRAC_WORD_4(_z,1); \ |
} while (0) |
|
/* Given a 1W * 1W => 2W primitive, do the extended multiplication. |
Do only 3 multiplications instead of four. This one is for machines |
where multiplication is much more expensive than subtraction. */ |
|
#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \ |
do { \ |
_FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ |
_FP_W_TYPE _d; \ |
int _c1, _c2; \ |
\ |
_b_f0 = X##_f0 + X##_f1; \ |
_c1 = _b_f0 < X##_f0; \ |
_b_f1 = Y##_f0 + Y##_f1; \ |
_c2 = _b_f1 < Y##_f0; \ |
doit(_d, _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ |
doit(_FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1), _b_f0, _b_f1); \ |
doit(_c_f1, _c_f0, X##_f1, Y##_f1); \ |
\ |
_b_f0 &= -_c2; \ |
_b_f1 &= -_c1; \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ |
_FP_FRAC_WORD_4(_z,1), (_c1 & _c2), 0, _d, \ |
0, _FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1)); \ |
__FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ |
_b_f0); \ |
__FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ |
_b_f1); \ |
__FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ |
_FP_FRAC_WORD_4(_z,1), \ |
0, _d, _FP_FRAC_WORD_4(_z,0)); \ |
__FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ |
_FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0); \ |
__FP_FRAC_ADD_2(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), \ |
_c_f1, _c_f0, \ |
_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2)); \ |
\ |
/* Normalize since we know where the msb of the multiplicands \ |
were (bit B), we know that the msb of the of the product is \ |
at either 2B or 2B-1. */ \ |
_FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ |
R##_f0 = _FP_FRAC_WORD_4(_z,0); \ |
R##_f1 = _FP_FRAC_WORD_4(_z,1); \ |
} while (0) |
|
#define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y) \ |
do { \ |
_FP_FRAC_DECL_4(_z); \ |
_FP_W_TYPE _x[2], _y[2]; \ |
_x[0] = X##_f0; _x[1] = X##_f1; \ |
_y[0] = Y##_f0; _y[1] = Y##_f1; \ |
\ |
mpn_mul_n(_z_f, _x, _y, 2); \ |
\ |
/* Normalize since we know where the msb of the multiplicands \ |
were (bit B), we know that the msb of the of the product is \ |
at either 2B or 2B-1. */ \ |
_FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ |
R##_f0 = _z_f[0]; \ |
R##_f1 = _z_f[1]; \ |
} while (0) |
|
/* Do at most 120x120=240 bits multiplication using double floating |
point multiplication. This is useful if floating point |
multiplication has much bigger throughput than integer multiply. |
It is supposed to work for _FP_W_TYPE_SIZE 64 and wfracbits |
between 106 and 120 only. |
Caller guarantees that X and Y has (1LLL << (wfracbits - 1)) set. |
SETFETZ is a macro which will disable all FPU exceptions and set rounding |
towards zero, RESETFE should optionally reset it back. */ |
|
#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe) \ |
do { \ |
static const double _const[] = { \ |
/* 2^-24 */ 5.9604644775390625e-08, \ |
/* 2^-48 */ 3.5527136788005009e-15, \ |
/* 2^-72 */ 2.1175823681357508e-22, \ |
/* 2^-96 */ 1.2621774483536189e-29, \ |
/* 2^28 */ 2.68435456e+08, \ |
/* 2^4 */ 1.600000e+01, \ |
/* 2^-20 */ 9.5367431640625e-07, \ |
/* 2^-44 */ 5.6843418860808015e-14, \ |
/* 2^-68 */ 3.3881317890172014e-21, \ |
/* 2^-92 */ 2.0194839173657902e-28, \ |
/* 2^-116 */ 1.2037062152420224e-35}; \ |
double _a240, _b240, _c240, _d240, _e240, _f240, \ |
_g240, _h240, _i240, _j240, _k240; \ |
union { double d; UDItype i; } _l240, _m240, _n240, _o240, \ |
_p240, _q240, _r240, _s240; \ |
UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \ |
\ |
if (wfracbits < 106 || wfracbits > 120) \ |
abort(); \ |
\ |
setfetz; \ |
\ |
_e240 = (double)(long)(X##_f0 & 0xffffff); \ |
_j240 = (double)(long)(Y##_f0 & 0xffffff); \ |
_d240 = (double)(long)((X##_f0 >> 24) & 0xffffff); \ |
_i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff); \ |
_c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48)); \ |
_h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48)); \ |
_b240 = (double)(long)((X##_f1 >> 8) & 0xffffff); \ |
_g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff); \ |
_a240 = (double)(long)(X##_f1 >> 32); \ |
_f240 = (double)(long)(Y##_f1 >> 32); \ |
_e240 *= _const[3]; \ |
_j240 *= _const[3]; \ |
_d240 *= _const[2]; \ |
_i240 *= _const[2]; \ |
_c240 *= _const[1]; \ |
_h240 *= _const[1]; \ |
_b240 *= _const[0]; \ |
_g240 *= _const[0]; \ |
_s240.d = _e240*_j240;\ |
_r240.d = _d240*_j240 + _e240*_i240;\ |
_q240.d = _c240*_j240 + _d240*_i240 + _e240*_h240;\ |
_p240.d = _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240;\ |
_o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240;\ |
_n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240; \ |
_m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240; \ |
_l240.d = _a240*_g240 + _b240*_f240; \ |
_k240 = _a240*_f240; \ |
_r240.d += _s240.d; \ |
_q240.d += _r240.d; \ |
_p240.d += _q240.d; \ |
_o240.d += _p240.d; \ |
_n240.d += _o240.d; \ |
_m240.d += _n240.d; \ |
_l240.d += _m240.d; \ |
_k240 += _l240.d; \ |
_s240.d -= ((_const[10]+_s240.d)-_const[10]); \ |
_r240.d -= ((_const[9]+_r240.d)-_const[9]); \ |
_q240.d -= ((_const[8]+_q240.d)-_const[8]); \ |
_p240.d -= ((_const[7]+_p240.d)-_const[7]); \ |
_o240.d += _const[7]; \ |
_n240.d += _const[6]; \ |
_m240.d += _const[5]; \ |
_l240.d += _const[4]; \ |
if (_s240.d != 0.0) _y240 = 1; \ |
if (_r240.d != 0.0) _y240 = 1; \ |
if (_q240.d != 0.0) _y240 = 1; \ |
if (_p240.d != 0.0) _y240 = 1; \ |
_t240 = (DItype)_k240; \ |
_u240 = _l240.i; \ |
_v240 = _m240.i; \ |
_w240 = _n240.i; \ |
_x240 = _o240.i; \ |
R##_f1 = (_t240 << (128 - (wfracbits - 1))) \ |
| ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104)); \ |
R##_f0 = ((_u240 & 0xffffff) << (168 - (wfracbits - 1))) \ |
| ((_v240 & 0xffffff) << (144 - (wfracbits - 1))) \ |
| ((_w240 & 0xffffff) << (120 - (wfracbits - 1))) \ |
| ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96)) \ |
| _y240; \ |
resetfe; \ |
} while (0) |
|
/* |
* Division algorithms: |
*/ |
|
#define _FP_DIV_MEAT_2_udiv(fs, R, X, Y) \ |
do { \ |
_FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0; \ |
if (_FP_FRAC_GT_2(X, Y)) \ |
{ \ |
_n_f2 = X##_f1 >> 1; \ |
_n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \ |
_n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \ |
} \ |
else \ |
{ \ |
R##_e--; \ |
_n_f2 = X##_f1; \ |
_n_f1 = X##_f0; \ |
_n_f0 = 0; \ |
} \ |
\ |
/* Normalize, i.e. make the most significant bit of the \ |
denominator set. */ \ |
_FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs); \ |
\ |
udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1); \ |
umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0); \ |
_r_f0 = _n_f0; \ |
if (_FP_FRAC_GT_2(_m, _r)) \ |
{ \ |
R##_f1--; \ |
_FP_FRAC_ADD_2(_r, Y, _r); \ |
if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ |
{ \ |
R##_f1--; \ |
_FP_FRAC_ADD_2(_r, Y, _r); \ |
} \ |
} \ |
_FP_FRAC_DEC_2(_r, _m); \ |
\ |
if (_r_f1 == Y##_f1) \ |
{ \ |
/* This is a special case, not an optimization \ |
(_r/Y##_f1 would not fit into UWtype). \ |
As _r is guaranteed to be < Y, R##_f0 can be either \ |
(UWtype)-1 or (UWtype)-2. But as we know what kind \ |
of bits it is (sticky, guard, round), we don't care. \ |
We also don't care what the reminder is, because the \ |
guard bit will be set anyway. -jj */ \ |
R##_f0 = -1; \ |
} \ |
else \ |
{ \ |
udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1); \ |
umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0); \ |
_r_f0 = 0; \ |
if (_FP_FRAC_GT_2(_m, _r)) \ |
{ \ |
R##_f0--; \ |
_FP_FRAC_ADD_2(_r, Y, _r); \ |
if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ |
{ \ |
R##_f0--; \ |
_FP_FRAC_ADD_2(_r, Y, _r); \ |
} \ |
} \ |
if (!_FP_FRAC_EQ_2(_r, _m)) \ |
R##_f0 |= _FP_WORK_STICKY; \ |
} \ |
} while (0) |
|
|
#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \ |
do { \ |
_FP_W_TYPE _x[4], _y[2], _z[4]; \ |
_y[0] = Y##_f0; _y[1] = Y##_f1; \ |
_x[0] = _x[3] = 0; \ |
if (_FP_FRAC_GT_2(X, Y)) \ |
{ \ |
R##_e++; \ |
_x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) | \ |
X##_f1 >> (_FP_W_TYPE_SIZE - \ |
(_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE))); \ |
_x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE); \ |
} \ |
else \ |
{ \ |
_x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) | \ |
X##_f1 >> (_FP_W_TYPE_SIZE - \ |
(_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE))); \ |
_x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE); \ |
} \ |
\ |
(void) mpn_divrem (_z, 0, _x, 4, _y, 2); \ |
R##_f1 = _z[1]; \ |
R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \ |
} while (0) |
|
|
/* |
* Square root algorithms: |
* We have just one right now, maybe Newton approximation |
* should be added for those machines where division is fast. |
*/ |
|
#define _FP_SQRT_MEAT_2(R, S, T, X, q) \ |
do { \ |
while (q) \ |
{ \ |
T##_f1 = S##_f1 + q; \ |
if (T##_f1 <= X##_f1) \ |
{ \ |
S##_f1 = T##_f1 + q; \ |
X##_f1 -= T##_f1; \ |
R##_f1 += q; \ |
} \ |
_FP_FRAC_SLL_2(X, 1); \ |
q >>= 1; \ |
} \ |
q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ |
while (q != _FP_WORK_ROUND) \ |
{ \ |
T##_f0 = S##_f0 + q; \ |
T##_f1 = S##_f1; \ |
if (T##_f1 < X##_f1 || \ |
(T##_f1 == X##_f1 && T##_f0 <= X##_f0)) \ |
{ \ |
S##_f0 = T##_f0 + q; \ |
S##_f1 += (T##_f0 > S##_f0); \ |
_FP_FRAC_DEC_2(X, T); \ |
R##_f0 += q; \ |
} \ |
_FP_FRAC_SLL_2(X, 1); \ |
q >>= 1; \ |
} \ |
if (X##_f0 | X##_f1) \ |
{ \ |
if (S##_f1 < X##_f1 || \ |
(S##_f1 == X##_f1 && S##_f0 < X##_f0)) \ |
R##_f0 |= _FP_WORK_ROUND; \ |
R##_f0 |= _FP_WORK_STICKY; \ |
} \ |
} while (0) |
|
|
/* |
* Assembly/disassembly for converting to/from integral types. |
* No shifting or overflow handled here. |
*/ |
|
#define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \ |
(void)((rsize <= _FP_W_TYPE_SIZE) \ |
? ({ r = X##_f0; }) \ |
: ({ \ |
r = X##_f1; \ |
r <<= _FP_W_TYPE_SIZE; \ |
r += X##_f0; \ |
})) |
|
#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \ |
do { \ |
X##_f0 = r; \ |
X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ |
} while (0) |
|
/* |
* Convert FP values between word sizes |
*/ |
|
#define _FP_FRAC_COPY_1_2(D, S) (D##_f = S##_f0) |
|
#define _FP_FRAC_COPY_2_1(D, S) ((D##_f0 = S##_f), (D##_f1 = 0)) |
|
#define _FP_FRAC_COPY_2_2(D,S) _FP_FRAC_COPY_2(D,S) |
/fixunstfdi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 64bit unsigned integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
UDItype __fixunstfdi(TFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); |
UDItype r; |
|
FP_UNPACK_RAW_Q(A, a); |
FP_TO_INT_Q(r, A, DI_BITS, 0); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/op-4.h
0,0 → 1,688
/* Software floating-point emulation. |
Basic four-word fraction declaration and manipulation. |
Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com), |
Jakub Jelinek (jj@ultra.linux.cz), |
David S. Miller (davem@redhat.com) and |
Peter Maydell (pmaydell@chiark.greenend.org.uk). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4] |
#define _FP_FRAC_COPY_4(D,S) \ |
(D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \ |
D##_f[2] = S##_f[2], D##_f[3] = S##_f[3]) |
#define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I) |
#define _FP_FRAC_HIGH_4(X) (X##_f[3]) |
#define _FP_FRAC_LOW_4(X) (X##_f[0]) |
#define _FP_FRAC_WORD_4(X,w) (X##_f[w]) |
|
#define _FP_FRAC_SLL_4(X,N) \ |
do { \ |
_FP_I_TYPE _up, _down, _skip, _i; \ |
_skip = (N) / _FP_W_TYPE_SIZE; \ |
_up = (N) % _FP_W_TYPE_SIZE; \ |
_down = _FP_W_TYPE_SIZE - _up; \ |
if (!_up) \ |
for (_i = 3; _i >= _skip; --_i) \ |
X##_f[_i] = X##_f[_i-_skip]; \ |
else \ |
{ \ |
for (_i = 3; _i > _skip; --_i) \ |
X##_f[_i] = X##_f[_i-_skip] << _up \ |
| X##_f[_i-_skip-1] >> _down; \ |
X##_f[_i--] = X##_f[0] << _up; \ |
} \ |
for (; _i >= 0; --_i) \ |
X##_f[_i] = 0; \ |
} while (0) |
|
/* This one was broken too */ |
#define _FP_FRAC_SRL_4(X,N) \ |
do { \ |
_FP_I_TYPE _up, _down, _skip, _i; \ |
_skip = (N) / _FP_W_TYPE_SIZE; \ |
_down = (N) % _FP_W_TYPE_SIZE; \ |
_up = _FP_W_TYPE_SIZE - _down; \ |
if (!_down) \ |
for (_i = 0; _i <= 3-_skip; ++_i) \ |
X##_f[_i] = X##_f[_i+_skip]; \ |
else \ |
{ \ |
for (_i = 0; _i < 3-_skip; ++_i) \ |
X##_f[_i] = X##_f[_i+_skip] >> _down \ |
| X##_f[_i+_skip+1] << _up; \ |
X##_f[_i++] = X##_f[3] >> _down; \ |
} \ |
for (; _i < 4; ++_i) \ |
X##_f[_i] = 0; \ |
} while (0) |
|
|
/* Right shift with sticky-lsb. |
* What this actually means is that we do a standard right-shift, |
* but that if any of the bits that fall off the right hand side |
* were one then we always set the LSbit. |
*/ |
#define _FP_FRAC_SRST_4(X,S,N,size) \ |
do { \ |
_FP_I_TYPE _up, _down, _skip, _i; \ |
_FP_W_TYPE _s; \ |
_skip = (N) / _FP_W_TYPE_SIZE; \ |
_down = (N) % _FP_W_TYPE_SIZE; \ |
_up = _FP_W_TYPE_SIZE - _down; \ |
for (_s = _i = 0; _i < _skip; ++_i) \ |
_s |= X##_f[_i]; \ |
if (!_down) \ |
for (_i = 0; _i <= 3-_skip; ++_i) \ |
X##_f[_i] = X##_f[_i+_skip]; \ |
else \ |
{ \ |
_s |= X##_f[_i] << _up; \ |
for (_i = 0; _i < 3-_skip; ++_i) \ |
X##_f[_i] = X##_f[_i+_skip] >> _down \ |
| X##_f[_i+_skip+1] << _up; \ |
X##_f[_i++] = X##_f[3] >> _down; \ |
} \ |
for (; _i < 4; ++_i) \ |
X##_f[_i] = 0; \ |
S = (_s != 0); \ |
} while (0) |
|
#define _FP_FRAC_SRS_4(X,N,size) \ |
do { \ |
int _sticky; \ |
_FP_FRAC_SRST_4(X, _sticky, N, size); \ |
X##_f[0] |= _sticky; \ |
} while (0) |
|
#define _FP_FRAC_ADD_4(R,X,Y) \ |
__FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ |
X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ |
Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) |
|
#define _FP_FRAC_SUB_4(R,X,Y) \ |
__FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ |
X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ |
Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) |
|
#define _FP_FRAC_DEC_4(X,Y) \ |
__FP_FRAC_DEC_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ |
Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) |
|
#define _FP_FRAC_ADDI_4(X,I) \ |
__FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I) |
|
#define _FP_ZEROFRAC_4 0,0,0,0 |
#define _FP_MINFRAC_4 0,0,0,1 |
#define _FP_MAXFRAC_4 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0) |
|
#define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0) |
#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE)X##_f[3] < 0) |
#define _FP_FRAC_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs) |
#define _FP_FRAC_CLEAR_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs) |
|
#define _FP_FRAC_EQ_4(X,Y) \ |
(X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \ |
&& X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3]) |
|
#define _FP_FRAC_GT_4(X,Y) \ |
(X##_f[3] > Y##_f[3] || \ |
(X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ |
(X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ |
(X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \ |
)) \ |
)) \ |
) |
|
#define _FP_FRAC_GE_4(X,Y) \ |
(X##_f[3] > Y##_f[3] || \ |
(X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ |
(X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ |
(X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \ |
)) \ |
)) \ |
) |
|
|
#define _FP_FRAC_CLZ_4(R,X) \ |
do { \ |
if (X##_f[3]) \ |
{ \ |
__FP_CLZ(R,X##_f[3]); \ |
} \ |
else if (X##_f[2]) \ |
{ \ |
__FP_CLZ(R,X##_f[2]); \ |
R += _FP_W_TYPE_SIZE; \ |
} \ |
else if (X##_f[1]) \ |
{ \ |
__FP_CLZ(R,X##_f[1]); \ |
R += _FP_W_TYPE_SIZE*2; \ |
} \ |
else \ |
{ \ |
__FP_CLZ(R,X##_f[0]); \ |
R += _FP_W_TYPE_SIZE*3; \ |
} \ |
} while(0) |
|
|
#define _FP_UNPACK_RAW_4(fs, X, val) \ |
do { \ |
union _FP_UNION_##fs _flo; _flo.flt = (val); \ |
X##_f[0] = _flo.bits.frac0; \ |
X##_f[1] = _flo.bits.frac1; \ |
X##_f[2] = _flo.bits.frac2; \ |
X##_f[3] = _flo.bits.frac3; \ |
X##_e = _flo.bits.exp; \ |
X##_s = _flo.bits.sign; \ |
} while (0) |
|
#define _FP_UNPACK_RAW_4_P(fs, X, val) \ |
do { \ |
union _FP_UNION_##fs *_flo = \ |
(union _FP_UNION_##fs *)(val); \ |
\ |
X##_f[0] = _flo->bits.frac0; \ |
X##_f[1] = _flo->bits.frac1; \ |
X##_f[2] = _flo->bits.frac2; \ |
X##_f[3] = _flo->bits.frac3; \ |
X##_e = _flo->bits.exp; \ |
X##_s = _flo->bits.sign; \ |
} while (0) |
|
#define _FP_PACK_RAW_4(fs, val, X) \ |
do { \ |
union _FP_UNION_##fs _flo; \ |
_flo.bits.frac0 = X##_f[0]; \ |
_flo.bits.frac1 = X##_f[1]; \ |
_flo.bits.frac2 = X##_f[2]; \ |
_flo.bits.frac3 = X##_f[3]; \ |
_flo.bits.exp = X##_e; \ |
_flo.bits.sign = X##_s; \ |
(val) = _flo.flt; \ |
} while (0) |
|
#define _FP_PACK_RAW_4_P(fs, val, X) \ |
do { \ |
union _FP_UNION_##fs *_flo = \ |
(union _FP_UNION_##fs *)(val); \ |
\ |
_flo->bits.frac0 = X##_f[0]; \ |
_flo->bits.frac1 = X##_f[1]; \ |
_flo->bits.frac2 = X##_f[2]; \ |
_flo->bits.frac3 = X##_f[3]; \ |
_flo->bits.exp = X##_e; \ |
_flo->bits.sign = X##_s; \ |
} while (0) |
|
/* |
* Multiplication algorithms: |
*/ |
|
/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ |
|
#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \ |
do { \ |
_FP_FRAC_DECL_8(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ |
_FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f); \ |
\ |
doit(_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0), X##_f[0], Y##_f[0]); \ |
doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]); \ |
doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]); \ |
doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]); \ |
doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]); \ |
doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ |
_FP_FRAC_WORD_8(_z,1), 0,_b_f1,_b_f0, \ |
0,0,_FP_FRAC_WORD_8(_z,1)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ |
_FP_FRAC_WORD_8(_z,1), 0,_c_f1,_c_f0, \ |
_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ |
_FP_FRAC_WORD_8(_z,1)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ |
_FP_FRAC_WORD_8(_z,2), 0,_d_f1,_d_f0, \ |
0,_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ |
_FP_FRAC_WORD_8(_z,2), 0,_e_f1,_e_f0, \ |
_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ |
_FP_FRAC_WORD_8(_z,2)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ |
_FP_FRAC_WORD_8(_z,2), 0,_f_f1,_f_f0, \ |
_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ |
_FP_FRAC_WORD_8(_z,2)); \ |
doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]); \ |
doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]); \ |
doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]); \ |
doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ |
_FP_FRAC_WORD_8(_z,3), 0,_b_f1,_b_f0, \ |
0,_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ |
_FP_FRAC_WORD_8(_z,3), 0,_c_f1,_c_f0, \ |
_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ |
_FP_FRAC_WORD_8(_z,3)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ |
_FP_FRAC_WORD_8(_z,3), 0,_d_f1,_d_f0, \ |
_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ |
_FP_FRAC_WORD_8(_z,3)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ |
_FP_FRAC_WORD_8(_z,3), 0,_e_f1,_e_f0, \ |
_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ |
_FP_FRAC_WORD_8(_z,3)); \ |
doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]); \ |
doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]); \ |
doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]); \ |
doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]); \ |
doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ |
_FP_FRAC_WORD_8(_z,4), 0,_b_f1,_b_f0, \ |
0,_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ |
_FP_FRAC_WORD_8(_z,4), 0,_c_f1,_c_f0, \ |
_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ |
_FP_FRAC_WORD_8(_z,4)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ |
_FP_FRAC_WORD_8(_z,4), 0,_d_f1,_d_f0, \ |
_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ |
_FP_FRAC_WORD_8(_z,4)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ |
_FP_FRAC_WORD_8(_z,5), 0,_e_f1,_e_f0, \ |
0,_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5)); \ |
__FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ |
_FP_FRAC_WORD_8(_z,5), 0,_f_f1,_f_f0, \ |
_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ |
_FP_FRAC_WORD_8(_z,5)); \ |
doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]); \ |
__FP_FRAC_ADD_2(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ |
_b_f1,_b_f0, \ |
_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6)); \ |
\ |
/* Normalize since we know where the msb of the multiplicands \ |
were (bit B), we know that the msb of the of the product is \ |
at either 2B or 2B-1. */ \ |
_FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ |
__FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ |
_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ |
} while (0) |
|
#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \ |
do { \ |
_FP_FRAC_DECL_8(_z); \ |
\ |
mpn_mul_n(_z_f, _x_f, _y_f, 4); \ |
\ |
/* Normalize since we know where the msb of the multiplicands \ |
were (bit B), we know that the msb of the of the product is \ |
at either 2B or 2B-1. */ \ |
_FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ |
__FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ |
_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ |
} while (0) |
|
/* |
* Helper utility for _FP_DIV_MEAT_4_udiv: |
* pppp = m * nnn |
*/ |
#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0) \ |
do { \ |
UWtype _t; \ |
umul_ppmm(p1,p0,m,n0); \ |
umul_ppmm(p2,_t,m,n1); \ |
__FP_FRAC_ADDI_2(p2,p1,_t); \ |
umul_ppmm(p3,_t,m,n2); \ |
__FP_FRAC_ADDI_2(p3,p2,_t); \ |
} while (0) |
|
/* |
* Division algorithms: |
*/ |
|
#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \ |
do { \ |
int _i; \ |
_FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m); \ |
_FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4); \ |
if (_FP_FRAC_GT_4(X, Y)) \ |
{ \ |
_n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \ |
_FP_FRAC_SRL_4(X, 1); \ |
} \ |
else \ |
R##_e--; \ |
\ |
/* Normalize, i.e. make the most significant bit of the \ |
denominator set. */ \ |
_FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs); \ |
\ |
for (_i = 3; ; _i--) \ |
{ \ |
if (X##_f[3] == Y##_f[3]) \ |
{ \ |
/* This is a special case, not an optimization \ |
(X##_f[3]/Y##_f[3] would not fit into UWtype). \ |
As X## is guaranteed to be < Y, R##_f[_i] can be either \ |
(UWtype)-1 or (UWtype)-2. */ \ |
R##_f[_i] = -1; \ |
if (!_i) \ |
break; \ |
__FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ |
Y##_f[2], Y##_f[1], Y##_f[0], 0, \ |
X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \ |
_FP_FRAC_SUB_4(X, Y, X); \ |
if (X##_f[3] > Y##_f[3]) \ |
{ \ |
R##_f[_i] = -2; \ |
_FP_FRAC_ADD_4(X, Y, X); \ |
} \ |
} \ |
else \ |
{ \ |
udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \ |
umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0], \ |
R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \ |
X##_f[2] = X##_f[1]; \ |
X##_f[1] = X##_f[0]; \ |
X##_f[0] = _n_f[_i]; \ |
if (_FP_FRAC_GT_4(_m, X)) \ |
{ \ |
R##_f[_i]--; \ |
_FP_FRAC_ADD_4(X, Y, X); \ |
if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X)) \ |
{ \ |
R##_f[_i]--; \ |
_FP_FRAC_ADD_4(X, Y, X); \ |
} \ |
} \ |
_FP_FRAC_DEC_4(X, _m); \ |
if (!_i) \ |
{ \ |
if (!_FP_FRAC_EQ_4(X, _m)) \ |
R##_f[0] |= _FP_WORK_STICKY; \ |
break; \ |
} \ |
} \ |
} \ |
} while (0) |
|
|
/* |
* Square root algorithms: |
* We have just one right now, maybe Newton approximation |
* should be added for those machines where division is fast. |
*/ |
|
#define _FP_SQRT_MEAT_4(R, S, T, X, q) \ |
do { \ |
while (q) \ |
{ \ |
T##_f[3] = S##_f[3] + q; \ |
if (T##_f[3] <= X##_f[3]) \ |
{ \ |
S##_f[3] = T##_f[3] + q; \ |
X##_f[3] -= T##_f[3]; \ |
R##_f[3] += q; \ |
} \ |
_FP_FRAC_SLL_4(X, 1); \ |
q >>= 1; \ |
} \ |
q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ |
while (q) \ |
{ \ |
T##_f[2] = S##_f[2] + q; \ |
T##_f[3] = S##_f[3]; \ |
if (T##_f[3] < X##_f[3] || \ |
(T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \ |
{ \ |
S##_f[2] = T##_f[2] + q; \ |
S##_f[3] += (T##_f[2] > S##_f[2]); \ |
__FP_FRAC_DEC_2(X##_f[3], X##_f[2], \ |
T##_f[3], T##_f[2]); \ |
R##_f[2] += q; \ |
} \ |
_FP_FRAC_SLL_4(X, 1); \ |
q >>= 1; \ |
} \ |
q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ |
while (q) \ |
{ \ |
T##_f[1] = S##_f[1] + q; \ |
T##_f[2] = S##_f[2]; \ |
T##_f[3] = S##_f[3]; \ |
if (T##_f[3] < X##_f[3] || \ |
(T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] || \ |
(T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1])))) \ |
{ \ |
S##_f[1] = T##_f[1] + q; \ |
S##_f[2] += (T##_f[1] > S##_f[1]); \ |
S##_f[3] += (T##_f[2] > S##_f[2]); \ |
__FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1], \ |
T##_f[3], T##_f[2], T##_f[1]); \ |
R##_f[1] += q; \ |
} \ |
_FP_FRAC_SLL_4(X, 1); \ |
q >>= 1; \ |
} \ |
q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ |
while (q != _FP_WORK_ROUND) \ |
{ \ |
T##_f[0] = S##_f[0] + q; \ |
T##_f[1] = S##_f[1]; \ |
T##_f[2] = S##_f[2]; \ |
T##_f[3] = S##_f[3]; \ |
if (_FP_FRAC_GE_4(X,T)) \ |
{ \ |
S##_f[0] = T##_f[0] + q; \ |
S##_f[1] += (T##_f[0] > S##_f[0]); \ |
S##_f[2] += (T##_f[1] > S##_f[1]); \ |
S##_f[3] += (T##_f[2] > S##_f[2]); \ |
_FP_FRAC_DEC_4(X, T); \ |
R##_f[0] += q; \ |
} \ |
_FP_FRAC_SLL_4(X, 1); \ |
q >>= 1; \ |
} \ |
if (!_FP_FRAC_ZEROP_4(X)) \ |
{ \ |
if (_FP_FRAC_GT_4(X,S)) \ |
R##_f[0] |= _FP_WORK_ROUND; \ |
R##_f[0] |= _FP_WORK_STICKY; \ |
} \ |
} while (0) |
|
|
/* |
* Internals |
*/ |
|
#define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \ |
(X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0) |
|
#ifndef __FP_FRAC_ADD_3 |
#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ |
do { \ |
_FP_W_TYPE _c1, _c2; \ |
r0 = x0 + y0; \ |
_c1 = r0 < x0; \ |
r1 = x1 + y1; \ |
_c2 = r1 < x1; \ |
r1 += _c1; \ |
_c2 |= r1 < _c1; \ |
r2 = x2 + y2 + _c2; \ |
} while (0) |
#endif |
|
#ifndef __FP_FRAC_ADD_4 |
#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ |
do { \ |
_FP_W_TYPE _c1, _c2, _c3; \ |
r0 = x0 + y0; \ |
_c1 = r0 < x0; \ |
r1 = x1 + y1; \ |
_c2 = r1 < x1; \ |
r1 += _c1; \ |
_c2 |= r1 < _c1; \ |
r2 = x2 + y2; \ |
_c3 = r2 < x2; \ |
r2 += _c2; \ |
_c3 |= r2 < _c2; \ |
r3 = x3 + y3 + _c3; \ |
} while (0) |
#endif |
|
#ifndef __FP_FRAC_SUB_3 |
#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ |
do { \ |
_FP_W_TYPE _c1, _c2; \ |
r0 = x0 - y0; \ |
_c1 = r0 > x0; \ |
r1 = x1 - y1; \ |
_c2 = r1 > x1; \ |
r1 -= _c1; \ |
_c2 |= _c1 && (y1 == x1); \ |
r2 = x2 - y2 - _c2; \ |
} while (0) |
#endif |
|
#ifndef __FP_FRAC_SUB_4 |
#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ |
do { \ |
_FP_W_TYPE _c1, _c2, _c3; \ |
r0 = x0 - y0; \ |
_c1 = r0 > x0; \ |
r1 = x1 - y1; \ |
_c2 = r1 > x1; \ |
r1 -= _c1; \ |
_c2 |= _c1 && (y1 == x1); \ |
r2 = x2 - y2; \ |
_c3 = r2 > x2; \ |
r2 -= _c2; \ |
_c3 |= _c2 && (y2 == x2); \ |
r3 = x3 - y3 - _c3; \ |
} while (0) |
#endif |
|
#ifndef __FP_FRAC_DEC_3 |
#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) \ |
do { \ |
UWtype _t0, _t1, _t2; \ |
_t0 = x0, _t1 = x1, _t2 = x2; \ |
__FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \ |
} while (0) |
#endif |
|
#ifndef __FP_FRAC_DEC_4 |
#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) \ |
do { \ |
UWtype _t0, _t1, _t2, _t3; \ |
_t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \ |
__FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0); \ |
} while (0) |
#endif |
|
#ifndef __FP_FRAC_ADDI_4 |
#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ |
do { \ |
UWtype _t; \ |
_t = ((x0 += i) < i); \ |
x1 += _t; _t = (x1 < _t); \ |
x2 += _t; _t = (x2 < _t); \ |
x3 += _t; \ |
} while (0) |
#endif |
|
/* Convert FP values between word sizes. This appears to be more |
* complicated than I'd have expected it to be, so these might be |
* wrong... These macros are in any case somewhat bogus because they |
* use information about what various FRAC_n variables look like |
* internally [eg, that 2 word vars are X_f0 and x_f1]. But so do |
* the ones in op-2.h and op-1.h. |
*/ |
#define _FP_FRAC_COPY_1_4(D, S) (D##_f = S##_f[0]) |
|
#define _FP_FRAC_COPY_2_4(D, S) \ |
do { \ |
D##_f0 = S##_f[0]; \ |
D##_f1 = S##_f[1]; \ |
} while (0) |
|
/* Assembly/disassembly for converting to/from integral types. |
* No shifting or overflow handled here. |
*/ |
/* Put the FP value X into r, which is an integer of size rsize. */ |
#define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \ |
do { \ |
if (rsize <= _FP_W_TYPE_SIZE) \ |
r = X##_f[0]; \ |
else if (rsize <= 2*_FP_W_TYPE_SIZE) \ |
{ \ |
r = X##_f[1]; \ |
r <<= _FP_W_TYPE_SIZE; \ |
r += X##_f[0]; \ |
} \ |
else \ |
{ \ |
/* I'm feeling lazy so we deal with int == 3words (implausible)*/ \ |
/* and int == 4words as a single case. */ \ |
r = X##_f[3]; \ |
r <<= _FP_W_TYPE_SIZE; \ |
r += X##_f[2]; \ |
r <<= _FP_W_TYPE_SIZE; \ |
r += X##_f[1]; \ |
r <<= _FP_W_TYPE_SIZE; \ |
r += X##_f[0]; \ |
} \ |
} while (0) |
|
/* "No disassemble Number Five!" */ |
/* move an integer of size rsize into X's fractional part. We rely on |
* the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid |
* having to mask the values we store into it. |
*/ |
#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \ |
do { \ |
X##_f[0] = r; \ |
X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ |
X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \ |
X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \ |
} while (0); |
|
#define _FP_FRAC_COPY_4_1(D, S) \ |
do { \ |
D##_f[0] = S##_f; \ |
D##_f[1] = D##_f[2] = D##_f[3] = 0; \ |
} while (0) |
|
#define _FP_FRAC_COPY_4_2(D, S) \ |
do { \ |
D##_f[0] = S##_f0; \ |
D##_f[1] = S##_f1; \ |
D##_f[2] = D##_f[3] = 0; \ |
} while (0) |
|
#define _FP_FRAC_COPY_4_4(D,S) _FP_FRAC_COPY_4(D,S) |
/adddf3.c
0,0 → 1,49
/* Software floating-point emulation. |
Return a + b |
Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
DFtype __adddf3(DFtype a, DFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); |
DFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_SEMIRAW_D(A, a); |
FP_UNPACK_SEMIRAW_D(B, b); |
FP_ADD_D(R, A, B); |
FP_PACK_SEMIRAW_D(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/op-8.h
0,0 → 1,111
/* Software floating-point emulation. |
Basic eight-word fraction declaration and manipulation. |
Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com), |
Jakub Jelinek (jj@ultra.linux.cz) and |
Peter Maydell (pmaydell@chiark.greenend.org.uk). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
/* We need just a few things from here for op-4, if we ever need some |
other macros, they can be added. */ |
#define _FP_FRAC_DECL_8(X) _FP_W_TYPE X##_f[8] |
#define _FP_FRAC_HIGH_8(X) (X##_f[7]) |
#define _FP_FRAC_LOW_8(X) (X##_f[0]) |
#define _FP_FRAC_WORD_8(X,w) (X##_f[w]) |
|
#define _FP_FRAC_SLL_8(X,N) \ |
do { \ |
_FP_I_TYPE _up, _down, _skip, _i; \ |
_skip = (N) / _FP_W_TYPE_SIZE; \ |
_up = (N) % _FP_W_TYPE_SIZE; \ |
_down = _FP_W_TYPE_SIZE - _up; \ |
if (!_up) \ |
for (_i = 7; _i >= _skip; --_i) \ |
X##_f[_i] = X##_f[_i-_skip]; \ |
else \ |
{ \ |
for (_i = 7; _i > _skip; --_i) \ |
X##_f[_i] = X##_f[_i-_skip] << _up \ |
| X##_f[_i-_skip-1] >> _down; \ |
X##_f[_i--] = X##_f[0] << _up; \ |
} \ |
for (; _i >= 0; --_i) \ |
X##_f[_i] = 0; \ |
} while (0) |
|
#define _FP_FRAC_SRL_8(X,N) \ |
do { \ |
_FP_I_TYPE _up, _down, _skip, _i; \ |
_skip = (N) / _FP_W_TYPE_SIZE; \ |
_down = (N) % _FP_W_TYPE_SIZE; \ |
_up = _FP_W_TYPE_SIZE - _down; \ |
if (!_down) \ |
for (_i = 0; _i <= 7-_skip; ++_i) \ |
X##_f[_i] = X##_f[_i+_skip]; \ |
else \ |
{ \ |
for (_i = 0; _i < 7-_skip; ++_i) \ |
X##_f[_i] = X##_f[_i+_skip] >> _down \ |
| X##_f[_i+_skip+1] << _up; \ |
X##_f[_i++] = X##_f[7] >> _down; \ |
} \ |
for (; _i < 8; ++_i) \ |
X##_f[_i] = 0; \ |
} while (0) |
|
|
/* Right shift with sticky-lsb. |
* What this actually means is that we do a standard right-shift, |
* but that if any of the bits that fall off the right hand side |
* were one then we always set the LSbit. |
*/ |
#define _FP_FRAC_SRS_8(X,N,size) \ |
do { \ |
_FP_I_TYPE _up, _down, _skip, _i; \ |
_FP_W_TYPE _s; \ |
_skip = (N) / _FP_W_TYPE_SIZE; \ |
_down = (N) % _FP_W_TYPE_SIZE; \ |
_up = _FP_W_TYPE_SIZE - _down; \ |
for (_s = _i = 0; _i < _skip; ++_i) \ |
_s |= X##_f[_i]; \ |
if (!_down) \ |
for (_i = 0; _i <= 7-_skip; ++_i) \ |
X##_f[_i] = X##_f[_i+_skip]; \ |
else \ |
{ \ |
_s |= X##_f[_i] << _up; \ |
for (_i = 0; _i < 7-_skip; ++_i) \ |
X##_f[_i] = X##_f[_i+_skip] >> _down \ |
| X##_f[_i+_skip+1] << _up; \ |
X##_f[_i++] = X##_f[7] >> _down; \ |
} \ |
for (; _i < 8; ++_i) \ |
X##_f[_i] = 0; \ |
/* don't fix the LSB until the very end when we're sure f[0] is stable */ \ |
X##_f[0] |= (_s != 0); \ |
} while (0) |
|
/floatsitf.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a 32bit signed integer to IEEE quad |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
TFtype __floatsitf(SItype i) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); |
TFtype a; |
|
FP_FROM_INT_Q(A, i, SI_BITS, USItype); |
FP_PACK_RAW_Q(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/floatdidf.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a 64bit signed integer to IEEE double |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
DFtype __floatdidf(DItype i) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); |
DFtype a; |
|
FP_FROM_INT_D(A, i, DI_BITS, UDItype); |
FP_PACK_RAW_D(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/fixtfdi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 64bit signed integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
DItype __fixtfdi(TFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); |
UDItype r; |
|
FP_UNPACK_RAW_Q(A, a); |
FP_TO_INT_Q(r, A, DI_BITS, 1); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/fixunssfsi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 32bit unsigned integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
USItype __fixunssfsi(SFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); |
USItype r; |
|
FP_UNPACK_RAW_S(A, a); |
FP_TO_INT_S(r, A, SI_BITS, 0); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/addsf3.c
0,0 → 1,50
/* Software floating-point emulation. |
Return a + b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
SFtype __addsf3(SFtype a, SFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); |
SFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_SEMIRAW_S(A, a); |
FP_UNPACK_SEMIRAW_S(B, b); |
FP_ADD_S(R, A, B); |
FP_PACK_SEMIRAW_S(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
|
/addtf3.c
0,0 → 1,49
/* Software floating-point emulation. |
Return a + b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
TFtype __addtf3(TFtype a, TFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); |
TFtype r; |
|
FP_INIT_ROUNDMODE; |
FP_UNPACK_SEMIRAW_Q(A, a); |
FP_UNPACK_SEMIRAW_Q(B, b); |
FP_ADD_Q(R, A, B); |
FP_PACK_SEMIRAW_Q(r, R); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/fixsfsi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 32bit signed integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
SItype __fixsfsi(SFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); |
USItype r; |
|
FP_UNPACK_RAW_S(A, a); |
FP_TO_INT_S(r, A, SI_BITS, 1); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/floatditf.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a 64bit signed integer to IEEE quad |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "quad.h" |
|
TFtype __floatditf(DItype i) |
{ |
FP_DECL_EX; |
FP_DECL_Q(A); |
TFtype a; |
|
FP_FROM_INT_Q(A, i, DI_BITS, UDItype); |
FP_PACK_RAW_Q(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/README
0,0 → 1,4
Except for t-softfp, the files in this directory are part of the GNU C |
Library, not part of GCC. As described at |
<http://gcc.gnu.org/codingconventions.html>, changes should be made to |
the GNU C Library and the changed files then imported into GCC. |
/double.h
0,0 → 1,264
/* Software floating-point emulation. |
Definitions for IEEE Double Precision |
Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com), |
Jakub Jelinek (jj@ultra.linux.cz), |
David S. Miller (davem@redhat.com) and |
Peter Maydell (pmaydell@chiark.greenend.org.uk). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#if _FP_W_TYPE_SIZE < 32 |
#error "Here's a nickel kid. Go buy yourself a real computer." |
#endif |
|
#if _FP_W_TYPE_SIZE < 64 |
#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE) |
#else |
#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE |
#endif |
|
#define _FP_FRACBITS_D 53 |
#define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D) |
#define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D) |
#define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D) |
#define _FP_EXPBITS_D 11 |
#define _FP_EXPBIAS_D 1023 |
#define _FP_EXPMAX_D 2047 |
|
#define _FP_QNANBIT_D \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE) |
#define _FP_QNANBIT_SH_D \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) |
#define _FP_IMPLBIT_D \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE) |
#define _FP_IMPLBIT_SH_D \ |
((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) |
#define _FP_OVERFLOW_D \ |
((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE) |
|
typedef float DFtype __attribute__((mode(DF))); |
|
#if _FP_W_TYPE_SIZE < 64 |
|
union _FP_UNION_D |
{ |
DFtype flt; |
struct { |
#if __BYTE_ORDER == __BIG_ENDIAN |
unsigned sign : 1; |
unsigned exp : _FP_EXPBITS_D; |
unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; |
unsigned frac0 : _FP_W_TYPE_SIZE; |
#else |
unsigned frac0 : _FP_W_TYPE_SIZE; |
unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; |
unsigned exp : _FP_EXPBITS_D; |
unsigned sign : 1; |
#endif |
} bits __attribute__((packed)); |
}; |
|
#define FP_DECL_D(X) _FP_DECL(2,X) |
#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val) |
#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_2_P(D,X,val) |
#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X) |
#define FP_PACK_RAW_DP(val,X) \ |
do { \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_2_P(D,val,X); \ |
} while (0) |
|
#define FP_UNPACK_D(X,val) \ |
do { \ |
_FP_UNPACK_RAW_2(D,X,val); \ |
_FP_UNPACK_CANONICAL(D,2,X); \ |
} while (0) |
|
#define FP_UNPACK_DP(X,val) \ |
do { \ |
_FP_UNPACK_RAW_2_P(D,X,val); \ |
_FP_UNPACK_CANONICAL(D,2,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_D(X,val) \ |
do { \ |
_FP_UNPACK_RAW_2(D,X,val); \ |
_FP_UNPACK_SEMIRAW(D,2,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_DP(X,val) \ |
do { \ |
_FP_UNPACK_RAW_2_P(D,X,val); \ |
_FP_UNPACK_SEMIRAW(D,2,X); \ |
} while (0) |
|
#define FP_PACK_D(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(D,2,X); \ |
_FP_PACK_RAW_2(D,val,X); \ |
} while (0) |
|
#define FP_PACK_DP(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(D,2,X); \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_2_P(D,val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_D(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(D,2,X); \ |
_FP_PACK_RAW_2(D,val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_DP(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(D,2,X); \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_2_P(D,val,X); \ |
} while (0) |
|
#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,2,X) |
#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X) |
#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y) |
#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y) |
#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y) |
#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y) |
#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X) |
#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) |
|
#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un) |
#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y) |
#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,2,r,X,Y) |
|
#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg) |
#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt) |
|
#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2(X) |
#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2(X) |
|
#else |
|
union _FP_UNION_D |
{ |
DFtype flt; |
struct { |
#if __BYTE_ORDER == __BIG_ENDIAN |
unsigned sign : 1; |
unsigned exp : _FP_EXPBITS_D; |
_FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); |
#else |
_FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); |
unsigned exp : _FP_EXPBITS_D; |
unsigned sign : 1; |
#endif |
} bits __attribute__((packed)); |
}; |
|
#define FP_DECL_D(X) _FP_DECL(1,X) |
#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val) |
#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_1_P(D,X,val) |
#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X) |
#define FP_PACK_RAW_DP(val,X) \ |
do { \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_1_P(D,val,X); \ |
} while (0) |
|
#define FP_UNPACK_D(X,val) \ |
do { \ |
_FP_UNPACK_RAW_1(D,X,val); \ |
_FP_UNPACK_CANONICAL(D,1,X); \ |
} while (0) |
|
#define FP_UNPACK_DP(X,val) \ |
do { \ |
_FP_UNPACK_RAW_1_P(D,X,val); \ |
_FP_UNPACK_CANONICAL(D,1,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_D(X,val) \ |
do { \ |
_FP_UNPACK_RAW_2(1,X,val); \ |
_FP_UNPACK_SEMIRAW(D,1,X); \ |
} while (0) |
|
#define FP_UNPACK_SEMIRAW_DP(X,val) \ |
do { \ |
_FP_UNPACK_RAW_2_P(1,X,val); \ |
_FP_UNPACK_SEMIRAW(D,1,X); \ |
} while (0) |
|
#define FP_PACK_D(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(D,1,X); \ |
_FP_PACK_RAW_1(D,val,X); \ |
} while (0) |
|
#define FP_PACK_DP(val,X) \ |
do { \ |
_FP_PACK_CANONICAL(D,1,X); \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_1_P(D,val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_D(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(D,1,X); \ |
_FP_PACK_RAW_1(D,val,X); \ |
} while (0) |
|
#define FP_PACK_SEMIRAW_DP(val,X) \ |
do { \ |
_FP_PACK_SEMIRAW(D,1,X); \ |
if (!FP_INHIBIT_RESULTS) \ |
_FP_PACK_RAW_1_P(D,val,X); \ |
} while (0) |
|
#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,1,X) |
#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X) |
#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y) |
#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y) |
#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y) |
#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y) |
#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X) |
#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) |
|
/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by |
the target machine. */ |
|
#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un) |
#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y) |
#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,1,r,X,Y) |
|
#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg) |
#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt) |
|
#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1(X) |
#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1(X) |
|
#endif /* W_TYPE_SIZE < 64 */ |
/fixunsdfsi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 32bit unsigned integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
USItype __fixunsdfsi(DFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); |
USItype r; |
|
FP_UNPACK_RAW_D(A, a); |
FP_TO_INT_D(r, A, SI_BITS, 0); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
/soft-fp.h
0,0 → 1,209
/* Software floating-point emulation. |
Copyright (C) 1997,1998,1999,2000,2002,2003,2005,2006 |
Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com), |
Jakub Jelinek (jj@ultra.linux.cz), |
David S. Miller (davem@redhat.com) and |
Peter Maydell (pmaydell@chiark.greenend.org.uk). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#ifndef SOFT_FP_H |
#define SOFT_FP_H |
|
#ifdef _LIBC |
#include <sfp-machine.h> |
#else |
#include "sfp-machine.h" |
#endif |
|
/* Allow sfp-machine to have its own byte order definitions. */ |
#ifndef __BYTE_ORDER |
#ifdef _LIBC |
#include <endian.h> |
#else |
#error "endianness not defined by sfp-machine.h" |
#endif |
#endif |
|
#define _FP_WORKBITS 3 |
#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) |
#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2) |
#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1) |
#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0) |
|
#ifndef FP_RND_NEAREST |
# define FP_RND_NEAREST 0 |
# define FP_RND_ZERO 1 |
# define FP_RND_PINF 2 |
# define FP_RND_MINF 3 |
#endif |
#ifndef FP_ROUNDMODE |
# define FP_ROUNDMODE FP_RND_NEAREST |
#endif |
|
/* By default don't care about exceptions. */ |
#ifndef FP_EX_INVALID |
#define FP_EX_INVALID 0 |
#endif |
#ifndef FP_EX_OVERFLOW |
#define FP_EX_OVERFLOW 0 |
#endif |
#ifndef FP_EX_UNDERFLOW |
#define FP_EX_UNDERFLOW 0 |
#endif |
#ifndef FP_EX_DIVZERO |
#define FP_EX_DIVZERO 0 |
#endif |
#ifndef FP_EX_INEXACT |
#define FP_EX_INEXACT 0 |
#endif |
#ifndef FP_EX_DENORM |
#define FP_EX_DENORM 0 |
#endif |
|
#ifdef _FP_DECL_EX |
#define FP_DECL_EX \ |
int _fex = 0; \ |
_FP_DECL_EX |
#else |
#define FP_DECL_EX int _fex = 0 |
#endif |
|
#ifndef FP_INIT_ROUNDMODE |
#define FP_INIT_ROUNDMODE do {} while (0) |
#endif |
|
#ifndef FP_HANDLE_EXCEPTIONS |
#define FP_HANDLE_EXCEPTIONS do {} while (0) |
#endif |
|
#ifndef FP_INHIBIT_RESULTS |
/* By default we write the results always. |
* sfp-machine may override this and e.g. |
* check if some exceptions are unmasked |
* and inhibit it in such a case. |
*/ |
#define FP_INHIBIT_RESULTS 0 |
#endif |
|
#define FP_SET_EXCEPTION(ex) \ |
_fex |= (ex) |
|
#define FP_UNSET_EXCEPTION(ex) \ |
_fex &= ~(ex) |
|
#define FP_CLEAR_EXCEPTIONS \ |
_fex = 0 |
|
#define _FP_ROUND_NEAREST(wc, X) \ |
do { \ |
if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \ |
_FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ |
} while (0) |
|
#define _FP_ROUND_ZERO(wc, X) (void)0 |
|
#define _FP_ROUND_PINF(wc, X) \ |
do { \ |
if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ |
_FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ |
} while (0) |
|
#define _FP_ROUND_MINF(wc, X) \ |
do { \ |
if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ |
_FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ |
} while (0) |
|
#define _FP_ROUND(wc, X) \ |
do { \ |
if (_FP_FRAC_LOW_##wc(X) & 7) \ |
FP_SET_EXCEPTION(FP_EX_INEXACT); \ |
switch (FP_ROUNDMODE) \ |
{ \ |
case FP_RND_NEAREST: \ |
_FP_ROUND_NEAREST(wc,X); \ |
break; \ |
case FP_RND_ZERO: \ |
_FP_ROUND_ZERO(wc,X); \ |
break; \ |
case FP_RND_PINF: \ |
_FP_ROUND_PINF(wc,X); \ |
break; \ |
case FP_RND_MINF: \ |
_FP_ROUND_MINF(wc,X); \ |
break; \ |
} \ |
} while (0) |
|
#define FP_CLS_NORMAL 0 |
#define FP_CLS_ZERO 1 |
#define FP_CLS_INF 2 |
#define FP_CLS_NAN 3 |
|
#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y)) |
|
#include "op-1.h" |
#include "op-2.h" |
#include "op-4.h" |
#include "op-8.h" |
#include "op-common.h" |
|
/* Sigh. Silly things longlong.h needs. */ |
#define UWtype _FP_W_TYPE |
#define W_TYPE_SIZE _FP_W_TYPE_SIZE |
|
typedef int QItype __attribute__((mode(QI))); |
typedef int SItype __attribute__((mode(SI))); |
typedef int DItype __attribute__((mode(DI))); |
typedef unsigned int UQItype __attribute__((mode(QI))); |
typedef unsigned int USItype __attribute__((mode(SI))); |
typedef unsigned int UDItype __attribute__((mode(DI))); |
#if _FP_W_TYPE_SIZE == 32 |
typedef unsigned int UHWtype __attribute__((mode(HI))); |
#elif _FP_W_TYPE_SIZE == 64 |
typedef USItype UHWtype; |
#endif |
|
#define SI_BITS (__CHAR_BIT__ * (int)sizeof(SItype)) |
#define DI_BITS (__CHAR_BIT__ * (int)sizeof(DItype)) |
|
#ifndef umul_ppmm |
#ifdef _LIBC |
#include <stdlib/longlong.h> |
#else |
#include "longlong.h" |
#endif |
#endif |
|
#ifdef _LIBC |
#include <stdlib.h> |
#else |
extern void abort (void); |
#endif |
|
#endif |
/unorddf2.c
0,0 → 1,45
/* Software floating-point emulation. |
Return 1 iff a or b is a NaN, 0 otherwise. |
Copyright (C) 2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Joseph Myers (joseph@codesourcery.com). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
int |
__unorddf2(DFtype a, DFtype b) |
{ |
FP_DECL_D(A); FP_DECL_D(B); |
int r; |
|
FP_UNPACK_RAW_D(A, a); |
FP_UNPACK_RAW_D(B, b); |
FP_CMP_UNORD_D(r, A, B); |
|
return r; |
} |
/floatsisf.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a 32bit signed integer to IEEE single |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "single.h" |
|
SFtype __floatsisf(SItype i) |
{ |
FP_DECL_EX; |
FP_DECL_S(A); |
SFtype a; |
|
FP_FROM_INT_S(A, i, SI_BITS, USItype); |
FP_PACK_RAW_S(a, A); |
FP_HANDLE_EXCEPTIONS; |
|
return a; |
} |
/ledf2.c
0,0 → 1,51
/* Software floating-point emulation. |
Return 0 iff a == b, 1 iff a > b, 2 iff a ? b, -1 iff a < b |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
int __ledf2(DFtype a, DFtype b) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); FP_DECL_D(B); |
int r; |
|
FP_UNPACK_RAW_D(A, a); |
FP_UNPACK_RAW_D(B, b); |
FP_CMP_D(r, A, B, 2); |
if (r == 2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))) |
FP_SET_EXCEPTION(FP_EX_INVALID); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |
|
strong_alias(__ledf2, __ltdf2); |
/fixdfsi.c
0,0 → 1,46
/* Software floating-point emulation. |
Convert a to 32bit signed integer |
Copyright (C) 1997,1999,2006 Free Software Foundation, Inc. |
This file is part of the GNU C Library. |
Contributed by Richard Henderson (rth@cygnus.com) and |
Jakub Jelinek (jj@ultra.linux.cz). |
|
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. |
|
In addition to the permissions in the GNU Lesser General Public |
License, the Free Software Foundation gives you unlimited |
permission to link the compiled version of this file into |
combinations with other programs, and to distribute those |
combinations without any restriction coming from the use of this |
file. (The Lesser General Public License restrictions do apply in |
other respects; for example, they cover modification of the file, |
and distribution when not linked into a combine executable.) |
|
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, 51 Franklin Street, Fifth Floor, Boston, |
MA 02110-1301, USA. */ |
|
#include "soft-fp.h" |
#include "double.h" |
|
SItype __fixdfsi(DFtype a) |
{ |
FP_DECL_EX; |
FP_DECL_D(A); |
USItype r; |
|
FP_UNPACK_RAW_D(A, a); |
FP_TO_INT_D(r, A, SI_BITS, 1); |
FP_HANDLE_EXCEPTIONS; |
|
return r; |
} |