1169689Skan/* Software floating-point emulation. 2169689Skan Basic one-word fraction declaration and manipulation. 3169689Skan Copyright (C) 1997,1998,1999,2006 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#define _FP_FRAC_DECL_1(X) _FP_W_TYPE X##_f 35169689Skan#define _FP_FRAC_COPY_1(D,S) (D##_f = S##_f) 36169689Skan#define _FP_FRAC_SET_1(X,I) (X##_f = I) 37169689Skan#define _FP_FRAC_HIGH_1(X) (X##_f) 38169689Skan#define _FP_FRAC_LOW_1(X) (X##_f) 39169689Skan#define _FP_FRAC_WORD_1(X,w) (X##_f) 40169689Skan 41169689Skan#define _FP_FRAC_ADDI_1(X,I) (X##_f += I) 42169689Skan#define _FP_FRAC_SLL_1(X,N) \ 43169689Skan do { \ 44169689Skan if (__builtin_constant_p(N) && (N) == 1) \ 45169689Skan X##_f += X##_f; \ 46169689Skan else \ 47169689Skan X##_f <<= (N); \ 48169689Skan } while (0) 49169689Skan#define _FP_FRAC_SRL_1(X,N) (X##_f >>= N) 50169689Skan 51169689Skan/* Right shift with sticky-lsb. */ 52169689Skan#define _FP_FRAC_SRST_1(X,S,N,sz) __FP_FRAC_SRST_1(X##_f, S, N, sz) 53169689Skan#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz) 54169689Skan 55169689Skan#define __FP_FRAC_SRST_1(X,S,N,sz) \ 56169689Skando { \ 57169689Skan S = (__builtin_constant_p(N) && (N) == 1 \ 58169689Skan ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \ 59169689Skan X = X >> (N); \ 60169689Skan} while (0) 61169689Skan 62169689Skan#define __FP_FRAC_SRS_1(X,N,sz) \ 63169689Skan (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \ 64169689Skan ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0))) 65169689Skan 66169689Skan#define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f) 67169689Skan#define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f) 68169689Skan#define _FP_FRAC_DEC_1(X,Y) (X##_f -= Y##_f) 69169689Skan#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ(z, X##_f) 70169689Skan 71169689Skan/* Predicates */ 72169689Skan#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE)X##_f < 0) 73169689Skan#define _FP_FRAC_ZEROP_1(X) (X##_f == 0) 74169689Skan#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs) 75169689Skan#define _FP_FRAC_CLEAR_OVERP_1(fs,X) (X##_f &= ~_FP_OVERFLOW_##fs) 76169689Skan#define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f) 77169689Skan#define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f) 78169689Skan#define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f) 79169689Skan 80169689Skan#define _FP_ZEROFRAC_1 0 81169689Skan#define _FP_MINFRAC_1 1 82169689Skan#define _FP_MAXFRAC_1 (~(_FP_WS_TYPE)0) 83169689Skan 84169689Skan/* 85169689Skan * Unpack the raw bits of a native fp value. Do not classify or 86169689Skan * normalize the data. 87169689Skan */ 88169689Skan 89169689Skan#define _FP_UNPACK_RAW_1(fs, X, val) \ 90169689Skan do { \ 91169689Skan union _FP_UNION_##fs _flo; _flo.flt = (val); \ 92169689Skan \ 93169689Skan X##_f = _flo.bits.frac; \ 94169689Skan X##_e = _flo.bits.exp; \ 95169689Skan X##_s = _flo.bits.sign; \ 96169689Skan } while (0) 97169689Skan 98169689Skan#define _FP_UNPACK_RAW_1_P(fs, X, val) \ 99169689Skan do { \ 100169689Skan union _FP_UNION_##fs *_flo = \ 101169689Skan (union _FP_UNION_##fs *)(val); \ 102169689Skan \ 103169689Skan X##_f = _flo->bits.frac; \ 104169689Skan X##_e = _flo->bits.exp; \ 105169689Skan X##_s = _flo->bits.sign; \ 106169689Skan } while (0) 107169689Skan 108169689Skan/* 109169689Skan * Repack the raw bits of a native fp value. 110169689Skan */ 111169689Skan 112169689Skan#define _FP_PACK_RAW_1(fs, val, X) \ 113169689Skan do { \ 114169689Skan union _FP_UNION_##fs _flo; \ 115169689Skan \ 116169689Skan _flo.bits.frac = X##_f; \ 117169689Skan _flo.bits.exp = X##_e; \ 118169689Skan _flo.bits.sign = X##_s; \ 119169689Skan \ 120169689Skan (val) = _flo.flt; \ 121169689Skan } while (0) 122169689Skan 123169689Skan#define _FP_PACK_RAW_1_P(fs, val, X) \ 124169689Skan do { \ 125169689Skan union _FP_UNION_##fs *_flo = \ 126169689Skan (union _FP_UNION_##fs *)(val); \ 127169689Skan \ 128169689Skan _flo->bits.frac = X##_f; \ 129169689Skan _flo->bits.exp = X##_e; \ 130169689Skan _flo->bits.sign = X##_s; \ 131169689Skan } while (0) 132169689Skan 133169689Skan 134169689Skan/* 135169689Skan * Multiplication algorithms: 136169689Skan */ 137169689Skan 138169689Skan/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the 139169689Skan multiplication immediately. */ 140169689Skan 141169689Skan#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y) \ 142169689Skan do { \ 143169689Skan R##_f = X##_f * Y##_f; \ 144169689Skan /* Normalize since we know where the msb of the multiplicands \ 145169689Skan were (bit B), we know that the msb of the of the product is \ 146169689Skan at either 2B or 2B-1. */ \ 147169689Skan _FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits); \ 148169689Skan } while (0) 149169689Skan 150169689Skan/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ 151169689Skan 152169689Skan#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit) \ 153169689Skan do { \ 154169689Skan _FP_W_TYPE _Z_f0, _Z_f1; \ 155169689Skan doit(_Z_f1, _Z_f0, X##_f, Y##_f); \ 156169689Skan /* Normalize since we know where the msb of the multiplicands \ 157169689Skan were (bit B), we know that the msb of the of the product is \ 158169689Skan at either 2B or 2B-1. */ \ 159169689Skan _FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits); \ 160169689Skan R##_f = _Z_f0; \ 161169689Skan } while (0) 162169689Skan 163169689Skan/* Finally, a simple widening multiply algorithm. What fun! */ 164169689Skan 165169689Skan#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \ 166169689Skan do { \ 167169689Skan _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1; \ 168169689Skan \ 169169689Skan /* split the words in half */ \ 170169689Skan _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \ 171169689Skan _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ 172169689Skan _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \ 173169689Skan _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ 174169689Skan \ 175169689Skan /* multiply the pieces */ \ 176169689Skan _z_f0 = _xl * _yl; \ 177169689Skan _a_f0 = _xh * _yl; \ 178169689Skan _a_f1 = _xl * _yh; \ 179169689Skan _z_f1 = _xh * _yh; \ 180169689Skan \ 181169689Skan /* reassemble into two full words */ \ 182169689Skan if ((_a_f0 += _a_f1) < _a_f1) \ 183169689Skan _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \ 184169689Skan _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \ 185169689Skan _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \ 186169689Skan _FP_FRAC_ADD_2(_z, _z, _a); \ 187169689Skan \ 188169689Skan /* normalize */ \ 189169689Skan _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits); \ 190169689Skan R##_f = _z_f0; \ 191169689Skan } while (0) 192169689Skan 193169689Skan 194169689Skan/* 195169689Skan * Division algorithms: 196169689Skan */ 197169689Skan 198169689Skan/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the 199169689Skan division immediately. Give this macro either _FP_DIV_HELP_imm for 200169689Skan C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you 201169689Skan choose will depend on what the compiler does with divrem4. */ 202169689Skan 203169689Skan#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \ 204169689Skan do { \ 205169689Skan _FP_W_TYPE _q, _r; \ 206169689Skan X##_f <<= (X##_f < Y##_f \ 207169689Skan ? R##_e--, _FP_WFRACBITS_##fs \ 208169689Skan : _FP_WFRACBITS_##fs - 1); \ 209169689Skan doit(_q, _r, X##_f, Y##_f); \ 210169689Skan R##_f = _q | (_r != 0); \ 211169689Skan } while (0) 212169689Skan 213169689Skan/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd 214169689Skan that may be useful in this situation. This first is for a primitive 215169689Skan that requires normalization, the second for one that does not. Look 216169689Skan for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */ 217169689Skan 218169689Skan#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \ 219169689Skan do { \ 220169689Skan _FP_W_TYPE _nh, _nl, _q, _r, _y; \ 221169689Skan \ 222169689Skan /* Normalize Y -- i.e. make the most significant bit set. */ \ 223169689Skan _y = Y##_f << _FP_WFRACXBITS_##fs; \ 224169689Skan \ 225169689Skan /* Shift X op correspondingly high, that is, up one full word. */ \ 226169689Skan if (X##_f < Y##_f) \ 227169689Skan { \ 228169689Skan R##_e--; \ 229169689Skan _nl = 0; \ 230169689Skan _nh = X##_f; \ 231169689Skan } \ 232169689Skan else \ 233169689Skan { \ 234169689Skan _nl = X##_f << (_FP_W_TYPE_SIZE - 1); \ 235169689Skan _nh = X##_f >> 1; \ 236169689Skan } \ 237169689Skan \ 238169689Skan udiv_qrnnd(_q, _r, _nh, _nl, _y); \ 239169689Skan R##_f = _q | (_r != 0); \ 240169689Skan } while (0) 241169689Skan 242169689Skan#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \ 243169689Skan do { \ 244169689Skan _FP_W_TYPE _nh, _nl, _q, _r; \ 245169689Skan if (X##_f < Y##_f) \ 246169689Skan { \ 247169689Skan R##_e--; \ 248169689Skan _nl = X##_f << _FP_WFRACBITS_##fs; \ 249169689Skan _nh = X##_f >> _FP_WFRACXBITS_##fs; \ 250169689Skan } \ 251169689Skan else \ 252169689Skan { \ 253169689Skan _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \ 254169689Skan _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \ 255169689Skan } \ 256169689Skan udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \ 257169689Skan R##_f = _q | (_r != 0); \ 258169689Skan } while (0) 259169689Skan 260169689Skan 261169689Skan/* 262169689Skan * Square root algorithms: 263169689Skan * We have just one right now, maybe Newton approximation 264169689Skan * should be added for those machines where division is fast. 265169689Skan */ 266169689Skan 267169689Skan#define _FP_SQRT_MEAT_1(R, S, T, X, q) \ 268169689Skan do { \ 269169689Skan while (q != _FP_WORK_ROUND) \ 270169689Skan { \ 271169689Skan T##_f = S##_f + q; \ 272169689Skan if (T##_f <= X##_f) \ 273169689Skan { \ 274169689Skan S##_f = T##_f + q; \ 275169689Skan X##_f -= T##_f; \ 276169689Skan R##_f += q; \ 277169689Skan } \ 278169689Skan _FP_FRAC_SLL_1(X, 1); \ 279169689Skan q >>= 1; \ 280169689Skan } \ 281169689Skan if (X##_f) \ 282169689Skan { \ 283169689Skan if (S##_f < X##_f) \ 284169689Skan R##_f |= _FP_WORK_ROUND; \ 285169689Skan R##_f |= _FP_WORK_STICKY; \ 286169689Skan } \ 287169689Skan } while (0) 288169689Skan 289169689Skan/* 290169689Skan * Assembly/disassembly for converting to/from integral types. 291169689Skan * No shifting or overflow handled here. 292169689Skan */ 293169689Skan 294169689Skan#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f) 295169689Skan#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r) 296169689Skan 297169689Skan 298169689Skan/* 299169689Skan * Convert FP values between word sizes 300169689Skan */ 301169689Skan 302169689Skan#define _FP_FRAC_COPY_1_1(D, S) (D##_f = S##_f) 303