1169689Skan/* Software floating-point emulation. 2169689Skan Definitions for IEEE Double Precision 3171825Skan Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. 4169689Skan This file is part of the GNU C Library. 5169689Skan Contributed by Richard Henderson (rth@cygnus.com), 6169689Skan Jakub Jelinek (jj@ultra.linux.cz), 7169689Skan David S. Miller (davem@redhat.com) and 8169689Skan Peter Maydell (pmaydell@chiark.greenend.org.uk). 9169689Skan 10169689Skan The GNU C Library is free software; you can redistribute it and/or 11169689Skan modify it under the terms of the GNU Lesser General Public 12169689Skan License as published by the Free Software Foundation; either 13169689Skan version 2.1 of the License, or (at your option) any later version. 14169689Skan 15169689Skan In addition to the permissions in the GNU Lesser General Public 16169689Skan License, the Free Software Foundation gives you unlimited 17169689Skan permission to link the compiled version of this file into 18169689Skan combinations with other programs, and to distribute those 19169689Skan combinations without any restriction coming from the use of this 20169689Skan file. (The Lesser General Public License restrictions do apply in 21169689Skan other respects; for example, they cover modification of the file, 22169689Skan and distribution when not linked into a combine executable.) 23169689Skan 24169689Skan The GNU C Library is distributed in the hope that it will be useful, 25169689Skan but WITHOUT ANY WARRANTY; without even the implied warranty of 26169689Skan MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 27169689Skan Lesser General Public License for more details. 28169689Skan 29169689Skan You should have received a copy of the GNU Lesser General Public 30169689Skan License along with the GNU C Library; if not, write to the Free 31169689Skan Software Foundation, 51 Franklin Street, Fifth Floor, Boston, 32169689Skan MA 02110-1301, USA. */ 33169689Skan 34169689Skan#if _FP_W_TYPE_SIZE < 32 35169689Skan#error "Here's a nickel kid. Go buy yourself a real computer." 36169689Skan#endif 37169689Skan 38169689Skan#if _FP_W_TYPE_SIZE < 64 39169689Skan#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE) 40169689Skan#else 41169689Skan#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE 42169689Skan#endif 43169689Skan 44169689Skan#define _FP_FRACBITS_D 53 45169689Skan#define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D) 46169689Skan#define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D) 47169689Skan#define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D) 48169689Skan#define _FP_EXPBITS_D 11 49169689Skan#define _FP_EXPBIAS_D 1023 50169689Skan#define _FP_EXPMAX_D 2047 51169689Skan 52169689Skan#define _FP_QNANBIT_D \ 53169689Skan ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE) 54169689Skan#define _FP_QNANBIT_SH_D \ 55169689Skan ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) 56169689Skan#define _FP_IMPLBIT_D \ 57169689Skan ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE) 58169689Skan#define _FP_IMPLBIT_SH_D \ 59169689Skan ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) 60169689Skan#define _FP_OVERFLOW_D \ 61169689Skan ((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE) 62169689Skan 63169689Skantypedef float DFtype __attribute__((mode(DF))); 64169689Skan 65169689Skan#if _FP_W_TYPE_SIZE < 64 66169689Skan 67169689Skanunion _FP_UNION_D 68169689Skan{ 69169689Skan DFtype flt; 70169689Skan struct { 71169689Skan#if __BYTE_ORDER == __BIG_ENDIAN 72169689Skan unsigned sign : 1; 73169689Skan unsigned exp : _FP_EXPBITS_D; 74169689Skan unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; 75169689Skan unsigned frac0 : _FP_W_TYPE_SIZE; 76169689Skan#else 77169689Skan unsigned frac0 : _FP_W_TYPE_SIZE; 78169689Skan unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; 79169689Skan unsigned exp : _FP_EXPBITS_D; 80169689Skan unsigned sign : 1; 81169689Skan#endif 82169689Skan } bits __attribute__((packed)); 83169689Skan}; 84169689Skan 85169689Skan#define FP_DECL_D(X) _FP_DECL(2,X) 86169689Skan#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val) 87169689Skan#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_2_P(D,X,val) 88169689Skan#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X) 89169689Skan#define FP_PACK_RAW_DP(val,X) \ 90169689Skan do { \ 91169689Skan if (!FP_INHIBIT_RESULTS) \ 92169689Skan _FP_PACK_RAW_2_P(D,val,X); \ 93169689Skan } while (0) 94169689Skan 95169689Skan#define FP_UNPACK_D(X,val) \ 96169689Skan do { \ 97169689Skan _FP_UNPACK_RAW_2(D,X,val); \ 98169689Skan _FP_UNPACK_CANONICAL(D,2,X); \ 99169689Skan } while (0) 100169689Skan 101169689Skan#define FP_UNPACK_DP(X,val) \ 102169689Skan do { \ 103169689Skan _FP_UNPACK_RAW_2_P(D,X,val); \ 104169689Skan _FP_UNPACK_CANONICAL(D,2,X); \ 105169689Skan } while (0) 106169689Skan 107169689Skan#define FP_UNPACK_SEMIRAW_D(X,val) \ 108169689Skan do { \ 109169689Skan _FP_UNPACK_RAW_2(D,X,val); \ 110169689Skan _FP_UNPACK_SEMIRAW(D,2,X); \ 111169689Skan } while (0) 112169689Skan 113169689Skan#define FP_UNPACK_SEMIRAW_DP(X,val) \ 114169689Skan do { \ 115169689Skan _FP_UNPACK_RAW_2_P(D,X,val); \ 116169689Skan _FP_UNPACK_SEMIRAW(D,2,X); \ 117169689Skan } while (0) 118169689Skan 119169689Skan#define FP_PACK_D(val,X) \ 120169689Skan do { \ 121169689Skan _FP_PACK_CANONICAL(D,2,X); \ 122169689Skan _FP_PACK_RAW_2(D,val,X); \ 123169689Skan } while (0) 124169689Skan 125169689Skan#define FP_PACK_DP(val,X) \ 126169689Skan do { \ 127169689Skan _FP_PACK_CANONICAL(D,2,X); \ 128169689Skan if (!FP_INHIBIT_RESULTS) \ 129169689Skan _FP_PACK_RAW_2_P(D,val,X); \ 130169689Skan } while (0) 131169689Skan 132169689Skan#define FP_PACK_SEMIRAW_D(val,X) \ 133169689Skan do { \ 134169689Skan _FP_PACK_SEMIRAW(D,2,X); \ 135169689Skan _FP_PACK_RAW_2(D,val,X); \ 136169689Skan } while (0) 137169689Skan 138169689Skan#define FP_PACK_SEMIRAW_DP(val,X) \ 139169689Skan do { \ 140169689Skan _FP_PACK_SEMIRAW(D,2,X); \ 141169689Skan if (!FP_INHIBIT_RESULTS) \ 142169689Skan _FP_PACK_RAW_2_P(D,val,X); \ 143169689Skan } while (0) 144169689Skan 145169689Skan#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,2,X) 146169689Skan#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X) 147169689Skan#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y) 148169689Skan#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y) 149169689Skan#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y) 150169689Skan#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y) 151169689Skan#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X) 152169689Skan#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) 153169689Skan 154169689Skan#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un) 155169689Skan#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y) 156169689Skan#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,2,r,X,Y) 157169689Skan 158169689Skan#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg) 159169689Skan#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt) 160169689Skan 161169689Skan#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2(X) 162169689Skan#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2(X) 163169689Skan 164169689Skan#else 165169689Skan 166169689Skanunion _FP_UNION_D 167169689Skan{ 168169689Skan DFtype flt; 169169689Skan struct { 170169689Skan#if __BYTE_ORDER == __BIG_ENDIAN 171171825Skan unsigned sign : 1; 172171825Skan unsigned exp : _FP_EXPBITS_D; 173171825Skan _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); 174169689Skan#else 175171825Skan _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); 176171825Skan unsigned exp : _FP_EXPBITS_D; 177171825Skan unsigned sign : 1; 178169689Skan#endif 179169689Skan } bits __attribute__((packed)); 180169689Skan}; 181169689Skan 182169689Skan#define FP_DECL_D(X) _FP_DECL(1,X) 183169689Skan#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val) 184169689Skan#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_1_P(D,X,val) 185169689Skan#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X) 186169689Skan#define FP_PACK_RAW_DP(val,X) \ 187169689Skan do { \ 188169689Skan if (!FP_INHIBIT_RESULTS) \ 189169689Skan _FP_PACK_RAW_1_P(D,val,X); \ 190169689Skan } while (0) 191169689Skan 192169689Skan#define FP_UNPACK_D(X,val) \ 193169689Skan do { \ 194169689Skan _FP_UNPACK_RAW_1(D,X,val); \ 195169689Skan _FP_UNPACK_CANONICAL(D,1,X); \ 196169689Skan } while (0) 197169689Skan 198169689Skan#define FP_UNPACK_DP(X,val) \ 199169689Skan do { \ 200169689Skan _FP_UNPACK_RAW_1_P(D,X,val); \ 201169689Skan _FP_UNPACK_CANONICAL(D,1,X); \ 202169689Skan } while (0) 203169689Skan 204169689Skan#define FP_UNPACK_SEMIRAW_D(X,val) \ 205169689Skan do { \ 206169689Skan _FP_UNPACK_RAW_2(1,X,val); \ 207169689Skan _FP_UNPACK_SEMIRAW(D,1,X); \ 208169689Skan } while (0) 209169689Skan 210169689Skan#define FP_UNPACK_SEMIRAW_DP(X,val) \ 211169689Skan do { \ 212169689Skan _FP_UNPACK_RAW_2_P(1,X,val); \ 213169689Skan _FP_UNPACK_SEMIRAW(D,1,X); \ 214169689Skan } while (0) 215169689Skan 216169689Skan#define FP_PACK_D(val,X) \ 217169689Skan do { \ 218169689Skan _FP_PACK_CANONICAL(D,1,X); \ 219169689Skan _FP_PACK_RAW_1(D,val,X); \ 220169689Skan } while (0) 221169689Skan 222169689Skan#define FP_PACK_DP(val,X) \ 223169689Skan do { \ 224169689Skan _FP_PACK_CANONICAL(D,1,X); \ 225169689Skan if (!FP_INHIBIT_RESULTS) \ 226169689Skan _FP_PACK_RAW_1_P(D,val,X); \ 227169689Skan } while (0) 228169689Skan 229169689Skan#define FP_PACK_SEMIRAW_D(val,X) \ 230169689Skan do { \ 231169689Skan _FP_PACK_SEMIRAW(D,1,X); \ 232169689Skan _FP_PACK_RAW_1(D,val,X); \ 233169689Skan } while (0) 234169689Skan 235169689Skan#define FP_PACK_SEMIRAW_DP(val,X) \ 236169689Skan do { \ 237169689Skan _FP_PACK_SEMIRAW(D,1,X); \ 238169689Skan if (!FP_INHIBIT_RESULTS) \ 239169689Skan _FP_PACK_RAW_1_P(D,val,X); \ 240169689Skan } while (0) 241169689Skan 242169689Skan#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,1,X) 243169689Skan#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X) 244169689Skan#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y) 245169689Skan#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y) 246169689Skan#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y) 247169689Skan#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y) 248169689Skan#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X) 249169689Skan#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) 250169689Skan 251169689Skan/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by 252169689Skan the target machine. */ 253169689Skan 254169689Skan#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un) 255169689Skan#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y) 256169689Skan#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,1,r,X,Y) 257169689Skan 258169689Skan#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg) 259169689Skan#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt) 260169689Skan 261169689Skan#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1(X) 262169689Skan#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1(X) 263169689Skan 264169689Skan#endif /* W_TYPE_SIZE < 64 */ 265