1169689Skan/* Software floating-point emulation. 2169689Skan Definitions for IEEE Quad 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_Q (4*_FP_W_TYPE_SIZE) 40169689Skan#else 41169689Skan#define _FP_FRACTBITS_Q (2*_FP_W_TYPE_SIZE) 42169689Skan#endif 43169689Skan 44169689Skan#define _FP_FRACBITS_Q 113 45169689Skan#define _FP_FRACXBITS_Q (_FP_FRACTBITS_Q - _FP_FRACBITS_Q) 46169689Skan#define _FP_WFRACBITS_Q (_FP_WORKBITS + _FP_FRACBITS_Q) 47169689Skan#define _FP_WFRACXBITS_Q (_FP_FRACTBITS_Q - _FP_WFRACBITS_Q) 48169689Skan#define _FP_EXPBITS_Q 15 49169689Skan#define _FP_EXPBIAS_Q 16383 50169689Skan#define _FP_EXPMAX_Q 32767 51169689Skan 52169689Skan#define _FP_QNANBIT_Q \ 53169689Skan ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE) 54169689Skan#define _FP_QNANBIT_SH_Q \ 55169689Skan ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) 56169689Skan#define _FP_IMPLBIT_Q \ 57169689Skan ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE) 58169689Skan#define _FP_IMPLBIT_SH_Q \ 59169689Skan ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) 60169689Skan#define _FP_OVERFLOW_Q \ 61169689Skan ((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE)) 62169689Skan 63169689Skantypedef float TFtype __attribute__((mode(TF))); 64169689Skan 65169689Skan#if _FP_W_TYPE_SIZE < 64 66169689Skan 67169689Skanunion _FP_UNION_Q 68169689Skan{ 69169689Skan TFtype flt; 70169689Skan struct 71169689Skan { 72169689Skan#if __BYTE_ORDER == __BIG_ENDIAN 73169689Skan unsigned sign : 1; 74169689Skan unsigned exp : _FP_EXPBITS_Q; 75169689Skan unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); 76169689Skan unsigned long frac2 : _FP_W_TYPE_SIZE; 77169689Skan unsigned long frac1 : _FP_W_TYPE_SIZE; 78169689Skan unsigned long frac0 : _FP_W_TYPE_SIZE; 79169689Skan#else 80169689Skan unsigned long frac0 : _FP_W_TYPE_SIZE; 81169689Skan unsigned long frac1 : _FP_W_TYPE_SIZE; 82169689Skan unsigned long frac2 : _FP_W_TYPE_SIZE; 83169689Skan unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); 84169689Skan unsigned exp : _FP_EXPBITS_Q; 85169689Skan unsigned sign : 1; 86169689Skan#endif /* not bigendian */ 87169689Skan } bits __attribute__((packed)); 88169689Skan}; 89169689Skan 90169689Skan 91169689Skan#define FP_DECL_Q(X) _FP_DECL(4,X) 92169689Skan#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_4(Q,X,val) 93169689Skan#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_4_P(Q,X,val) 94169689Skan#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_4(Q,val,X) 95169689Skan#define FP_PACK_RAW_QP(val,X) \ 96169689Skan do { \ 97169689Skan if (!FP_INHIBIT_RESULTS) \ 98169689Skan _FP_PACK_RAW_4_P(Q,val,X); \ 99169689Skan } while (0) 100169689Skan 101169689Skan#define FP_UNPACK_Q(X,val) \ 102169689Skan do { \ 103169689Skan _FP_UNPACK_RAW_4(Q,X,val); \ 104169689Skan _FP_UNPACK_CANONICAL(Q,4,X); \ 105169689Skan } while (0) 106169689Skan 107169689Skan#define FP_UNPACK_QP(X,val) \ 108169689Skan do { \ 109169689Skan _FP_UNPACK_RAW_4_P(Q,X,val); \ 110169689Skan _FP_UNPACK_CANONICAL(Q,4,X); \ 111169689Skan } while (0) 112169689Skan 113169689Skan#define FP_UNPACK_SEMIRAW_Q(X,val) \ 114169689Skan do { \ 115169689Skan _FP_UNPACK_RAW_4(Q,X,val); \ 116169689Skan _FP_UNPACK_SEMIRAW(Q,4,X); \ 117169689Skan } while (0) 118169689Skan 119169689Skan#define FP_UNPACK_SEMIRAW_QP(X,val) \ 120169689Skan do { \ 121169689Skan _FP_UNPACK_RAW_4_P(Q,X,val); \ 122169689Skan _FP_UNPACK_SEMIRAW(Q,4,X); \ 123169689Skan } while (0) 124169689Skan 125169689Skan#define FP_PACK_Q(val,X) \ 126169689Skan do { \ 127169689Skan _FP_PACK_CANONICAL(Q,4,X); \ 128169689Skan _FP_PACK_RAW_4(Q,val,X); \ 129169689Skan } while (0) 130169689Skan 131169689Skan#define FP_PACK_QP(val,X) \ 132169689Skan do { \ 133169689Skan _FP_PACK_CANONICAL(Q,4,X); \ 134169689Skan if (!FP_INHIBIT_RESULTS) \ 135169689Skan _FP_PACK_RAW_4_P(Q,val,X); \ 136169689Skan } while (0) 137169689Skan 138169689Skan#define FP_PACK_SEMIRAW_Q(val,X) \ 139169689Skan do { \ 140169689Skan _FP_PACK_SEMIRAW(Q,4,X); \ 141169689Skan _FP_PACK_RAW_4(Q,val,X); \ 142169689Skan } while (0) 143169689Skan 144169689Skan#define FP_PACK_SEMIRAW_QP(val,X) \ 145169689Skan do { \ 146169689Skan _FP_PACK_SEMIRAW(Q,4,X); \ 147169689Skan if (!FP_INHIBIT_RESULTS) \ 148169689Skan _FP_PACK_RAW_4_P(Q,val,X); \ 149169689Skan } while (0) 150169689Skan 151169689Skan#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,4,X) 152169689Skan#define FP_NEG_Q(R,X) _FP_NEG(Q,4,R,X) 153169689Skan#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,4,R,X,Y) 154169689Skan#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,4,R,X,Y) 155169689Skan#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,4,R,X,Y) 156169689Skan#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,4,R,X,Y) 157169689Skan#define FP_SQRT_Q(R,X) _FP_SQRT(Q,4,R,X) 158169689Skan#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_4(R,S,T,X,Q) 159169689Skan 160169689Skan#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,4,r,X,Y,un) 161169689Skan#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,4,r,X,Y) 162169689Skan#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,4,r,X,Y) 163169689Skan 164169689Skan#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,4,r,X,rsz,rsg) 165169689Skan#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,4,X,r,rs,rt) 166169689Skan 167169689Skan#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_4(X) 168169689Skan#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_4(X) 169169689Skan 170169689Skan#else /* not _FP_W_TYPE_SIZE < 64 */ 171169689Skanunion _FP_UNION_Q 172169689Skan{ 173169689Skan TFtype flt /* __attribute__((mode(TF))) */ ; 174169689Skan struct { 175169689Skan _FP_W_TYPE a, b; 176169689Skan } longs; 177169689Skan struct { 178169689Skan#if __BYTE_ORDER == __BIG_ENDIAN 179171825Skan unsigned sign : 1; 180171825Skan unsigned exp : _FP_EXPBITS_Q; 181171825Skan _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; 182171825Skan _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; 183169689Skan#else 184171825Skan _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; 185171825Skan _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; 186171825Skan unsigned exp : _FP_EXPBITS_Q; 187171825Skan unsigned sign : 1; 188169689Skan#endif 189169689Skan } bits; 190169689Skan}; 191169689Skan 192169689Skan#define FP_DECL_Q(X) _FP_DECL(2,X) 193169689Skan#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_2(Q,X,val) 194169689Skan#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_2_P(Q,X,val) 195169689Skan#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_2(Q,val,X) 196169689Skan#define FP_PACK_RAW_QP(val,X) \ 197169689Skan do { \ 198169689Skan if (!FP_INHIBIT_RESULTS) \ 199169689Skan _FP_PACK_RAW_2_P(Q,val,X); \ 200169689Skan } while (0) 201169689Skan 202169689Skan#define FP_UNPACK_Q(X,val) \ 203169689Skan do { \ 204169689Skan _FP_UNPACK_RAW_2(Q,X,val); \ 205169689Skan _FP_UNPACK_CANONICAL(Q,2,X); \ 206169689Skan } while (0) 207169689Skan 208169689Skan#define FP_UNPACK_QP(X,val) \ 209169689Skan do { \ 210169689Skan _FP_UNPACK_RAW_2_P(Q,X,val); \ 211169689Skan _FP_UNPACK_CANONICAL(Q,2,X); \ 212169689Skan } while (0) 213169689Skan 214169689Skan#define FP_UNPACK_SEMIRAW_Q(X,val) \ 215169689Skan do { \ 216169689Skan _FP_UNPACK_RAW_2(Q,X,val); \ 217169689Skan _FP_UNPACK_SEMIRAW(Q,2,X); \ 218169689Skan } while (0) 219169689Skan 220169689Skan#define FP_UNPACK_SEMIRAW_QP(X,val) \ 221169689Skan do { \ 222169689Skan _FP_UNPACK_RAW_2_P(Q,X,val); \ 223169689Skan _FP_UNPACK_SEMIRAW(Q,2,X); \ 224169689Skan } while (0) 225169689Skan 226169689Skan#define FP_PACK_Q(val,X) \ 227169689Skan do { \ 228169689Skan _FP_PACK_CANONICAL(Q,2,X); \ 229169689Skan _FP_PACK_RAW_2(Q,val,X); \ 230169689Skan } while (0) 231169689Skan 232169689Skan#define FP_PACK_QP(val,X) \ 233169689Skan do { \ 234169689Skan _FP_PACK_CANONICAL(Q,2,X); \ 235169689Skan if (!FP_INHIBIT_RESULTS) \ 236169689Skan _FP_PACK_RAW_2_P(Q,val,X); \ 237169689Skan } while (0) 238169689Skan 239169689Skan#define FP_PACK_SEMIRAW_Q(val,X) \ 240169689Skan do { \ 241169689Skan _FP_PACK_SEMIRAW(Q,2,X); \ 242169689Skan _FP_PACK_RAW_2(Q,val,X); \ 243169689Skan } while (0) 244169689Skan 245169689Skan#define FP_PACK_SEMIRAW_QP(val,X) \ 246169689Skan do { \ 247169689Skan _FP_PACK_SEMIRAW(Q,2,X); \ 248169689Skan if (!FP_INHIBIT_RESULTS) \ 249169689Skan _FP_PACK_RAW_2_P(Q,val,X); \ 250169689Skan } while (0) 251169689Skan 252169689Skan#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,2,X) 253169689Skan#define FP_NEG_Q(R,X) _FP_NEG(Q,2,R,X) 254169689Skan#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,2,R,X,Y) 255169689Skan#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,2,R,X,Y) 256169689Skan#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,2,R,X,Y) 257169689Skan#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,2,R,X,Y) 258169689Skan#define FP_SQRT_Q(R,X) _FP_SQRT(Q,2,R,X) 259169689Skan#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) 260169689Skan 261169689Skan#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,2,r,X,Y,un) 262169689Skan#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,2,r,X,Y) 263169689Skan#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,2,r,X,Y) 264169689Skan 265169689Skan#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,2,r,X,rsz,rsg) 266169689Skan#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,2,X,r,rs,rt) 267169689Skan 268169689Skan#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_2(X) 269169689Skan#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_2(X) 270169689Skan 271169689Skan#endif /* not _FP_W_TYPE_SIZE < 64 */ 272