^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 eight-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) and
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 7) Peter Maydell (pmaydell@chiark.greenend.org.uk).
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 8)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 9) The GNU C Library is free software; you can redistribute it and/or
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 10) modify it under the terms of the GNU Library General Public License as
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 11) published by the Free Software Foundation; either version 2 of the
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 12) License, or (at your option) any later version.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 13)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 14) The GNU C Library is distributed in the hope that it will be useful,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 15) but WITHOUT ANY WARRANTY; without even the implied warranty of
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 16) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 17) Library General Public License for more details.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 18)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 19) You should have received a copy of the GNU Library General Public
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 20) License along with the GNU C Library; see the file COPYING.LIB. If
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 21) not, write to the Free Software Foundation, Inc.,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 22) 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 23)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 24) #ifndef __MATH_EMU_OP_8_H__
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 25) #define __MATH_EMU_OP_8_H__
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 26)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 27) /* We need just a few things from here for op-4, if we ever need some
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 28) other macros, they can be added. */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 29) #define _FP_FRAC_DECL_8(X) _FP_W_TYPE X##_f[8]
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 30) #define _FP_FRAC_HIGH_8(X) (X##_f[7])
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 31) #define _FP_FRAC_LOW_8(X) (X##_f[0])
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 32) #define _FP_FRAC_WORD_8(X,w) (X##_f[w])
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 33)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 34) #define _FP_FRAC_SLL_8(X,N) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 35) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 36) _FP_I_TYPE _up, _down, _skip, _i; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 37) _skip = (N) / _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 38) _up = (N) % _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 39) _down = _FP_W_TYPE_SIZE - _up; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 40) if (!_up) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 41) for (_i = 7; _i >= _skip; --_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 42) X##_f[_i] = X##_f[_i-_skip]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 43) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 44) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 45) for (_i = 7; _i > _skip; --_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 46) X##_f[_i] = X##_f[_i-_skip] << _up \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 47) | X##_f[_i-_skip-1] >> _down; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 48) X##_f[_i--] = X##_f[0] << _up; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 49) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 50) for (; _i >= 0; --_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 51) X##_f[_i] = 0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 52) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 53)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 54) #define _FP_FRAC_SRL_8(X,N) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 55) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 56) _FP_I_TYPE _up, _down, _skip, _i; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 57) _skip = (N) / _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 58) _down = (N) % _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 59) _up = _FP_W_TYPE_SIZE - _down; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 60) if (!_down) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 61) for (_i = 0; _i <= 7-_skip; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 62) X##_f[_i] = X##_f[_i+_skip]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 63) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 64) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 65) for (_i = 0; _i < 7-_skip; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 66) X##_f[_i] = X##_f[_i+_skip] >> _down \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 67) | X##_f[_i+_skip+1] << _up; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 68) X##_f[_i++] = X##_f[7] >> _down; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 69) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 70) for (; _i < 8; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) X##_f[_i] = 0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 74)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 75) /* Right shift with sticky-lsb.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 76) * What this actually means is that we do a standard right-shift,
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 77) * but that if any of the bits that fall off the right hand side
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 78) * were one then we always set the LSbit.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 79) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 80) #define _FP_FRAC_SRS_8(X,N,size) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 81) do { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 82) _FP_I_TYPE _up, _down, _skip, _i; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 83) _FP_W_TYPE _s; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 84) _skip = (N) / _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 85) _down = (N) % _FP_W_TYPE_SIZE; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 86) _up = _FP_W_TYPE_SIZE - _down; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 87) for (_s = _i = 0; _i < _skip; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 88) _s |= X##_f[_i]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 89) _s |= X##_f[_i] << _up; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 90) /* s is now != 0 if we want to set the LSbit */ \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 91) if (!_down) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 92) for (_i = 0; _i <= 7-_skip; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 93) X##_f[_i] = X##_f[_i+_skip]; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 94) else \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 95) { \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 96) for (_i = 0; _i < 7-_skip; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 97) X##_f[_i] = X##_f[_i+_skip] >> _down \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 98) | X##_f[_i+_skip+1] << _up; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 99) X##_f[_i++] = X##_f[7] >> _down; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 100) } \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 101) for (; _i < 8; ++_i) \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 102) X##_f[_i] = 0; \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 103) /* 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 104) X##_f[0] |= (_s != 0); \
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 105) } while (0)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 106)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 107) #endif