1226031Sstas/* Software floating-point emulation. 2226031Sstas Definitions for IEEE Double Precision 3226031Sstas Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. 4226031Sstas This file is part of the GNU C Library. 5226031Sstas Contributed by Richard Henderson (rth@cygnus.com), 6226031Sstas Jakub Jelinek (jj@ultra.linux.cz), 7226031Sstas David S. Miller (davem@redhat.com) and 8226031Sstas Peter Maydell (pmaydell@chiark.greenend.org.uk). 9226031Sstas 10226031Sstas The GNU C Library is free software; you can redistribute it and/or 11226031Sstas modify it under the terms of the GNU Lesser General Public 12226031Sstas License as published by the Free Software Foundation; either 13226031Sstas version 2.1 of the License, or (at your option) any later version. 14226031Sstas 15226031Sstas In addition to the permissions in the GNU Lesser General Public 16226031Sstas License, the Free Software Foundation gives you unlimited 17226031Sstas permission to link the compiled version of this file into 18226031Sstas combinations with other programs, and to distribute those 19226031Sstas combinations without any restriction coming from the use of this 20226031Sstas file. (The Lesser General Public License restrictions do apply in 21226031Sstas other respects; for example, they cover modification of the file, 22226031Sstas and distribution when not linked into a combine executable.) 23226031Sstas 24226031Sstas The GNU C Library is distributed in the hope that it will be useful, 25226031Sstas but WITHOUT ANY WARRANTY; without even the implied warranty of 26226031Sstas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 27226031Sstas Lesser General Public License for more details. 28226031Sstas 29226031Sstas You should have received a copy of the GNU Lesser General Public 30226031Sstas License along with the GNU C Library; if not, write to the Free 31226031Sstas Software Foundation, 51 Franklin Street, Fifth Floor, Boston, 32226031Sstas MA 02110-1301, USA. */ 33226031Sstas 34226031Sstas#if _FP_W_TYPE_SIZE < 32 35226031Sstas#error "Here's a nickel kid. Go buy yourself a real computer." 36226031Sstas#endif 37226031Sstas 38226031Sstas#if _FP_W_TYPE_SIZE < 64 39226031Sstas#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE) 40226031Sstas#else 41226031Sstas#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE 42226031Sstas#endif 43226031Sstas 44226031Sstas#define _FP_FRACBITS_D 53 45226031Sstas#define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D) 46226031Sstas#define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D) 47226031Sstas#define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D) 48226031Sstas#define _FP_EXPBITS_D 11 49226031Sstas#define _FP_EXPBIAS_D 1023 50226031Sstas#define _FP_EXPMAX_D 2047 51226031Sstas 52226031Sstas#define _FP_QNANBIT_D \ 53226031Sstas ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE) 54226031Sstas#define _FP_QNANBIT_SH_D \ 55226031Sstas ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) 56226031Sstas#define _FP_IMPLBIT_D \ 57226031Sstas ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE) 58226031Sstas#define _FP_IMPLBIT_SH_D \ 59226031Sstas ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) 60226031Sstas#define _FP_OVERFLOW_D \ 61226031Sstas ((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE) 62226031Sstas 63226031Sstastypedef float DFtype __attribute__((mode(DF))); 64226031Sstas 65226031Sstas#if _FP_W_TYPE_SIZE < 64 66226031Sstas 67226031Sstasunion _FP_UNION_D 68226031Sstas{ 69226031Sstas DFtype flt; 70226031Sstas struct { 71226031Sstas#if __BYTE_ORDER == __BIG_ENDIAN 72226031Sstas unsigned sign : 1; 73226031Sstas unsigned exp : _FP_EXPBITS_D; 74226031Sstas unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; 75226031Sstas unsigned frac0 : _FP_W_TYPE_SIZE; 76226031Sstas#else 77226031Sstas unsigned frac0 : _FP_W_TYPE_SIZE; 78226031Sstas unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; 79226031Sstas unsigned exp : _FP_EXPBITS_D; 80226031Sstas unsigned sign : 1; 81226031Sstas#endif 82226031Sstas } bits __attribute__((packed)); 83226031Sstas}; 84226031Sstas 85226031Sstas#define FP_DECL_D(X) _FP_DECL(2,X) 86226031Sstas#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val) 87226031Sstas#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_2_P(D,X,val) 88226031Sstas#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X) 89226031Sstas#define FP_PACK_RAW_DP(val,X) \ 90226031Sstas do { \ 91226031Sstas if (!FP_INHIBIT_RESULTS) \ 92226031Sstas _FP_PACK_RAW_2_P(D,val,X); \ 93226031Sstas } while (0) 94226031Sstas 95226031Sstas#define FP_UNPACK_D(X,val) \ 96226031Sstas do { \ 97226031Sstas _FP_UNPACK_RAW_2(D,X,val); \ 98226031Sstas _FP_UNPACK_CANONICAL(D,2,X); \ 99226031Sstas } while (0) 100226031Sstas 101226031Sstas#define FP_UNPACK_DP(X,val) \ 102226031Sstas do { \ 103226031Sstas _FP_UNPACK_RAW_2_P(D,X,val); \ 104226031Sstas _FP_UNPACK_CANONICAL(D,2,X); \ 105226031Sstas } while (0) 106226031Sstas 107226031Sstas#define FP_UNPACK_SEMIRAW_D(X,val) \ 108226031Sstas do { \ 109226031Sstas _FP_UNPACK_RAW_2(D,X,val); \ 110226031Sstas _FP_UNPACK_SEMIRAW(D,2,X); \ 111226031Sstas } while (0) 112226031Sstas 113226031Sstas#define FP_UNPACK_SEMIRAW_DP(X,val) \ 114226031Sstas do { \ 115226031Sstas _FP_UNPACK_RAW_2_P(D,X,val); \ 116226031Sstas _FP_UNPACK_SEMIRAW(D,2,X); \ 117226031Sstas } while (0) 118226031Sstas 119226031Sstas#define FP_PACK_D(val,X) \ 120226031Sstas do { \ 121226031Sstas _FP_PACK_CANONICAL(D,2,X); \ 122226031Sstas _FP_PACK_RAW_2(D,val,X); \ 123226031Sstas } while (0) 124226031Sstas 125226031Sstas#define FP_PACK_DP(val,X) \ 126226031Sstas do { \ 127226031Sstas _FP_PACK_CANONICAL(D,2,X); \ 128226031Sstas if (!FP_INHIBIT_RESULTS) \ 129226031Sstas _FP_PACK_RAW_2_P(D,val,X); \ 130226031Sstas } while (0) 131226031Sstas 132226031Sstas#define FP_PACK_SEMIRAW_D(val,X) \ 133226031Sstas do { \ 134226031Sstas _FP_PACK_SEMIRAW(D,2,X); \ 135226031Sstas _FP_PACK_RAW_2(D,val,X); \ 136226031Sstas } while (0) 137226031Sstas 138226031Sstas#define FP_PACK_SEMIRAW_DP(val,X) \ 139226031Sstas do { \ 140226031Sstas _FP_PACK_SEMIRAW(D,2,X); \ 141226031Sstas if (!FP_INHIBIT_RESULTS) \ 142226031Sstas _FP_PACK_RAW_2_P(D,val,X); \ 143226031Sstas } while (0) 144226031Sstas 145226031Sstas#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,2,X) 146226031Sstas#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X) 147226031Sstas#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y) 148226031Sstas#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y) 149226031Sstas#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y) 150226031Sstas#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y) 151226031Sstas#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X) 152226031Sstas#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) 153226031Sstas 154226031Sstas#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un) 155226031Sstas#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y) 156226031Sstas#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,2,r,X,Y) 157226031Sstas 158226031Sstas#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg) 159#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt) 160 161#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2(X) 162#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2(X) 163 164#else 165 166union _FP_UNION_D 167{ 168 DFtype flt; 169 struct { 170#if __BYTE_ORDER == __BIG_ENDIAN 171 unsigned sign : 1; 172 unsigned exp : _FP_EXPBITS_D; 173 _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); 174#else 175 _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); 176 unsigned exp : _FP_EXPBITS_D; 177 unsigned sign : 1; 178#endif 179 } bits __attribute__((packed)); 180}; 181 182#define FP_DECL_D(X) _FP_DECL(1,X) 183#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val) 184#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_1_P(D,X,val) 185#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X) 186#define FP_PACK_RAW_DP(val,X) \ 187 do { \ 188 if (!FP_INHIBIT_RESULTS) \ 189 _FP_PACK_RAW_1_P(D,val,X); \ 190 } while (0) 191 192#define FP_UNPACK_D(X,val) \ 193 do { \ 194 _FP_UNPACK_RAW_1(D,X,val); \ 195 _FP_UNPACK_CANONICAL(D,1,X); \ 196 } while (0) 197 198#define FP_UNPACK_DP(X,val) \ 199 do { \ 200 _FP_UNPACK_RAW_1_P(D,X,val); \ 201 _FP_UNPACK_CANONICAL(D,1,X); \ 202 } while (0) 203 204#define FP_UNPACK_SEMIRAW_D(X,val) \ 205 do { \ 206 _FP_UNPACK_RAW_2(1,X,val); \ 207 _FP_UNPACK_SEMIRAW(D,1,X); \ 208 } while (0) 209 210#define FP_UNPACK_SEMIRAW_DP(X,val) \ 211 do { \ 212 _FP_UNPACK_RAW_2_P(1,X,val); \ 213 _FP_UNPACK_SEMIRAW(D,1,X); \ 214 } while (0) 215 216#define FP_PACK_D(val,X) \ 217 do { \ 218 _FP_PACK_CANONICAL(D,1,X); \ 219 _FP_PACK_RAW_1(D,val,X); \ 220 } while (0) 221 222#define FP_PACK_DP(val,X) \ 223 do { \ 224 _FP_PACK_CANONICAL(D,1,X); \ 225 if (!FP_INHIBIT_RESULTS) \ 226 _FP_PACK_RAW_1_P(D,val,X); \ 227 } while (0) 228 229#define FP_PACK_SEMIRAW_D(val,X) \ 230 do { \ 231 _FP_PACK_SEMIRAW(D,1,X); \ 232 _FP_PACK_RAW_1(D,val,X); \ 233 } while (0) 234 235#define FP_PACK_SEMIRAW_DP(val,X) \ 236 do { \ 237 _FP_PACK_SEMIRAW(D,1,X); \ 238 if (!FP_INHIBIT_RESULTS) \ 239 _FP_PACK_RAW_1_P(D,val,X); \ 240 } while (0) 241 242#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,1,X) 243#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X) 244#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y) 245#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y) 246#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y) 247#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y) 248#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X) 249#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) 250 251/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by 252 the target machine. */ 253 254#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un) 255#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y) 256#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,1,r,X,Y) 257 258#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg) 259#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt) 260 261#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1(X) 262#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1(X) 263 264#endif /* W_TYPE_SIZE < 64 */ 265