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

Go to the source code of this file.

Functions

void extF80M_sqrt (const extFloat80_t *aPtr, extFloat80_t *zPtr)
 

Function Documentation

◆ extF80M_sqrt()

void extF80M_sqrt ( const extFloat80_t * aPtr,
extFloat80_t * zPtr )

Definition at line 55 of file extF80M_sqrt.c.

56{
57 const struct extFloat80M *aSPtr;
58 struct extFloat80M *zSPtr;
59 uint_fast16_t uiA64, signUI64;
60 int32_t expA;
61 uint64_t rem64;
62 int32_t expZ;
63 uint32_t rem96[3], sig32A, recipSqrt32, sig32Z, q;
64 uint64_t sig64Z, x64;
65 uint32_t rem32, term[4], rem[4], extSigZ[3];
66
67 /*------------------------------------------------------------------------
68 *------------------------------------------------------------------------*/
69 aSPtr = (const struct extFloat80M *) aPtr;
70 zSPtr = (struct extFloat80M *) zPtr;
71 /*------------------------------------------------------------------------
72 *------------------------------------------------------------------------*/
73 uiA64 = aSPtr->signExp;
74 signUI64 = uiA64 & packToExtF80UI64( 1, 0 );
75 expA = expExtF80UI64( uiA64 );
76 rem64 = aSPtr->signif;
77 /*------------------------------------------------------------------------
78 *------------------------------------------------------------------------*/
79 if ( expA == 0x7FFF ) {
80 if ( rem64 & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) {
81 softfloat_propagateNaNExtF80M( aSPtr, 0, zSPtr );
82 return;
83 }
84 if ( signUI64 ) goto invalid;
85 rem64 = UINT64_C( 0x8000000000000000 );
86 goto copyA;
87 }
88 /*------------------------------------------------------------------------
89 *------------------------------------------------------------------------*/
90 if ( ! expA ) expA = 1;
91 if ( ! (rem64 & UINT64_C( 0x8000000000000000 )) ) {
92 if ( ! rem64 ) {
93 uiA64 = signUI64;
94 goto copyA;
95 }
96 expA += softfloat_normExtF80SigM( &rem64 );
97 }
98 if ( signUI64 ) goto invalid;
99 /*------------------------------------------------------------------------
100 *------------------------------------------------------------------------*/
101 expZ = ((expA - 0x3FFF)>>1) + 0x3FFF;
102 expA &= 1;
103 softfloat_shortShiftLeft64To96M( rem64, 30 - expA, rem96 );
104 sig32A = rem64>>32;
105 recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A );
106 sig32Z = ((uint64_t) sig32A * recipSqrt32)>>32;
107 if ( expA ) sig32Z >>= 1;
108 rem64 =
109 ((uint64_t) rem96[indexWord( 3, 2 )]<<32 | rem96[indexWord( 3, 1 )])
110 - (uint64_t) sig32Z * sig32Z;
111 rem96[indexWord( 3, 2 )] = rem64>>32;
112 rem96[indexWord( 3, 1 )] = rem64;
113 /*------------------------------------------------------------------------
114 *------------------------------------------------------------------------*/
115 q = ((uint32_t) (rem64>>2) * (uint64_t) recipSqrt32)>>32;
116 sig64Z = ((uint64_t) sig32Z<<32) + ((uint64_t) q<<3);
117 term[indexWord( 3, 2 )] = 0;
118 /*------------------------------------------------------------------------
119 | (Repeating this loop is a rare occurrence.)
120 *------------------------------------------------------------------------*/
121 for (;;) {
122 x64 = ((uint64_t) sig32Z<<32) + sig64Z;
123 term[indexWord( 3, 1 )] = x64>>32;
124 term[indexWord( 3, 0 )] = x64;
126 rem96, 29, term, q, &rem[indexMultiwordHi( 4, 3 )] );
127 rem32 = rem[indexWord( 4, 3 )];
128 if ( ! (rem32 & 0x80000000) ) break;
129 --q;
130 sig64Z -= 1<<3;
131 }
132 rem64 = (uint64_t) rem32<<32 | rem[indexWord( 4, 2 )];
133 /*------------------------------------------------------------------------
134 *------------------------------------------------------------------------*/
135 q = (((uint32_t) (rem64>>2) * (uint64_t) recipSqrt32)>>32) + 2;
136 if ( rem64>>34 ) q += recipSqrt32;
137 x64 = (uint64_t) q<<7;
138 extSigZ[indexWord( 3, 0 )] = x64;
139 x64 = (sig64Z<<1) + (x64>>32);
140 extSigZ[indexWord( 3, 2 )] = x64>>32;
141 extSigZ[indexWord( 3, 1 )] = x64;
142 /*------------------------------------------------------------------------
143 *------------------------------------------------------------------------*/
144 if ( (q & 0xFFFFFF) <= 2 ) {
145 q &= ~(uint32_t) 0xFFFF;
146 extSigZ[indexWordLo( 3 )] = q<<7;
147 x64 = sig64Z + (q>>27);
148 term[indexWord( 4, 3 )] = 0;
149 term[indexWord( 4, 2 )] = x64>>32;
150 term[indexWord( 4, 1 )] = x64;
151 term[indexWord( 4, 0 )] = q<<5;
152 rem[indexWord( 4, 0 )] = 0;
153 softfloat_remStep128MBy32( rem, 28, term, q, rem );
154 q = rem[indexWordHi( 4 )];
155 if ( q & 0x80000000 ) {
156 softfloat_sub1X96M( extSigZ );
157 } else {
158 if ( q || rem[indexWord( 4, 1 )] || rem[indexWord( 4, 2 )] ) {
159 extSigZ[indexWordLo( 3 )] |= 1;
160 }
161 }
162 }
164 0, expZ, extSigZ, extF80_roundingPrecision, zSPtr );
165 return;
166 /*------------------------------------------------------------------------
167 *------------------------------------------------------------------------*/
168 invalid:
170 return;
171 /*------------------------------------------------------------------------
172 *------------------------------------------------------------------------*/
173 copyA:
174 zSPtr->signExp = uiA64;
175 zSPtr->signif = rem64;
176
177}
void softfloat_propagateNaNExtF80M(const struct extFloat80M *aSPtr, const struct extFloat80M *bSPtr, struct extFloat80M *zSPtr)
#define packToExtF80UI64(sign, exp)
Definition internals.h:148
#define expExtF80UI64(a64)
Definition internals.h:147
void softfloat_invalidExtF80M(struct extFloat80M *)
void softfloat_roundPackMToExtF80M(bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M *)
int softfloat_normExtF80SigM(uint64_t *)
#define indexMultiwordHi(total, n)
#define indexWordLo(total)
#define indexWord(total, n)
#define indexWordHi(total)
#define softfloat_sub1X96M(zPtr)
#define softfloat_remStep128MBy32(remPtr, dist, bPtr, q, zPtr)
#define softfloat_remStep96MBy32(remPtr, dist, bPtr, q, zPtr)
void softfloat_shortShiftLeft64To96M(uint64_t a, uint_fast8_t dist, uint32_t *zPtr)
uint32_t softfloat_approxRecipSqrt32_1(unsigned int oddExpA, uint32_t a)
THREAD_LOCAL uint_fast8_t extF80_roundingPrecision
unsigned int uint32_t
Definition stdint.h:126
uint16_t uint_fast16_t
Definition stdint.h:155
#define UINT64_C(val)
Definition stdint.h:284
signed int int32_t
Definition stdint.h:123
unsigned __int64 uint64_t
Definition stdint.h:136
uint64_t signif
uint16_t signExp
Here is the call graph for this function: