diff options
author | John Hauser <jhauser@eecs.berkeley.edu> | 2017-08-10 16:26:24 -0700 |
---|---|---|
committer | John Hauser <jhauser@eecs.berkeley.edu> | 2017-08-10 16:26:24 -0700 |
commit | db047c521e07644199a679db36d842c05959e067 (patch) | |
tree | 2071959425595ce5ed7590597edd149fa995f584 /source/extF80_sqrt.c | |
parent | 9d731d45e86ae28cf13b0094979577061e0e811c (diff) | |
download | berkeley-softfloat-3-db047c521e07644199a679db36d842c05959e067.zip berkeley-softfloat-3-db047c521e07644199a679db36d842c05959e067.tar.gz berkeley-softfloat-3-db047c521e07644199a679db36d842c05959e067.tar.bz2 |
Release 3d. See "doc/SoftFloat-history.html".
Diffstat (limited to 'source/extF80_sqrt.c')
-rw-r--r-- | source/extF80_sqrt.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/source/extF80_sqrt.c b/source/extF80_sqrt.c index d120125..4c19af3 100644 --- a/source/extF80_sqrt.c +++ b/source/extF80_sqrt.c @@ -2,10 +2,10 @@ /*============================================================================ This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3c, by John R. Hauser. +Package, Release 3d, by John R. Hauser. -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -56,8 +56,8 @@ extFloat80_t extF80_sqrt( extFloat80_t a ) int_fast32_t expZ; uint_fast32_t sig32A, recipSqrt32, sig32Z; struct uint128 rem; - uint_fast64_t q, sigZ, x64; - struct uint128 term; + uint_fast64_t q, x64, sigZ; + struct uint128 y, term; uint_fast64_t sigZExtra; union { struct extFloat80M s; extFloat80_t f; } uZ; @@ -116,14 +116,22 @@ extFloat80_t extF80_sqrt( extFloat80_t a ) /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ q = ((uint32_t) (rem.v64>>2) * (uint_fast64_t) recipSqrt32)>>32; - sigZ = ((uint_fast64_t) sig32Z<<32) + (q<<3); - x64 = ((uint_fast64_t) sig32Z<<32) + sigZ; - term = softfloat_mul64ByShifted32To128( x64, q ); - rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); - rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); + x64 = (uint_fast64_t) sig32Z<<32; + sigZ = x64 + (q<<3); + y = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); /*------------------------------------------------------------------------ + | (Repeating this loop is a rare occurrence.) *------------------------------------------------------------------------*/ - q = (((uint32_t) (rem.v64>>2) * (uint_fast64_t) recipSqrt32)>>32) + 2; + for (;;) { + term = softfloat_mul64ByShifted32To128( x64 + sigZ, q ); + rem = softfloat_sub128( y.v64, y.v0, term.v64, term.v0 ); + if ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ) break; + --q; + sigZ -= 1<<3; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + q = (((rem.v64>>2) * recipSqrt32)>>32) + 2; x64 = sigZ; sigZ = (sigZ<<1) + (q>>25); sigZExtra = (uint64_t) (q<<39); |