📄 op-2.h
字号:
/* Software floating-point emulation. Basic two-word fraction declaration and manipulation. Copyright (C) 1997,1998,1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson (rth@cygnus.com), Jakub Jelinek (jj@ultra.linux.cz), David S. Miller (davem@redhat.com) and Peter Maydell (pmaydell@chiark.greenend.org.uk). The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#ifndef __MATH_EMU_OP_2_H__#define __MATH_EMU_OP_2_H__#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1)#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I)#define _FP_FRAC_HIGH_2(X) (X##_f1)#define _FP_FRAC_LOW_2(X) (X##_f0)#define _FP_FRAC_WORD_2(X,w) (X##_f##w)#define _FP_FRAC_SLL_2(X,N) \ do { \ if ((N) < _FP_W_TYPE_SIZE) \ { \ if (__builtin_constant_p(N) && (N) == 1) \ { \ X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \ X##_f0 += X##_f0; \ } \ else \ { \ X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \ X##_f0 <<= (N); \ } \ } \ else \ { \ X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \ X##_f0 = 0; \ } \ } while (0)#define _FP_FRAC_SRL_2(X,N) \ do { \ if ((N) < _FP_W_TYPE_SIZE) \ { \ X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \ X##_f1 >>= (N); \ } \ else \ { \ X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \ X##_f1 = 0; \ } \ } while (0)/* Right shift with sticky-lsb. */#define _FP_FRAC_SRS_2(X,N,sz) \ do { \ if ((N) < _FP_W_TYPE_SIZE) \ { \ X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \ (__builtin_constant_p(N) && (N) == 1 \ ? X##_f0 & 1 \ : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \ X##_f1 >>= (N); \ } \ else \ { \ X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \ (((X##_f1 << (2*_FP_W_TYPE_SIZE - (N))) | X##_f0) != 0)); \ X##_f1 = 0; \ } \ } while (0)#define _FP_FRAC_ADDI_2(X,I) \ __FP_FRAC_ADDI_2(X##_f1, X##_f0, I)#define _FP_FRAC_ADD_2(R,X,Y) \ __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)#define _FP_FRAC_SUB_2(R,X,Y) \ __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)#define _FP_FRAC_DEC_2(X,Y) \ __FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0)#define _FP_FRAC_CLZ_2(R,X) \ do { \ if (X##_f1) \ __FP_CLZ(R,X##_f1); \ else \ { \ __FP_CLZ(R,X##_f0); \ R += _FP_W_TYPE_SIZE; \ } \ } while(0)/* Predicates */#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0)#define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0)#define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)#define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0)#define _FP_FRAC_GT_2(X, Y) \ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))#define _FP_FRAC_GE_2(X, Y) \ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))#define _FP_ZEROFRAC_2 0, 0#define _FP_MINFRAC_2 0, 1#define _FP_MAXFRAC_2 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0)/* * Internals */#define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1)#define __FP_CLZ_2(R, xh, xl) \ do { \ if (xh) \ __FP_CLZ(R,xh); \ else \ { \ __FP_CLZ(R,xl); \ R += _FP_W_TYPE_SIZE; \ } \ } while(0)#if 0#ifndef __FP_FRAC_ADDI_2#define __FP_FRAC_ADDI_2(xh, xl, i) \ (xh += ((xl += i) < i))#endif#ifndef __FP_FRAC_ADD_2#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \ (rh = xh + yh + ((rl = xl + yl) < xl))#endif#ifndef __FP_FRAC_SUB_2#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \ (rh = xh - yh - ((rl = xl - yl) > xl))#endif#ifndef __FP_FRAC_DEC_2#define __FP_FRAC_DEC_2(xh, xl, yh, yl) \ do { \ UWtype _t = xl; \ xh -= yh + ((xl -= yl) > _t); \ } while (0)#endif#else#undef __FP_FRAC_ADDI_2#define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i)#undef __FP_FRAC_ADD_2#define __FP_FRAC_ADD_2 add_ssaaaa#undef __FP_FRAC_SUB_2#define __FP_FRAC_SUB_2 sub_ddmmss#undef __FP_FRAC_DEC_2#define __FP_FRAC_DEC_2(xh, xl, yh, yl) sub_ddmmss(xh, xl, xh, xl, yh, yl)#endif/* * Unpack the raw bits of a native fp value. Do not classify or * normalize the data. */#define _FP_UNPACK_RAW_2(fs, X, val) \ do { \ union _FP_UNION_##fs _flo; _flo.flt = (val); \ \ X##_f0 = _flo.bits.frac0; \ X##_f1 = _flo.bits.frac1; \ X##_e = _flo.bits.exp; \ X##_s = _flo.bits.sign; \ } while (0)#define _FP_UNPACK_RAW_2_P(fs, X, val) \ do { \ union _FP_UNION_##fs *_flo = \ (union _FP_UNION_##fs *)(val); \ \ X##_f0 = _flo->bits.frac0; \ X##_f1 = _flo->bits.frac1; \ X##_e = _flo->bits.exp; \ X##_s = _flo->bits.sign; \ } while (0)/* * Repack the raw bits of a native fp value. */#define _FP_PACK_RAW_2(fs, val, X) \ do { \ union _FP_UNION_##fs _flo; \ \ _flo.bits.frac0 = X##_f0; \ _flo.bits.frac1 = X##_f1; \ _flo.bits.exp = X##_e; \ _flo.bits.sign = X##_s; \ \ (val) = _flo.flt; \ } while (0)#define _FP_PACK_RAW_2_P(fs, val, X) \ do { \ union _FP_UNION_##fs *_flo = \ (union _FP_UNION_##fs *)(val); \ \ _flo->bits.frac0 = X##_f0; \ _flo->bits.frac1 = X##_f1; \ _flo->bits.exp = X##_e; \ _flo->bits.sign = X##_s; \ } while (0)/* * Multiplication algorithms: *//* Given a 1W * 1W => 2W primitive, do the extended multiplication. */#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \ do { \ _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ \ doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ doit(_b_f1, _b_f0, X##_f0, Y##_f1); \ doit(_c_f1, _c_f0, X##_f1, Y##_f0); \ doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \ \ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ _FP_FRAC_WORD_4(_z,1), 0, _b_f1, _b_f0, \ _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ _FP_FRAC_WORD_4(_z,1)); \ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0, \ _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ _FP_FRAC_WORD_4(_z,1)); \ \ /* Normalize since we know where the msb of the multiplicands \ were (bit B), we know that the msb of the of the product is \ at either 2B or 2B-1. */ \ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ R##_f0 = _FP_FRAC_WORD_4(_z,0); \ R##_f1 = _FP_FRAC_WORD_4(_z,1); \ } while (0)/* Given a 1W * 1W => 2W primitive, do the extended multiplication. Do only 3 multiplications instead of four. This one is for machines where multiplication is much more expensive than subtraction. */#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \ do { \ _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ _FP_W_TYPE _d; \ int _c1, _c2; \ \ _b_f0 = X##_f0 + X##_f1; \ _c1 = _b_f0 < X##_f0; \ _b_f1 = Y##_f0 + Y##_f1; \ _c2 = _b_f1 < Y##_f0; \ doit(_d, _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ doit(_FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1), _b_f0, _b_f1); \ doit(_c_f1, _c_f0, X##_f1, Y##_f1); \ \ _b_f0 &= -_c2; \ _b_f1 &= -_c1; \ __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ _FP_FRAC_WORD_4(_z,1), (_c1 & _c2), 0, _d, \ 0, _FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1)); \ __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ _b_f0); \ __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ _b_f1); \ __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ _FP_FRAC_WORD_4(_z,1), \ 0, _d, _FP_FRAC_WORD_4(_z,0)); \ __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0); \ __FP_FRAC_ADD_2(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), \ _c_f1, _c_f0, \ _FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2)); \ \ /* Normalize since we know where the msb of the multiplicands \ were (bit B), we know that the msb of the of the product is \ at either 2B or 2B-1. */ \ _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ R##_f0 = _FP_FRAC_WORD_4(_z,0); \ R##_f1 = _FP_FRAC_WORD_4(_z,1); \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -