Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
extF80_sqrt.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include "platform.h"
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
Include dependency graph for extF80_sqrt.c:

Go to the source code of this file.

Functions

extFloat80_t extF80_sqrt (extFloat80_t a)
 

Function Documentation

◆ extF80_sqrt()

extFloat80_t extF80_sqrt ( extFloat80_t a)

Definition at line 44 of file extF80_sqrt.c.

45{
46 union { struct extFloat80M s; extFloat80_t f; } uA;
47 uint_fast16_t uiA64;
48 uint_fast64_t uiA0;
49 bool signA;
50 int_fast32_t expA;
51 uint_fast64_t sigA;
52 struct uint128 uiZ;
53 uint_fast16_t uiZ64;
54 uint_fast64_t uiZ0;
55 struct exp32_sig64 normExpSig;
56 int_fast32_t expZ;
57 uint_fast32_t sig32A, recipSqrt32, sig32Z;
58 struct uint128 rem;
59 uint_fast64_t q, x64, sigZ;
60 struct uint128 y, term;
61 uint_fast64_t sigZExtra;
62 union { struct extFloat80M s; extFloat80_t f; } uZ;
63
64 /*------------------------------------------------------------------------
65 *------------------------------------------------------------------------*/
66 uA.f = a;
67 uiA64 = uA.s.signExp;
68 uiA0 = uA.s.signif;
69 signA = signExtF80UI64( uiA64 );
70 expA = expExtF80UI64( uiA64 );
71 sigA = uiA0;
72 /*------------------------------------------------------------------------
73 *------------------------------------------------------------------------*/
74 if ( expA == 0x7FFF ) {
75 if ( sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) {
76 uiZ = softfloat_propagateNaNExtF80UI( uiA64, uiA0, 0, 0 );
77 uiZ64 = uiZ.v64;
78 uiZ0 = uiZ.v0;
79 goto uiZ;
80 }
81 if ( ! signA ) return a;
82 goto invalid;
83 }
84 /*------------------------------------------------------------------------
85 *------------------------------------------------------------------------*/
86 if ( signA ) {
87 if ( ! sigA ) goto zero;
88 goto invalid;
89 }
90 /*------------------------------------------------------------------------
91 *------------------------------------------------------------------------*/
92 if ( ! expA ) expA = 1;
93 if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) {
94 if ( ! sigA ) goto zero;
95 normExpSig = softfloat_normSubnormalExtF80Sig( sigA );
96 expA += normExpSig.exp;
97 sigA = normExpSig.sig;
98 }
99 /*------------------------------------------------------------------------
100 | (`sig32Z' is guaranteed to be a lower bound on the square root of
101 | `sig32A', which makes `sig32Z' also a lower bound on the square root of
102 | `sigA'.)
103 *------------------------------------------------------------------------*/
104 expZ = ((expA - 0x3FFF)>>1) + 0x3FFF;
105 expA &= 1;
106 sig32A = sigA>>32;
107 recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A );
108 sig32Z = ((uint_fast64_t) sig32A * recipSqrt32)>>32;
109 if ( expA ) {
110 sig32Z >>= 1;
111 rem = softfloat_shortShiftLeft128( 0, sigA, 61 );
112 } else {
113 rem = softfloat_shortShiftLeft128( 0, sigA, 62 );
114 }
115 rem.v64 -= (uint_fast64_t) sig32Z * sig32Z;
116 /*------------------------------------------------------------------------
117 *------------------------------------------------------------------------*/
118 q = ((uint32_t) (rem.v64>>2) * (uint_fast64_t) recipSqrt32)>>32;
119 x64 = (uint_fast64_t) sig32Z<<32;
120 sigZ = x64 + (q<<3);
121 y = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );
122 /*------------------------------------------------------------------------
123 | (Repeating this loop is a rare occurrence.)
124 *------------------------------------------------------------------------*/
125 for (;;) {
126 term = softfloat_mul64ByShifted32To128( x64 + sigZ, q );
127 rem = softfloat_sub128( y.v64, y.v0, term.v64, term.v0 );
128 if ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ) break;
129 --q;
130 sigZ -= 1<<3;
131 }
132 /*------------------------------------------------------------------------
133 *------------------------------------------------------------------------*/
134 q = (((rem.v64>>2) * recipSqrt32)>>32) + 2;
135 x64 = sigZ;
136 sigZ = (sigZ<<1) + (q>>25);
137 sigZExtra = (uint64_t) (q<<39);
138 /*------------------------------------------------------------------------
139 *------------------------------------------------------------------------*/
140 if ( (q & 0xFFFFFF) <= 2 ) {
141 q &= ~(uint_fast64_t) 0xFFFF;
142 sigZExtra = (uint64_t) (q<<39);
143 term = softfloat_mul64ByShifted32To128( x64 + (q>>27), q );
144 x64 = (uint32_t) (q<<5) * (uint_fast64_t) (uint32_t) q;
145 term = softfloat_add128( term.v64, term.v0, 0, x64 );
146 rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 28 );
147 rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
148 if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
149 if ( ! sigZExtra ) --sigZ;
150 --sigZExtra;
151 } else {
152 if ( rem.v64 | rem.v0 ) sigZExtra |= 1;
153 }
154 }
155 return
157 0, expZ, sigZ, sigZExtra, extF80_roundingPrecision );
158 /*------------------------------------------------------------------------
159 *------------------------------------------------------------------------*/
160 invalid:
162 uiZ64 = defaultNaNExtF80UI64;
163 uiZ0 = defaultNaNExtF80UI0;
164 goto uiZ;
165 /*------------------------------------------------------------------------
166 *------------------------------------------------------------------------*/
167 zero:
168 uiZ64 = packToExtF80UI64( signA, 0 );
169 uiZ0 = 0;
170 uiZ:
171 uZ.s.signExp = uiZ64;
172 uZ.s.signif = uiZ0;
173 return uZ.f;
174
175}
uint64_t y
Definition sha3.cpp:34
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0)
void softfloat_raiseFlags(uint_fast8_t flags)
#define defaultNaNExtF80UI0
Definition specialize.h:194
#define defaultNaNExtF80UI64
Definition specialize.h:193
#define packToExtF80UI64(sign, exp)
Definition internals.h:148
#define expExtF80UI64(a64)
Definition internals.h:147
#define signExtF80UI64(a64)
Definition internals.h:146
uint32_t softfloat_approxRecipSqrt32_1(unsigned int oddExpA, uint32_t a)
THREAD_LOCAL uint_fast8_t extF80_roundingPrecision
@ softfloat_flag_invalid
Definition softfloat.h:89
struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
Definition s_add128.c:44
struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b)
struct exp32_sig64 softfloat_normSubnormalExtF80Sig(uint_fast64_t sig)
extFloat80_t softfloat_roundPackToExtF80(bool sign, int_fast32_t exp, uint_fast64_t sig, uint_fast64_t sigExtra, uint_fast8_t roundingPrecision)
struct uint128 softfloat_shortShiftLeft128(uint64_t a64, uint64_t a0, uint_fast8_t dist)
struct uint128 softfloat_sub128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
Definition s_sub128.c:44
unsigned int uint32_t
Definition stdint.h:126
uint16_t uint_fast16_t
Definition stdint.h:155
uint64_t uint_fast64_t
Definition stdint.h:157
#define UINT64_C(val)
Definition stdint.h:284
uint32_t uint_fast32_t
Definition stdint.h:156
int32_t int_fast32_t
Definition stdint.h:152
unsigned __int64 uint64_t
Definition stdint.h:136
char * s
Here is the call graph for this function: