📄 op-4.h
字号:
} while (0)/* * Helper utility for _FP_DIV_MEAT_4_udiv: * pppp = m * nnn */#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0) \ do { \ UWtype _t; \ umul_ppmm(p1,p0,m,n0); \ umul_ppmm(p2,_t,m,n1); \ __FP_FRAC_ADDI_2(p2,p1,_t); \ umul_ppmm(p3,_t,m,n2); \ __FP_FRAC_ADDI_2(p3,p2,_t); \ } while (0)/* * Division algorithms: */#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \ do { \ int _i; \ _FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m); \ _FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4); \ if (_FP_FRAC_GT_4(X, Y)) \ { \ _n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \ _FP_FRAC_SRL_4(X, 1); \ } \ else \ R##_e--; \ \ /* Normalize, i.e. make the most significant bit of the \ denominator set. */ \ _FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs); \ \ for (_i = 3; ; _i--) \ { \ if (X##_f[3] == Y##_f[3]) \ { \ /* This is a special case, not an optimization \ (X##_f[3]/Y##_f[3] would not fit into UWtype). \ As X## is guaranteed to be < Y, R##_f[_i] can be either \ (UWtype)-1 or (UWtype)-2. */ \ R##_f[_i] = -1; \ if (!_i) \ break; \ __FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ Y##_f[2], Y##_f[1], Y##_f[0], 0, \ X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \ _FP_FRAC_SUB_4(X, Y, X); \ if (X##_f[3] > Y##_f[3]) \ { \ R##_f[_i] = -2; \ _FP_FRAC_ADD_4(X, Y, X); \ } \ } \ else \ { \ udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \ umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0], \ R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \ X##_f[2] = X##_f[1]; \ X##_f[1] = X##_f[0]; \ X##_f[0] = _n_f[_i]; \ if (_FP_FRAC_GT_4(_m, X)) \ { \ R##_f[_i]--; \ _FP_FRAC_ADD_4(X, Y, X); \ if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X)) \ { \ R##_f[_i]--; \ _FP_FRAC_ADD_4(X, Y, X); \ } \ } \ _FP_FRAC_DEC_4(X, _m); \ if (!_i) \ { \ if (!_FP_FRAC_EQ_4(X, _m)) \ R##_f[0] |= _FP_WORK_STICKY; \ break; \ } \ } \ } \ } while (0)/* * Square root algorithms: * We have just one right now, maybe Newton approximation * should be added for those machines where division is fast. */ #define _FP_SQRT_MEAT_4(R, S, T, X, q) \ do { \ while (q) \ { \ T##_f[3] = S##_f[3] + q; \ if (T##_f[3] <= X##_f[3]) \ { \ S##_f[3] = T##_f[3] + q; \ X##_f[3] -= T##_f[3]; \ R##_f[3] += q; \ } \ _FP_FRAC_SLL_4(X, 1); \ q >>= 1; \ } \ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ while (q) \ { \ T##_f[2] = S##_f[2] + q; \ T##_f[3] = S##_f[3]; \ if (T##_f[3] < X##_f[3] || \ (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \ { \ S##_f[2] = T##_f[2] + q; \ S##_f[3] += (T##_f[2] > S##_f[2]); \ __FP_FRAC_DEC_2(X##_f[3], X##_f[2], \ T##_f[3], T##_f[2]); \ R##_f[2] += q; \ } \ _FP_FRAC_SLL_4(X, 1); \ q >>= 1; \ } \ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ while (q) \ { \ T##_f[1] = S##_f[1] + q; \ T##_f[2] = S##_f[2]; \ T##_f[3] = S##_f[3]; \ if (T##_f[3] < X##_f[3] || \ (T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] || \ (T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1])))) \ { \ S##_f[1] = T##_f[1] + q; \ S##_f[2] += (T##_f[1] > S##_f[1]); \ S##_f[3] += (T##_f[2] > S##_f[2]); \ __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1], \ T##_f[3], T##_f[2], T##_f[1]); \ R##_f[1] += q; \ } \ _FP_FRAC_SLL_4(X, 1); \ q >>= 1; \ } \ q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ while (q != _FP_WORK_ROUND) \ { \ T##_f[0] = S##_f[0] + q; \ T##_f[1] = S##_f[1]; \ T##_f[2] = S##_f[2]; \ T##_f[3] = S##_f[3]; \ if (_FP_FRAC_GE_4(X,T)) \ { \ S##_f[0] = T##_f[0] + q; \ S##_f[1] += (T##_f[0] > S##_f[0]); \ S##_f[2] += (T##_f[1] > S##_f[1]); \ S##_f[3] += (T##_f[2] > S##_f[2]); \ _FP_FRAC_DEC_4(X, T); \ R##_f[0] += q; \ } \ _FP_FRAC_SLL_4(X, 1); \ q >>= 1; \ } \ if (!_FP_FRAC_ZEROP_4(X)) \ { \ if (_FP_FRAC_GT_4(X,S)) \ R##_f[0] |= _FP_WORK_ROUND; \ R##_f[0] |= _FP_WORK_STICKY; \ } \ } while (0)/* * Internals */#define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \ (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)#ifndef __FP_FRAC_ADD_3#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ (r0 = x0 + y0, \ r1 = x1 + y1 + (r0 < x0), \ r2 = x2 + y2 + (r1 < x1))#endif#ifndef __FP_FRAC_ADD_4#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ (r0 = x0 + y0, \ r1 = x1 + y1 + (r0 < x0), \ r2 = x2 + y2 + (r1 < x1), \ r3 = x3 + y3 + (r2 < x2))#endif#ifndef __FP_FRAC_SUB_3#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ (r0 = x0 - y0, \ r1 = x1 - y1 - (r0 > x0), \ r2 = x2 - y2 - (r1 > x1))#endif#ifndef __FP_FRAC_SUB_4#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ (r0 = x0 - y0, \ r1 = x1 - y1 - (r0 > x0), \ r2 = x2 - y2 - (r1 > x1), \ r3 = x3 - y3 - (r2 > x2))#endif#ifndef __FP_FRAC_DEC_3#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) \ do { \ UWtype _t0, _t1; \ _t0 = x0; \ x0 -= y0; \ _t1 = x1; \ x1 -= y1 + (x0 > _t0); \ x2 -= y2 + (x1 > _t1); \ } while (0)#endif#ifndef __FP_FRAC_DEC_4#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) \ do { \ UWtype _t0, _t1; \ _t0 = x0; \ x0 -= y0; \ _t1 = x1; \ x1 -= y1 + (x0 > _t0); \ _t0 = x2; \ x2 -= y2 + (x1 > _t1); \ x3 -= y3 + (x2 > _t0); \ } while (0)#endif#ifndef __FP_FRAC_ADDI_4#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ do { \ UWtype _t; \ _t = ((x0 += i) < i); \ x1 += _t; _t = (x1 < _t); \ x2 += _t; _t = (x2 < _t); \ x3 += _t; \ } while (0)#endif/* Convert FP values between word sizes. This appears to be more * complicated than I'd have expected it to be, so these might be * wrong... These macros are in any case somewhat bogus because they * use information about what various FRAC_n variables look like * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do * the ones in op-2.h and op-1.h. */#define _FP_FRAC_CONV_1_4(dfs, sfs, D, S) \ do { \ if (S##_c != FP_CLS_NAN) \ _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \ _FP_WFRACBITS_##sfs); \ else \ _FP_FRAC_SRL_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs)); \ D##_f = S##_f[0]; \ } while (0)#define _FP_FRAC_CONV_2_4(dfs, sfs, D, S) \ do { \ if (S##_c != FP_CLS_NAN) \ _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \ _FP_WFRACBITS_##sfs); \ else \ _FP_FRAC_SRL_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs)); \ D##_f0 = S##_f[0]; \ D##_f1 = S##_f[1]; \ } while (0)/* Assembly/disassembly for converting to/from integral types. * No shifting or overflow handled here. *//* Put the FP value X into r, which is an integer of size rsize. */#define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \ do { \ if (rsize <= _FP_W_TYPE_SIZE) \ r = X##_f[0]; \ else if (rsize <= 2*_FP_W_TYPE_SIZE) \ { \ r = X##_f[1]; \ r <<= _FP_W_TYPE_SIZE; \ r += X##_f[0]; \ } \ else \ { \ /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \ /* and int == 4words as a single case. */ \ r = X##_f[3]; \ r <<= _FP_W_TYPE_SIZE; \ r += X##_f[2]; \ r <<= _FP_W_TYPE_SIZE; \ r += X##_f[1]; \ r <<= _FP_W_TYPE_SIZE; \ r += X##_f[0]; \ } \ } while (0)/* "No disassemble Number Five!" *//* move an integer of size rsize into X's fractional part. We rely on * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid * having to mask the values we store into it. */#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \ do { \ X##_f[0] = r; \ X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \ X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \ } while (0);#define _FP_FRAC_CONV_4_1(dfs, sfs, D, S) \ do { \ D##_f[0] = S##_f; \ D##_f[1] = D##_f[2] = D##_f[3] = 0; \ _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \ } while (0)#define _FP_FRAC_CONV_4_2(dfs, sfs, D, S) \ do { \ D##_f[0] = S##_f0; \ D##_f[1] = S##_f1; \ D##_f[2] = D##_f[3] = 0; \ _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \ } while (0)#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -