Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
f128M_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 f128M_sqrt.c:

Go to the source code of this file.

Functions

void f128M_sqrt (const float128_t *aPtr, float128_t *zPtr)
 

Function Documentation

◆ f128M_sqrt()

void f128M_sqrt ( const float128_t * aPtr,
float128_t * zPtr )

Definition at line 55 of file f128M_sqrt.c.

56{
57 const uint32_t *aWPtr;
58 uint32_t *zWPtr;
59 uint32_t uiA96;
60 bool signA;
61 int32_t rawExpA;
62 uint32_t rem[6];
63 int32_t expA, expZ;
64 uint64_t rem64;
65 uint32_t sig32A, recipSqrt32, sig32Z, qs[3], q;
66 uint64_t sig64Z;
67 uint32_t term[5];
68 uint64_t x64;
69 uint32_t y[5], rem32;
70
71 /*------------------------------------------------------------------------
72 *------------------------------------------------------------------------*/
73 aWPtr = (const uint32_t *) aPtr;
74 zWPtr = (uint32_t *) zPtr;
75 /*------------------------------------------------------------------------
76 *------------------------------------------------------------------------*/
77 uiA96 = aWPtr[indexWordHi( 4 )];
78 signA = signF128UI96( uiA96 );
79 rawExpA = expF128UI96( uiA96 );
80 /*------------------------------------------------------------------------
81 *------------------------------------------------------------------------*/
82 if ( rawExpA == 0x7FFF ) {
83 if (
84 fracF128UI96( uiA96 )
85 || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )]
86 | aWPtr[indexWord( 4, 0 )])
87 ) {
88 softfloat_propagateNaNF128M( aWPtr, 0, zWPtr );
89 return;
90 }
91 if ( ! signA ) goto copyA;
92 goto invalid;
93 }
94 /*------------------------------------------------------------------------
95 *------------------------------------------------------------------------*/
96 expA = softfloat_shiftNormSigF128M( aWPtr, 13 - (rawExpA & 1), rem );
97 if ( expA == -128 ) goto copyA;
98 if ( signA ) goto invalid;
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) + 0x3FFE;
105 expA &= 1;
106 rem64 = (uint64_t) rem[indexWord( 4, 3 )]<<32 | rem[indexWord( 4, 2 )];
107 if ( expA ) {
108 if ( ! rawExpA ) {
109 softfloat_shortShiftRight128M( rem, 1, rem );
110 rem64 >>= 1;
111 }
112 sig32A = rem64>>29;
113 } else {
114 sig32A = rem64>>30;
115 }
116 recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A );
117 sig32Z = ((uint64_t) sig32A * recipSqrt32)>>32;
118 if ( expA ) sig32Z >>= 1;
119 qs[2] = sig32Z;
120 rem64 -= (uint64_t) sig32Z * sig32Z;
121 rem[indexWord( 4, 3 )] = rem64>>32;
122 rem[indexWord( 4, 2 )] = rem64;
123 /*------------------------------------------------------------------------
124 *------------------------------------------------------------------------*/
125 q = ((uint32_t) (rem64>>2) * (uint64_t) recipSqrt32)>>32;
126 sig64Z = ((uint64_t) sig32Z<<32) + ((uint64_t) q<<3);
127 term[indexWord( 4, 3 )] = 0;
128 term[indexWord( 4, 0 )] = 0;
129 /*------------------------------------------------------------------------
130 | (Repeating this loop is a rare occurrence.)
131 *------------------------------------------------------------------------*/
132 for (;;) {
133 x64 = ((uint64_t) sig32Z<<32) + sig64Z;
134 term[indexWord( 4, 2 )] = x64>>32;
135 term[indexWord( 4, 1 )] = x64;
136 softfloat_remStep128MBy32( rem, 29, term, q, y );
137 rem32 = y[indexWord( 4, 3 )];
138 if ( ! (rem32 & 0x80000000) ) break;
139 --q;
140 sig64Z -= 1<<3;
141 }
142 qs[1] = q;
143 rem64 = (uint64_t) rem32<<32 | y[indexWord( 4, 2 )];
144 /*------------------------------------------------------------------------
145 *------------------------------------------------------------------------*/
146 q = ((uint32_t) (rem64>>2) * (uint64_t) recipSqrt32)>>32;
147 if ( rem64>>34 ) q += recipSqrt32;
148 sig64Z <<= 1;
149 /*------------------------------------------------------------------------
150 | (Repeating this loop is a rare occurrence.)
151 *------------------------------------------------------------------------*/
152 for (;;) {
153 x64 = sig64Z + (q>>26);
154 term[indexWord( 4, 2 )] = x64>>32;
155 term[indexWord( 4, 1 )] = x64;
156 term[indexWord( 4, 0 )] = q<<6;
158 y, 29, term, q, &rem[indexMultiwordHi( 6, 4 )] );
159 rem32 = rem[indexWordHi( 6 )];
160 if ( ! (rem32 & 0x80000000) ) break;
161 --q;
162 }
163 qs[0] = q;
164 rem64 = (uint64_t) rem32<<32 | rem[indexWord( 6, 4 )];
165 /*------------------------------------------------------------------------
166 *------------------------------------------------------------------------*/
167 q = (((uint32_t) (rem64>>2) * (uint64_t) recipSqrt32)>>32) + 2;
168 if ( rem64>>34 ) q += recipSqrt32;
169 x64 = (uint64_t) q<<27;
170 y[indexWord( 5, 0 )] = x64;
171 x64 = ((uint64_t) qs[0]<<24) + (x64>>32);
172 y[indexWord( 5, 1 )] = x64;
173 x64 = ((uint64_t) qs[1]<<21) + (x64>>32);
174 y[indexWord( 5, 2 )] = x64;
175 x64 = ((uint64_t) qs[2]<<18) + (x64>>32);
176 y[indexWord( 5, 3 )] = x64;
177 y[indexWord( 5, 4 )] = x64>>32;
178 /*------------------------------------------------------------------------
179 *------------------------------------------------------------------------*/
180 if ( (q & 0xF) <= 2 ) {
181 q &= ~3;
182 y[indexWordLo( 5 )] = q<<27;
183 term[indexWord( 5, 4 )] = 0;
184 term[indexWord( 5, 3 )] = 0;
185 term[indexWord( 5, 2 )] = 0;
186 term[indexWord( 5, 1 )] = q>>6;
187 term[indexWord( 5, 0 )] = q<<26;
188 softfloat_sub160M( y, term, term );
189 rem[indexWord( 6, 1 )] = 0;
190 rem[indexWord( 6, 0 )] = 0;
192 &rem[indexMultiwordLo( 6, 5 )],
193 14,
194 term,
195 q,
196 &rem[indexMultiwordLo( 6, 5 )]
197 );
198 rem32 = rem[indexWord( 6, 4 )];
199 if ( rem32 & 0x80000000 ) {
201 } else {
202 if (
203 rem32 || rem[indexWord( 6, 0 )] || rem[indexWord( 6, 1 )]
204 || (rem[indexWord( 6, 3 )] | rem[indexWord( 6, 2 )])
205 ) {
206 y[indexWordLo( 5 )] |= 1;
207 }
208 }
209 }
210 softfloat_roundPackMToF128M( 0, expZ, y, zWPtr );
211 return;
212 /*------------------------------------------------------------------------
213 *------------------------------------------------------------------------*/
214 invalid:
215 softfloat_invalidF128M( zWPtr );
216 return;
217 /*------------------------------------------------------------------------
218 *------------------------------------------------------------------------*/
219 copyA:
220 zWPtr[indexWordHi( 4 )] = uiA96;
221 zWPtr[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )];
222 zWPtr[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )];
223 zWPtr[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )];
224
225}
uint64_t y
Definition sha3.cpp:34
void softfloat_propagateNaNF128M(const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr)
void softfloat_invalidF128M(uint32_t *)
#define fracF128UI96(a96)
Definition internals.h:249
void softfloat_roundPackMToF128M(bool, int32_t, uint32_t *, uint32_t *)
int softfloat_shiftNormSigF128M(const uint32_t *, uint_fast8_t, uint32_t *)
#define signF128UI96(a96)
Definition internals.h:247
#define expF128UI96(a96)
Definition internals.h:248
#define indexMultiwordHi(total, n)
#define indexMultiwordLo(total, n)
#define indexWordLo(total)
#define indexWord(total, n)
#define indexWordHi(total)
#define softfloat_sub1X160M(zPtr)
#define softfloat_remStep128MBy32(remPtr, dist, bPtr, q, zPtr)
#define softfloat_sub160M(aPtr, bPtr, zPtr)
#define softfloat_remStep160MBy32(remPtr, dist, bPtr, q, zPtr)
uint32_t softfloat_approxRecipSqrt32_1(unsigned int oddExpA, uint32_t a)
#define softfloat_shortShiftRight128M(aPtr, dist, zPtr)
Definition primitives.h:782
unsigned int uint32_t
Definition stdint.h:126
signed int int32_t
Definition stdint.h:123
unsigned __int64 uint64_t
Definition stdint.h:136
Here is the call graph for this function: