1 /* Software floating-point emulation. 2 Definitions for IEEE Extended Precision. 3 Copyright (C) 1999 Free Software Foundation, Inc. 4 This file is part of the GNU C Library. 5 Contributed by Jakub Jelinek (jj@ultra.linux.cz). 6 7 The GNU C Library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Library General Public License as 9 published by the Free Software Foundation; either version 2 of the 10 License, or (at your option) any later version. 11 12 The GNU C Library is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Library General Public License for more details. 16 17 You should have received a copy of the GNU Library General Public 18 License along with the GNU C Library; see the file COPYING.LIB. If 19 not, write to the Free Software Foundation, Inc., 20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 21 22 23 #ifndef __MATH_EMU_EXTENDED_H__ 24 #define __MATH_EMU_EXTENDED_H__ 25 26 #if _FP_W_TYPE_SIZE < 32 27 #error "Here's a nickel, kid. Go buy yourself a real computer." 28 #endif 29 30 #if _FP_W_TYPE_SIZE < 64 31 #define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE) 32 #else 33 #define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE) 34 #endif 35 36 #define _FP_FRACBITS_E 64 37 #define _FP_FRACXBITS_E (_FP_FRACTBITS_E - _FP_FRACBITS_E) 38 #define _FP_WFRACBITS_E (_FP_WORKBITS + _FP_FRACBITS_E) 39 #define _FP_WFRACXBITS_E (_FP_FRACTBITS_E - _FP_WFRACBITS_E) 40 #define _FP_EXPBITS_E 15 41 #define _FP_EXPBIAS_E 16383 42 #define _FP_EXPMAX_E 32767 43 44 #define _FP_QNANBIT_E \ 45 ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE) 46 #define _FP_IMPLBIT_E \ 47 ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE) 48 #define _FP_OVERFLOW_E \ 49 ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE)) 50 51 #if _FP_W_TYPE_SIZE < 64 52 53 union _FP_UNION_E 54 { 55 long double flt; 56 struct 57 { 58 #if __BYTE_ORDER == __BIG_ENDIAN 59 unsigned long pad1 : _FP_W_TYPE_SIZE; 60 unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); 61 unsigned long sign : 1; 62 unsigned long exp : _FP_EXPBITS_E; 63 unsigned long frac1 : _FP_W_TYPE_SIZE; 64 unsigned long frac0 : _FP_W_TYPE_SIZE; 65 #else 66 unsigned long frac0 : _FP_W_TYPE_SIZE; 67 unsigned long frac1 : _FP_W_TYPE_SIZE; 68 unsigned exp : _FP_EXPBITS_E; 69 unsigned sign : 1; 70 #endif /* not bigendian */ 71 } bits __attribute__((packed)); 72 }; 73 74 75 #define FP_DECL_E(X) _FP_DECL(4,X) 76 77 #define FP_UNPACK_RAW_E(X, val) \ 78 do { \ 79 union _FP_UNION_E _flo; _flo.flt = (val); \ 80 \ 81 X##_f[2] = 0; X##_f[3] = 0; \ 82 X##_f[0] = _flo.bits.frac0; \ 83 X##_f[1] = _flo.bits.frac1; \ 84 X##_e = _flo.bits.exp; \ 85 X##_s = _flo.bits.sign; \ 86 if (!X##_e && (X##_f[1] || X##_f[0]) \ 87 && !(X##_f[1] & _FP_IMPLBIT_E)) \ 88 { \ 89 X##_e++; \ 90 FP_SET_EXCEPTION(FP_EX_DENORM); \ 91 } \ 92 } while (0) 93 94 #define FP_UNPACK_RAW_EP(X, val) \ 95 do { \ 96 union _FP_UNION_E *_flo = \ 97 (union _FP_UNION_E *)(val); \ 98 \ 99 X##_f[2] = 0; X##_f[3] = 0; \ 100 X##_f[0] = _flo->bits.frac0; \ 101 X##_f[1] = _flo->bits.frac1; \ 102 X##_e = _flo->bits.exp; \ 103 X##_s = _flo->bits.sign; \ 104 if (!X##_e && (X##_f[1] || X##_f[0]) \ 105 && !(X##_f[1] & _FP_IMPLBIT_E)) \ 106 { \ 107 X##_e++; \ 108 FP_SET_EXCEPTION(FP_EX_DENORM); \ 109 } \ 110 } while (0) 111 112 #define FP_PACK_RAW_E(val, X) \ 113 do { \ 114 union _FP_UNION_E _flo; \ 115 \ 116 if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ 117 else X##_f[1] &= ~(_FP_IMPLBIT_E); \ 118 _flo.bits.frac0 = X##_f[0]; \ 119 _flo.bits.frac1 = X##_f[1]; \ 120 _flo.bits.exp = X##_e; \ 121 _flo.bits.sign = X##_s; \ 122 \ 123 (val) = _flo.flt; \ 124 } while (0) 125 126 #define FP_PACK_RAW_EP(val, X) \ 127 do { \ 128 if (!FP_INHIBIT_RESULTS) \ 129 { \ 130 union _FP_UNION_E *_flo = \ 131 (union _FP_UNION_E *)(val); \ 132 \ 133 if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ 134 else X##_f[1] &= ~(_FP_IMPLBIT_E); \ 135 _flo->bits.frac0 = X##_f[0]; \ 136 _flo->bits.frac1 = X##_f[1]; \ 137 _flo->bits.exp = X##_e; \ 138 _flo->bits.sign = X##_s; \ 139 } \ 140 } while (0) 141 142 #define FP_UNPACK_E(X,val) \ 143 do { \ 144 FP_UNPACK_RAW_E(X,val); \ 145 _FP_UNPACK_CANONICAL(E,4,X); \ 146 } while (0) 147 148 #define FP_UNPACK_EP(X,val) \ 149 do { \ 150 FP_UNPACK_RAW_2_P(X,val); \ 151 _FP_UNPACK_CANONICAL(E,4,X); \ 152 } while (0) 153 154 #define FP_PACK_E(val,X) \ 155 do { \ 156 _FP_PACK_CANONICAL(E,4,X); \ 157 FP_PACK_RAW_E(val,X); \ 158 } while (0) 159 160 #define FP_PACK_EP(val,X) \ 161 do { \ 162 _FP_PACK_CANONICAL(E,4,X); \ 163 FP_PACK_RAW_EP(val,X); \ 164 } while (0) 165 166 #define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X) 167 #define FP_NEG_E(R,X) _FP_NEG(E,4,R,X) 168 #define FP_ADD_E(R,X,Y) _FP_ADD(E,4,R,X,Y) 169 #define FP_SUB_E(R,X,Y) _FP_SUB(E,4,R,X,Y) 170 #define FP_MUL_E(R,X,Y) _FP_MUL(E,4,R,X,Y) 171 #define FP_DIV_E(R,X,Y) _FP_DIV(E,4,R,X,Y) 172 #define FP_SQRT_E(R,X) _FP_SQRT(E,4,R,X) 173 174 /* 175 * Square root algorithms: 176 * We have just one right now, maybe Newton approximation 177 * should be added for those machines where division is fast. 178 * This has special _E version because standard _4 square 179 * root would not work (it has to start normally with the 180 * second word and not the first), but as we have to do it 181 * anyway, we optimize it by doing most of the calculations 182 * in two UWtype registers instead of four. 183 */ 184 185 #define _FP_SQRT_MEAT_E(R, S, T, X, q) \ 186 do { \ 187 q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ 188 _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \ 189 while (q) \ 190 { \ 191 T##_f[1] = S##_f[1] + q; \ 192 if (T##_f[1] <= X##_f[1]) \ 193 { \ 194 S##_f[1] = T##_f[1] + q; \ 195 X##_f[1] -= T##_f[1]; \ 196 R##_f[1] += q; \ 197 } \ 198 _FP_FRAC_SLL_2(X, 1); \ 199 q >>= 1; \ 200 } \ 201 q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ 202 while (q) \ 203 { \ 204 T##_f[0] = S##_f[0] + q; \ 205 T##_f[1] = S##_f[1]; \ 206 if (T##_f[1] < X##_f[1] || \ 207 (T##_f[1] == X##_f[1] && \ 208 T##_f[0] <= X##_f[0])) \ 209 { \ 210 S##_f[0] = T##_f[0] + q; \ 211 S##_f[1] += (T##_f[0] > S##_f[0]); \ 212 _FP_FRAC_DEC_2(X, T); \ 213 R##_f[0] += q; \ 214 } \ 215 _FP_FRAC_SLL_2(X, 1); \ 216 q >>= 1; \ 217 } \ 218 _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \ 219 if (X##_f[0] | X##_f[1]) \ 220 { \ 221 if (S##_f[1] < X##_f[1] || \ 222 (S##_f[1] == X##_f[1] && \ 223 S##_f[0] < X##_f[0])) \ 224 R##_f[0] |= _FP_WORK_ROUND; \ 225 R##_f[0] |= _FP_WORK_STICKY; \ 226 } \ 227 } while (0) 228 229 #define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un) 230 #define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y) 231 232 #define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg) 233 #define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,4,r,X,rsz,rsg) 234 #define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt) 235 236 #define _FP_FRAC_HIGH_E(X) (X##_f[2]) 237 #define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1]) 238 239 #else /* not _FP_W_TYPE_SIZE < 64 */ 240 union _FP_UNION_E 241 { 242 long double flt /* __attribute__((mode(TF))) */ ; 243 struct { 244 #if __BYTE_ORDER == __BIG_ENDIAN 245 unsigned long pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); 246 unsigned sign : 1; 247 unsigned exp : _FP_EXPBITS_E; 248 unsigned long frac : _FP_W_TYPE_SIZE; 249 #else 250 unsigned long frac : _FP_W_TYPE_SIZE; 251 unsigned exp : _FP_EXPBITS_E; 252 unsigned sign : 1; 253 #endif 254 } bits; 255 }; 256 257 #define FP_DECL_E(X) _FP_DECL(2,X) 258 259 #define FP_UNPACK_RAW_E(X, val) \ 260 do { \ 261 union _FP_UNION_E _flo; _flo.flt = (val); \ 262 \ 263 X##_f0 = _flo.bits.frac; \ 264 X##_f1 = 0; \ 265 X##_e = _flo.bits.exp; \ 266 X##_s = _flo.bits.sign; \ 267 if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \ 268 { \ 269 X##_e++; \ 270 FP_SET_EXCEPTION(FP_EX_DENORM); \ 271 } \ 272 } while (0) 273 274 #define FP_UNPACK_RAW_EP(X, val) \ 275 do { \ 276 union _FP_UNION_E *_flo = \ 277 (union _FP_UNION_E *)(val); \ 278 \ 279 X##_f0 = _flo->bits.frac; \ 280 X##_f1 = 0; \ 281 X##_e = _flo->bits.exp; \ 282 X##_s = _flo->bits.sign; \ 283 if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \ 284 { \ 285 X##_e++; \ 286 FP_SET_EXCEPTION(FP_EX_DENORM); \ 287 } \ 288 } while (0) 289 290 #define FP_PACK_RAW_E(val, X) \ 291 do { \ 292 union _FP_UNION_E _flo; \ 293 \ 294 if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ 295 else X##_f0 &= ~(_FP_IMPLBIT_E); \ 296 _flo.bits.frac = X##_f0; \ 297 _flo.bits.exp = X##_e; \ 298 _flo.bits.sign = X##_s; \ 299 \ 300 (val) = _flo.flt; \ 301 } while (0) 302 303 #define FP_PACK_RAW_EP(fs, val, X) \ 304 do { \ 305 if (!FP_INHIBIT_RESULTS) \ 306 { \ 307 union _FP_UNION_E *_flo = \ 308 (union _FP_UNION_E *)(val); \ 309 \ 310 if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ 311 else X##_f0 &= ~(_FP_IMPLBIT_E); \ 312 _flo->bits.frac = X##_f0; \ 313 _flo->bits.exp = X##_e; \ 314 _flo->bits.sign = X##_s; \ 315 } \ 316 } while (0) 317 318 319 #define FP_UNPACK_E(X,val) \ 320 do { \ 321 FP_UNPACK_RAW_E(X,val); \ 322 _FP_UNPACK_CANONICAL(E,2,X); \ 323 } while (0) 324 325 #define FP_UNPACK_EP(X,val) \ 326 do { \ 327 FP_UNPACK_RAW_EP(X,val); \ 328 _FP_UNPACK_CANONICAL(E,2,X); \ 329 } while (0) 330 331 #define FP_PACK_E(val,X) \ 332 do { \ 333 _FP_PACK_CANONICAL(E,2,X); \ 334 FP_PACK_RAW_E(val,X); \ 335 } while (0) 336 337 #define FP_PACK_EP(val,X) \ 338 do { \ 339 _FP_PACK_CANONICAL(E,2,X); \ 340 FP_PACK_RAW_EP(val,X); \ 341 } while (0) 342 343 #define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X) 344 #define FP_NEG_E(R,X) _FP_NEG(E,2,R,X) 345 #define FP_ADD_E(R,X,Y) _FP_ADD(E,2,R,X,Y) 346 #define FP_SUB_E(R,X,Y) _FP_SUB(E,2,R,X,Y) 347 #define FP_MUL_E(R,X,Y) _FP_MUL(E,2,R,X,Y) 348 #define FP_DIV_E(R,X,Y) _FP_DIV(E,2,R,X,Y) 349 #define FP_SQRT_E(R,X) _FP_SQRT(E,2,R,X) 350 351 /* 352 * Square root algorithms: 353 * We have just one right now, maybe Newton approximation 354 * should be added for those machines where division is fast. 355 * We optimize it by doing most of the calculations 356 * in one UWtype registers instead of two, although we don't 357 * have to. 358 */ 359 #define _FP_SQRT_MEAT_E(R, S, T, X, q) \ 360 do { \ 361 q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ 362 _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \ 363 while (q) \ 364 { \ 365 T##_f0 = S##_f0 + q; \ 366 if (T##_f0 <= X##_f0) \ 367 { \ 368 S##_f0 = T##_f0 + q; \ 369 X##_f0 -= T##_f0; \ 370 R##_f0 += q; \ 371 } \ 372 _FP_FRAC_SLL_1(X, 1); \ 373 q >>= 1; \ 374 } \ 375 _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \ 376 if (X##_f0) \ 377 { \ 378 if (S##_f0 < X##_f0) \ 379 R##_f0 |= _FP_WORK_ROUND; \ 380 R##_f0 |= _FP_WORK_STICKY; \ 381 } \ 382 } while (0) 383 384 #define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un) 385 #define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y) 386 387 #define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg) 388 #define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,2,r,X,rsz,rsg) 389 #define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt) 390 391 #define _FP_FRAC_HIGH_E(X) (X##_f1) 392 #define _FP_FRAC_HIGH_RAW_E(X) (X##_f0) 393 394 #endif /* not _FP_W_TYPE_SIZE < 64 */ 395 396 #endif /* __MATH_EMU_EXTENDED_H__ */ 397