From 1a8aaf919dfdacf7fd31be9cb36cad8cb9875f0f Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 17 Oct 2002 23:16:26 +0000 Subject: Update. 2002-10-08 Richard Henderson * soft-fp/op-4.h: Handle carry correctly in __FP_FRAC_ADD_3, __FP_FRAC_ADD_4, __FP_FRAC_SUB_3, __FP_FRAC_SUB_4, __FP_FRAC_DEC_3, __FP_FRAC_DEC_4. * soft-fp/op-common.h: New macros _FP_DIV_MEAT_N_loop. 2002-10-08 Aldy Hernandez * configure.in: Compute completely-soft. * config.make.in: Make completely-soft available to sub-makes. * sysdeps/powerpc/soft-fp/Makefile: Add gcc-single-routines and gcc-double-routines. Add sim-full.c. Add fenv_const and fe_nomask to libm-support. * sysdeps/powerpc/soft-fp/sim-full.c: New file. * sysdeps/powerpc/soft-fp/fraiseexcpt.c: New file. * sysdeps/powerpc/soft-fp/fegetexcept.c: New file. * sysdeps/powerpc/soft-fp/fclrexcpt.c: New file. * sysdeps/powerpc/soft-fp/ftestexcept.c: New file. * sysdeps/powerpc/soft-fp/fgetexcptflg.c: New file. * sysdeps/powerpc/soft-fp/fsetexcptflg.c: New file. * sysdeps/powerpc/soft-fp/fedisblxcpt.c: New file. * sysdeps/powerpc/soft-fp/feenablxcpt.c: New file. * sysdeps/powerpc/soft-fp/fegetenv.c: New file. * sysdeps/powerpc/soft-fp/fesetenv.c: New file. * sysdeps/powerpc/soft-fp/fegetround.c: New file. * sysdeps/powerpc/soft-fp/fesetround.c: New file. * sysdeps/powerpc/soft-fp/feupdateenv.c: New file. * sysdeps/powerpc/soft-fp/feholdexcpt.c: New file. * sysdeps/powerpc/soft-fp/fenv_const.c: New file. * sysdeps/powerpc/soft-fp/libm-test-ulps: New file. * sysdeps/powerpc/soft-fp/Versions: Add libgcc soft-float symbols. Add __sim_disabled_exceptions, __sim_exceptions, __sim_round_mode. * sysdeps/powerpc/soft-float/Dist: Add sim-full.c, fenv_const.c. * sysdeps/powerpc/soft-float/sfp-machine.h: Define FP_HANDLE_EXCEPTIONS. Define FP_ROUNDMODE. Redefine FP_* macros to correspond to the FE_* bit positions. Define FP_DIV_MEAT_S to _FP_DIV_MEAT_1_loop. Define externs for __sim_exceptions, __sim_disabled_exceptions, __sim_round_mode, __simulate_exceptions. * sysdeps/powerpc/fpu/bits/fenv.h: Move file from here... * sysdeps/powerpc/bits/fenv.h: ...to here. 2002-10-06 Jakub Jelinek * sysdeps/powerpc/powerpc32/dl-machine.c (__process_machine_rela): Store R_PPC_UADDR32 and R_PPC_UADDR16 one byte at a time. Use __builtin_expect for R_PPC_ADDR24 overflow check. Fix R_PPC_ADDR16, R_PPC_UADDR16 and R_PPC_ADDR14* overflow check, use __builtin_expect. --- soft-fp/op-4.h | 90 ++++++++++++++++++++++++++++++++++------------------- soft-fp/op-common.h | 44 ++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 32 deletions(-) (limited to 'soft-fp') diff --git a/soft-fp/op-4.h b/soft-fp/op-4.h index bbfd433a86..404cb22848 100644 --- a/soft-fp/op-4.h +++ b/soft-fp/op-4.h @@ -510,58 +510,84 @@ (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)) +#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ + do { \ + int _c1, _c2; \ + r0 = x0 + y0; \ + _c1 = r0 < x0; \ + r1 = x1 + y1; \ + _c2 = r1 < x1; \ + r1 += _c1; \ + _c2 |= r1 < _c1; \ + r2 = x2 + y2 + _c2; \ + } while (0) #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)) +#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ + do { \ + int _c1, _c2, _c3; \ + r0 = x0 + y0; \ + _c1 = r0 < x0; \ + r1 = x1 + y1; \ + _c2 = r1 < x1; \ + r1 += _c1; \ + _c2 |= r1 < _c1; \ + r2 = x2 + y2; \ + _c3 = r2 < x2; \ + r2 += _c2; \ + _c3 |= r2 < _c2; \ + r3 = x3 + y3 + _c3; \ + } while (0) #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)) +#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ + do { \ + int _c1, _c2; \ + r0 = x0 - y0; \ + _c1 = r0 > x0; \ + r1 = x1 - y1; \ + _c2 = r1 > x1; \ + r1 -= _c1; \ + _c2 |= r1 > _c1; \ + r2 = x2 - y2 - _c2; \ + } while (0) #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)) +#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ + do { \ + int _c1, _c2, _c3; \ + r0 = x0 - y0; \ + _c1 = r0 > x0; \ + r1 = x1 - y1; \ + _c2 = r1 > x1; \ + r1 -= _c1; \ + _c2 |= r1 > _c1; \ + r2 = x2 - y2; \ + _c3 = r2 > x2; \ + r2 -= _c2; \ + _c3 |= r2 > _c2; \ + r3 = x3 - y3 - _c3; \ + } while (0) #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); \ + UWtype _t0, _t1, _t2; \ + _t0 = x0, _t1 = x1, _t2 = x2; \ + __FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \ } 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); \ + UWtype _t0, _t1, _t2, _t3; \ + _t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \ + __FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0); \ } while (0) #endif diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h index 232604e74a..3abafa14a8 100644 --- a/soft-fp/op-common.h +++ b/soft-fp/op-common.h @@ -766,3 +766,47 @@ do { \ q = n / d, r = n % d; \ } while (0) + +/* A restoring bit-by-bit division primitive. */ + +#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \ + do { \ + int count = _FP_WFRACBITS_##fs; \ + _FP_FRAC_DECL_##wc (u); \ + _FP_FRAC_DECL_##wc (v); \ + _FP_FRAC_COPY_##wc (u, X); \ + _FP_FRAC_COPY_##wc (v, Y); \ + _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ + /* Normalize U and V. */ \ + _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \ + _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \ + /* First round. Since the operands are normalized, either the \ + first or second bit will be set in the fraction. Produce a \ + normalized result by checking which and adjusting the loop \ + count and exponent accordingly. */ \ + if (_FP_FRAC_GE_1 (u, v)) \ + { \ + _FP_FRAC_SUB_##wc (u, u, v); \ + _FP_FRAC_LOW_##wc (R) |= 1; \ + count--; \ + } \ + else \ + R##_e--; \ + /* Subsequent rounds. */ \ + do { \ + int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \ + _FP_FRAC_SLL_##wc (u, 1); \ + _FP_FRAC_SLL_##wc (R, 1); \ + if (msb || _FP_FRAC_GE_1 (u, v)) \ + { \ + _FP_FRAC_SUB_##wc (u, u, v); \ + _FP_FRAC_LOW_##wc (R) |= 1; \ + } \ + } while (--count > 0); \ + /* If there's anything left in U, the result is inexact. */ \ + _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \ + } while (0) + +#define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y) +#define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y) +#define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y) -- cgit v1.2.3