^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 1) /* Software floating-point emulation.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 2) Basic four-word fraction declaration and manipulation.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3) Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 4) This file is part of the GNU C Library.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 5) Contributed by Richard Henderson (rth@cygnus.com),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 6) Jakub Jelinek (jj@ultra.linux.cz),
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 7) David S. Miller (davem@redhat.com) and
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 8) Peter Maydell (pmaydell@chiark.greenend.org.uk).
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 9)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 10) The GNU C Library is free software; you can redistribute it and/or
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 11) modify it under the terms of the GNU Library General Public License as
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 12) published by the Free Software Foundation; either version 2 of the
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 13) License, or (at your option) any later version.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 14)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 15) The GNU C Library is distributed in the hope that it will be useful,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 16) but WITHOUT ANY WARRANTY; without even the implied warranty of
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 17) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 18) Library General Public License for more details.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 19)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 20) You should have received a copy of the GNU Library General Public
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 21) License along with the GNU C Library; see the file COPYING.LIB. If
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 22) not, write to the Free Software Foundation, Inc.,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 23) 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 24)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 25) #ifndef __MATH_EMU_OP_4_H__
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 26) #define __MATH_EMU_OP_4_H__
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 27)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 28) #define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4]
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 29) #define _FP_FRAC_COPY_4(D,S) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 30) (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 31) D##_f[2] = S##_f[2], D##_f[3] = S##_f[3])
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 32) #define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 33) #define _FP_FRAC_HIGH_4(X) (X##_f[3])
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 34) #define _FP_FRAC_LOW_4(X) (X##_f[0])
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 35) #define _FP_FRAC_WORD_4(X,w) (X##_f[w])
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 36)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 37) #define _FP_FRAC_SLL_4(X,N) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 38) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 39) _FP_I_TYPE _up, _down, _skip, _i; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 40) _skip = (N) / _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 41) _up = (N) % _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 42) _down = _FP_W_TYPE_SIZE - _up; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 43) if (!_up) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 44) for (_i = 3; _i >= _skip; --_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 45) X##_f[_i] = X##_f[_i-_skip]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 46) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 47) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 48) for (_i = 3; _i > _skip; --_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 49) X##_f[_i] = X##_f[_i-_skip] << _up \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 50) | X##_f[_i-_skip-1] >> _down; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 51) X##_f[_i--] = X##_f[0] << _up; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 52) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 53) for (; _i >= 0; --_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 54) X##_f[_i] = 0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 55) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 56)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 57) /* This one was broken too */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 58) #define _FP_FRAC_SRL_4(X,N) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 59) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 60) _FP_I_TYPE _up, _down, _skip, _i; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 61) _skip = (N) / _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 62) _down = (N) % _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 63) _up = _FP_W_TYPE_SIZE - _down; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 64) if (!_down) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 65) for (_i = 0; _i <= 3-_skip; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 66) X##_f[_i] = X##_f[_i+_skip]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 67) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 68) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 69) for (_i = 0; _i < 3-_skip; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 70) X##_f[_i] = X##_f[_i+_skip] >> _down \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) | X##_f[_i+_skip+1] << _up; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) X##_f[_i++] = X##_f[3] >> _down; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 74) for (; _i < 4; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 75) X##_f[_i] = 0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 76) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 77)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 78)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 79) /* Right shift with sticky-lsb.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 80) * What this actually means is that we do a standard right-shift,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 81) * but that if any of the bits that fall off the right hand side
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 82) * were one then we always set the LSbit.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 83) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 84) #define _FP_FRAC_SRS_4(X,N,size) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 85) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 86) _FP_I_TYPE _up, _down, _skip, _i; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 87) _FP_W_TYPE _s; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 88) _skip = (N) / _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 89) _down = (N) % _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 90) _up = _FP_W_TYPE_SIZE - _down; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 91) for (_s = _i = 0; _i < _skip; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 92) _s |= X##_f[_i]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 93) _s |= X##_f[_i] << _up; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 94) /* s is now != 0 if we want to set the LSbit */ \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 95) if (!_down) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 96) for (_i = 0; _i <= 3-_skip; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 97) X##_f[_i] = X##_f[_i+_skip]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 98) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 99) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 100) for (_i = 0; _i < 3-_skip; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 101) X##_f[_i] = X##_f[_i+_skip] >> _down \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 102) | X##_f[_i+_skip+1] << _up; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 103) X##_f[_i++] = X##_f[3] >> _down; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 104) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 105) for (; _i < 4; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 106) X##_f[_i] = 0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 107) /* don't fix the LSB until the very end when we're sure f[0] is stable */ \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 108) X##_f[0] |= (_s != 0); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 109) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 110)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 111) #define _FP_FRAC_ADD_4(R,X,Y) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 112) __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 113) X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 114) Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 115)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 116) #define _FP_FRAC_SUB_4(R,X,Y) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 117) __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 118) X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 119) Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 120)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 121) #define _FP_FRAC_DEC_4(X,Y) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 122) __FP_FRAC_DEC_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 123) Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 124)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 125) #define _FP_FRAC_ADDI_4(X,I) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 126) __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 127)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 128) #define _FP_ZEROFRAC_4 0,0,0,0
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 129) #define _FP_MINFRAC_4 0,0,0,1
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 130) #define _FP_MAXFRAC_4 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 131)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 132) #define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 133) #define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE)X##_f[3] < 0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 134) #define _FP_FRAC_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 135) #define _FP_FRAC_CLEAR_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 136)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 137) #define _FP_FRAC_EQ_4(X,Y) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 138) (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 139) && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3])
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 140)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 141) #define _FP_FRAC_GT_4(X,Y) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 142) (X##_f[3] > Y##_f[3] || \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 143) (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 144) (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 145) (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 146) )) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 147) )) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 148) )
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 149)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 150) #define _FP_FRAC_GE_4(X,Y) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 151) (X##_f[3] > Y##_f[3] || \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 152) (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 153) (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 154) (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 155) )) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 156) )) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 157) )
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 158)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 159)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 160) #define _FP_FRAC_CLZ_4(R,X) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 161) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 162) if (X##_f[3]) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 163) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 164) __FP_CLZ(R,X##_f[3]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 165) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 166) else if (X##_f[2]) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 167) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 168) __FP_CLZ(R,X##_f[2]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 169) R += _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 170) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 171) else if (X##_f[1]) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 172) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 173) __FP_CLZ(R,X##_f[2]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 174) R += _FP_W_TYPE_SIZE*2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 175) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 176) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 177) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 178) __FP_CLZ(R,X##_f[0]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 179) R += _FP_W_TYPE_SIZE*3; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 180) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 181) } while(0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 182)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 183)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 184) #define _FP_UNPACK_RAW_4(fs, X, val) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 185) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 186) union _FP_UNION_##fs _flo; _flo.flt = (val); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 187) X##_f[0] = _flo.bits.frac0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 188) X##_f[1] = _flo.bits.frac1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 189) X##_f[2] = _flo.bits.frac2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 190) X##_f[3] = _flo.bits.frac3; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 191) X##_e = _flo.bits.exp; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 192) X##_s = _flo.bits.sign; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 193) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 194)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 195) #define _FP_UNPACK_RAW_4_P(fs, X, val) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 196) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 197) union _FP_UNION_##fs *_flo = \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 198) (union _FP_UNION_##fs *)(val); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 199) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 200) X##_f[0] = _flo->bits.frac0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 201) X##_f[1] = _flo->bits.frac1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 202) X##_f[2] = _flo->bits.frac2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 203) X##_f[3] = _flo->bits.frac3; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 204) X##_e = _flo->bits.exp; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 205) X##_s = _flo->bits.sign; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 206) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 207)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 208) #define _FP_PACK_RAW_4(fs, val, X) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 209) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 210) union _FP_UNION_##fs _flo; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 211) _flo.bits.frac0 = X##_f[0]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 212) _flo.bits.frac1 = X##_f[1]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 213) _flo.bits.frac2 = X##_f[2]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 214) _flo.bits.frac3 = X##_f[3]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 215) _flo.bits.exp = X##_e; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 216) _flo.bits.sign = X##_s; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 217) (val) = _flo.flt; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 218) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 219)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 220) #define _FP_PACK_RAW_4_P(fs, val, X) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 221) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 222) union _FP_UNION_##fs *_flo = \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 223) (union _FP_UNION_##fs *)(val); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 224) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 225) _flo->bits.frac0 = X##_f[0]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 226) _flo->bits.frac1 = X##_f[1]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 227) _flo->bits.frac2 = X##_f[2]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 228) _flo->bits.frac3 = X##_f[3]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 229) _flo->bits.exp = X##_e; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 230) _flo->bits.sign = X##_s; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 231) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 232)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 233) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 234) * Multiplication algorithms:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 235) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 236)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 237) /* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 238)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 239) #define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 240) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 241) _FP_FRAC_DECL_8(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 242) _FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 243) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 244) doit(_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0), X##_f[0], Y##_f[0]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 245) doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 246) doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 247) doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 248) doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 249) doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 250) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 251) _FP_FRAC_WORD_8(_z,1), 0,_b_f1,_b_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 252) 0,0,_FP_FRAC_WORD_8(_z,1)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 253) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 254) _FP_FRAC_WORD_8(_z,1), 0,_c_f1,_c_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 255) _FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 256) _FP_FRAC_WORD_8(_z,1)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 257) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 258) _FP_FRAC_WORD_8(_z,2), 0,_d_f1,_d_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 259) 0,_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 260) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 261) _FP_FRAC_WORD_8(_z,2), 0,_e_f1,_e_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 262) _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 263) _FP_FRAC_WORD_8(_z,2)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 264) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 265) _FP_FRAC_WORD_8(_z,2), 0,_f_f1,_f_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 266) _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 267) _FP_FRAC_WORD_8(_z,2)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 268) doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 269) doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 270) doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 271) doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 272) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 273) _FP_FRAC_WORD_8(_z,3), 0,_b_f1,_b_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 274) 0,_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 275) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 276) _FP_FRAC_WORD_8(_z,3), 0,_c_f1,_c_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 277) _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 278) _FP_FRAC_WORD_8(_z,3)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 279) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 280) _FP_FRAC_WORD_8(_z,3), 0,_d_f1,_d_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 281) _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 282) _FP_FRAC_WORD_8(_z,3)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 283) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 284) _FP_FRAC_WORD_8(_z,3), 0,_e_f1,_e_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 285) _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 286) _FP_FRAC_WORD_8(_z,3)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 287) doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 288) doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 289) doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 290) doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 291) doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 292) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 293) _FP_FRAC_WORD_8(_z,4), 0,_b_f1,_b_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 294) 0,_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 295) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 296) _FP_FRAC_WORD_8(_z,4), 0,_c_f1,_c_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 297) _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 298) _FP_FRAC_WORD_8(_z,4)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 299) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 300) _FP_FRAC_WORD_8(_z,4), 0,_d_f1,_d_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 301) _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 302) _FP_FRAC_WORD_8(_z,4)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 303) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 304) _FP_FRAC_WORD_8(_z,5), 0,_e_f1,_e_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 305) 0,_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 306) __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 307) _FP_FRAC_WORD_8(_z,5), 0,_f_f1,_f_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 308) _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 309) _FP_FRAC_WORD_8(_z,5)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 310) doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 311) __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 312) _b_f1,_b_f0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 313) _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 314) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 315) /* Normalize since we know where the msb of the multiplicands \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 316) were (bit B), we know that the msb of the of the product is \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 317) at either 2B or 2B-1. */ \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 318) _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 319) __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 320) _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 321) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 322)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 323) #define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 324) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 325) _FP_FRAC_DECL_8(_z); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 326) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 327) mpn_mul_n(_z_f, _x_f, _y_f, 4); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 328) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 329) /* Normalize since we know where the msb of the multiplicands \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 330) were (bit B), we know that the msb of the of the product is \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 331) at either 2B or 2B-1. */ \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 332) _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 333) __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 334) _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 335) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 336)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 337) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 338) * Helper utility for _FP_DIV_MEAT_4_udiv:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 339) * pppp = m * nnn
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 340) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 341) #define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 342) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 343) UWtype _t; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 344) umul_ppmm(p1,p0,m,n0); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 345) umul_ppmm(p2,_t,m,n1); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 346) __FP_FRAC_ADDI_2(p2,p1,_t); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 347) umul_ppmm(p3,_t,m,n2); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 348) __FP_FRAC_ADDI_2(p3,p2,_t); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 349) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 350)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 351) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 352) * Division algorithms:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 353) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 354)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 355) #define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 356) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 357) int _i; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 358) _FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 359) _FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 360) if (_FP_FRAC_GT_4(X, Y)) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 361) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 362) _n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 363) _FP_FRAC_SRL_4(X, 1); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 364) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 365) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 366) R##_e--; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 367) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 368) /* Normalize, i.e. make the most significant bit of the \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 369) denominator set. */ \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 370) _FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 371) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 372) for (_i = 3; ; _i--) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 373) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 374) if (X##_f[3] == Y##_f[3]) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 375) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 376) /* This is a special case, not an optimization \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 377) (X##_f[3]/Y##_f[3] would not fit into UWtype). \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 378) As X## is guaranteed to be < Y, R##_f[_i] can be either \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 379) (UWtype)-1 or (UWtype)-2. */ \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 380) R##_f[_i] = -1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 381) if (!_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 382) break; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 383) __FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 384) Y##_f[2], Y##_f[1], Y##_f[0], 0, \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 385) X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 386) _FP_FRAC_SUB_4(X, Y, X); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 387) if (X##_f[3] > Y##_f[3]) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 388) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 389) R##_f[_i] = -2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 390) _FP_FRAC_ADD_4(X, Y, X); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 391) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 392) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 393) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 394) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 395) udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 396) umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0], \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 397) R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 398) X##_f[2] = X##_f[1]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 399) X##_f[1] = X##_f[0]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 400) X##_f[0] = _n_f[_i]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 401) if (_FP_FRAC_GT_4(_m, X)) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 402) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 403) R##_f[_i]--; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 404) _FP_FRAC_ADD_4(X, Y, X); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 405) if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X)) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 406) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 407) R##_f[_i]--; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 408) _FP_FRAC_ADD_4(X, Y, X); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 409) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 410) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 411) _FP_FRAC_DEC_4(X, _m); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 412) if (!_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 413) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 414) if (!_FP_FRAC_EQ_4(X, _m)) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 415) R##_f[0] |= _FP_WORK_STICKY; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 416) break; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 417) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 418) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 419) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 420) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 421)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 422)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 423) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 424) * Square root algorithms:
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 425) * We have just one right now, maybe Newton approximation
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 426) * should be added for those machines where division is fast.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 427) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 428)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 429) #define _FP_SQRT_MEAT_4(R, S, T, X, q) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 430) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 431) while (q) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 432) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 433) T##_f[3] = S##_f[3] + q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 434) if (T##_f[3] <= X##_f[3]) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 435) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 436) S##_f[3] = T##_f[3] + q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 437) X##_f[3] -= T##_f[3]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 438) R##_f[3] += q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 439) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 440) _FP_FRAC_SLL_4(X, 1); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 441) q >>= 1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 442) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 443) q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 444) while (q) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 445) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 446) T##_f[2] = S##_f[2] + q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 447) T##_f[3] = S##_f[3]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 448) if (T##_f[3] < X##_f[3] || \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 449) (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 450) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 451) S##_f[2] = T##_f[2] + q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 452) S##_f[3] += (T##_f[2] > S##_f[2]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 453) __FP_FRAC_DEC_2(X##_f[3], X##_f[2], \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 454) T##_f[3], T##_f[2]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 455) R##_f[2] += q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 456) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 457) _FP_FRAC_SLL_4(X, 1); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 458) q >>= 1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 459) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 460) q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 461) while (q) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 462) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 463) T##_f[1] = S##_f[1] + q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 464) T##_f[2] = S##_f[2]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 465) T##_f[3] = S##_f[3]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 466) if (T##_f[3] < X##_f[3] || \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 467) (T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] || \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 468) (T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1])))) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 469) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 470) S##_f[1] = T##_f[1] + q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 471) S##_f[2] += (T##_f[1] > S##_f[1]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 472) S##_f[3] += (T##_f[2] > S##_f[2]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 473) __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1], \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 474) T##_f[3], T##_f[2], T##_f[1]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 475) R##_f[1] += q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 476) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 477) _FP_FRAC_SLL_4(X, 1); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 478) q >>= 1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 479) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 480) q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 481) while (q != _FP_WORK_ROUND) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 482) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 483) T##_f[0] = S##_f[0] + q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 484) T##_f[1] = S##_f[1]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 485) T##_f[2] = S##_f[2]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 486) T##_f[3] = S##_f[3]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 487) if (_FP_FRAC_GE_4(X,T)) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 488) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 489) S##_f[0] = T##_f[0] + q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 490) S##_f[1] += (T##_f[0] > S##_f[0]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 491) S##_f[2] += (T##_f[1] > S##_f[1]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 492) S##_f[3] += (T##_f[2] > S##_f[2]); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 493) _FP_FRAC_DEC_4(X, T); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 494) R##_f[0] += q; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 495) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 496) _FP_FRAC_SLL_4(X, 1); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 497) q >>= 1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 498) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 499) if (!_FP_FRAC_ZEROP_4(X)) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 500) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 501) if (_FP_FRAC_GT_4(X,S)) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 502) R##_f[0] |= _FP_WORK_ROUND; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 503) R##_f[0] |= _FP_WORK_STICKY; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 504) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 505) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 506)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 507)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 508) /*
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 509) * Internals
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 510) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 511)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 512) #define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 513) (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 514)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 515) #ifndef __FP_FRAC_ADD_3
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 516) #define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 517) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 518) int _c1, _c2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 519) r0 = x0 + y0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 520) _c1 = r0 < x0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 521) r1 = x1 + y1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 522) _c2 = r1 < x1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 523) r1 += _c1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 524) _c2 |= r1 < _c1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 525) r2 = x2 + y2 + _c2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 526) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 527) #endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 528)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 529) #ifndef __FP_FRAC_ADD_4
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 530) #define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 531) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 532) int _c1, _c2, _c3; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 533) r0 = x0 + y0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 534) _c1 = r0 < x0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 535) r1 = x1 + y1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 536) _c2 = r1 < x1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 537) r1 += _c1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 538) _c2 |= r1 < _c1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 539) r2 = x2 + y2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 540) _c3 = r2 < x2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 541) r2 += _c2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 542) _c3 |= r2 < _c2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 543) r3 = x3 + y3 + _c3; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 544) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 545) #endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 546)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 547) #ifndef __FP_FRAC_SUB_3
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 548) #define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 549) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 550) int _c1, _c2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 551) r0 = x0 - y0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 552) _c1 = r0 > x0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 553) r1 = x1 - y1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 554) _c2 = r1 > x1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 555) r1 -= _c1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 556) _c2 |= r1 > _c1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 557) r2 = x2 - y2 - _c2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 558) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 559) #endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 560)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 561) #ifndef __FP_FRAC_SUB_4
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 562) #define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 563) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 564) int _c1, _c2, _c3; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 565) r0 = x0 - y0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 566) _c1 = r0 > x0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 567) r1 = x1 - y1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 568) _c2 = r1 > x1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 569) r1 -= _c1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 570) _c2 |= r1 > _c1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 571) r2 = x2 - y2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 572) _c3 = r2 > x2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 573) r2 -= _c2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 574) _c3 |= r2 > _c2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 575) r3 = x3 - y3 - _c3; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 576) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 577) #endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 578)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 579) #ifndef __FP_FRAC_DEC_3
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 580) #define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 581) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 582) UWtype _t0, _t1, _t2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 583) _t0 = x0, _t1 = x1, _t2 = x2; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 584) __FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 585) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 586) #endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 587)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 588) #ifndef __FP_FRAC_DEC_4
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 589) #define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 590) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 591) UWtype _t0, _t1, _t2, _t3; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 592) _t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 593) __FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 594) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 595) #endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 596)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 597) #ifndef __FP_FRAC_ADDI_4
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 598) #define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 599) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 600) UWtype _t; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 601) _t = ((x0 += i) < i); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 602) x1 += _t; _t = (x1 < _t); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 603) x2 += _t; _t = (x2 < _t); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 604) x3 += _t; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 605) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 606) #endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 607)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 608) /* Convert FP values between word sizes. This appears to be more
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 609) * complicated than I'd have expected it to be, so these might be
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 610) * wrong... These macros are in any case somewhat bogus because they
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 611) * use information about what various FRAC_n variables look like
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 612) * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 613) * the ones in op-2.h and op-1.h.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 614) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 615) #define _FP_FRAC_CONV_1_4(dfs, sfs, D, S) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 616) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 617) if (S##_c != FP_CLS_NAN) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 618) _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 619) _FP_WFRACBITS_##sfs); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 620) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 621) _FP_FRAC_SRL_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 622) D##_f = S##_f[0]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 623) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 624)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 625) #define _FP_FRAC_CONV_2_4(dfs, sfs, D, S) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 626) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 627) if (S##_c != FP_CLS_NAN) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 628) _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 629) _FP_WFRACBITS_##sfs); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 630) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 631) _FP_FRAC_SRL_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 632) D##_f0 = S##_f[0]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 633) D##_f1 = S##_f[1]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 634) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 635)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 636) /* Assembly/disassembly for converting to/from integral types.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 637) * No shifting or overflow handled here.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 638) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 639) /* Put the FP value X into r, which is an integer of size rsize. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 640) #define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 641) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 642) if (rsize <= _FP_W_TYPE_SIZE) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 643) r = X##_f[0]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 644) else if (rsize <= 2*_FP_W_TYPE_SIZE) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 645) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 646) r = X##_f[1]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 647) r <<= _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 648) r += X##_f[0]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 649) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 650) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 651) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 652) /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 653) /* and int == 4words as a single case. */ \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 654) r = X##_f[3]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 655) r <<= _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 656) r += X##_f[2]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 657) r <<= _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 658) r += X##_f[1]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 659) r <<= _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 660) r += X##_f[0]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 661) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 662) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 663)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 664) /* "No disassemble Number Five!" */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 665) /* move an integer of size rsize into X's fractional part. We rely on
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 666) * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 667) * having to mask the values we store into it.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 668) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 669) #define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 670) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 671) X##_f[0] = r; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 672) X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 673) X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 674) X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 675) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 676)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 677) #define _FP_FRAC_CONV_4_1(dfs, sfs, D, S) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 678) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 679) D##_f[0] = S##_f; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 680) D##_f[1] = D##_f[2] = D##_f[3] = 0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 681) _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 682) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 683)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 684) #define _FP_FRAC_CONV_4_2(dfs, sfs, D, S) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 685) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 686) D##_f[0] = S##_f0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 687) D##_f[1] = S##_f1; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 688) D##_f[2] = D##_f[3] = 0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 689) _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 690) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 691)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 692) #endif