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

Go to the source code of this file.

Functions

void extF80M_rem (const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr)
 

Function Documentation

◆ extF80M_rem()

void extF80M_rem ( const extFloat80_t * aPtr,
const extFloat80_t * bPtr,
extFloat80_t * zPtr )

Definition at line 58 of file extF80M_rem.c.

60{
61 const struct extFloat80M *aSPtr, *bSPtr;
62 struct extFloat80M *zSPtr;
63 uint_fast16_t uiA64;
64 int32_t expA, expB;
65 uint64_t x64;
66 bool signRem;
67 uint64_t sigA;
68 int32_t expDiff;
69 uint32_t rem[3], x[3], sig32B, q, recip32, rem2[3], *remPtr, *altRemPtr;
70 uint32_t *newRemPtr, wordMeanRem;
71
72 /*------------------------------------------------------------------------
73 *------------------------------------------------------------------------*/
74 aSPtr = (const struct extFloat80M *) aPtr;
75 bSPtr = (const struct extFloat80M *) bPtr;
76 zSPtr = (struct extFloat80M *) zPtr;
77 /*------------------------------------------------------------------------
78 *------------------------------------------------------------------------*/
79 uiA64 = aSPtr->signExp;
80 expA = expExtF80UI64( uiA64 );
81 expB = expExtF80UI64( bSPtr->signExp );
82 /*------------------------------------------------------------------------
83 *------------------------------------------------------------------------*/
84 if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) {
85 if ( softfloat_tryPropagateNaNExtF80M( aSPtr, bSPtr, zSPtr ) ) return;
86 if ( expA == 0x7FFF ) goto invalid;
87 /*--------------------------------------------------------------------
88 | If we get here, then argument b is an infinity and `expB' is 0x7FFF;
89 | Doubling `expB' is an easy way to ensure that `expDiff' later is
90 | less than -1, which will result in returning a canonicalized version
91 | of argument a.
92 *--------------------------------------------------------------------*/
93 expB += expB;
94 }
95 /*------------------------------------------------------------------------
96 *------------------------------------------------------------------------*/
97 if ( ! expB ) expB = 1;
98 x64 = bSPtr->signif;
99 if ( ! (x64 & UINT64_C( 0x8000000000000000 )) ) {
100 if ( ! x64 ) goto invalid;
101 expB += softfloat_normExtF80SigM( &x64 );
102 }
103 signRem = signExtF80UI64( uiA64 );
104 if ( ! expA ) expA = 1;
105 sigA = aSPtr->signif;
106 if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) {
107 if ( ! sigA ) {
108 expA = 0;
109 goto copyA;
110 }
111 expA += softfloat_normExtF80SigM( &sigA );
112 }
113 /*------------------------------------------------------------------------
114 *------------------------------------------------------------------------*/
115 expDiff = expA - expB;
116 if ( expDiff < -1 ) goto copyA;
117 rem[indexWord( 3, 2 )] = sigA>>34;
118 rem[indexWord( 3, 1 )] = sigA>>2;
119 rem[indexWord( 3, 0 )] = (uint32_t) sigA<<30;
120 x[indexWord( 3, 0 )] = (uint32_t) x64<<30;
121 sig32B = x64>>32;
122 x64 >>= 2;
123 x[indexWord( 3, 2 )] = x64>>32;
124 x[indexWord( 3, 1 )] = x64;
125 if ( expDiff < 1 ) {
126 if ( expDiff ) {
127 --expB;
128 softfloat_add96M( x, x, x );
129 q = 0;
130 } else {
131 q = (softfloat_compare96M( x, rem ) <= 0);
132 if ( q ) softfloat_sub96M( rem, x, rem );
133 }
134 } else {
135 recip32 = softfloat_approxRecip32_1( sig32B );
136 expDiff -= 30;
137 for (;;) {
138 x64 = (uint64_t) rem[indexWordHi( 3 )] * recip32;
139 if ( expDiff < 0 ) break;
140 q = (x64 + 0x80000000)>>32;
141 softfloat_remStep96MBy32( rem, 29, x, q, rem );
142 if ( rem[indexWordHi( 3 )] & 0x80000000 ) {
143 softfloat_add96M( rem, x, rem );
144 }
145 expDiff -= 29;
146 }
147 /*--------------------------------------------------------------------
148 | (`expDiff' cannot be less than -29 here.)
149 *--------------------------------------------------------------------*/
150 q = (uint32_t) (x64>>32)>>(~expDiff & 31);
151 softfloat_remStep96MBy32( rem, expDiff + 30, x, q, rem );
152 if ( rem[indexWordHi( 3 )] & 0x80000000 ) {
153 remPtr = rem;
154 altRemPtr = rem2;
155 softfloat_add96M( remPtr, x, altRemPtr );
156 goto selectRem;
157 }
158 }
159 /*------------------------------------------------------------------------
160 *------------------------------------------------------------------------*/
161 remPtr = rem;
162 altRemPtr = rem2;
163 do {
164 ++q;
165 newRemPtr = altRemPtr;
166 softfloat_sub96M( remPtr, x, newRemPtr );
167 altRemPtr = remPtr;
168 remPtr = newRemPtr;
169 } while ( ! (remPtr[indexWordHi( 3 )] & 0x80000000) );
170 selectRem:
171 softfloat_add96M( remPtr, altRemPtr, x );
172 wordMeanRem = x[indexWordHi( 3 )];
173 if (
174 (wordMeanRem & 0x80000000)
175 || (! wordMeanRem && (q & 1) && ! x[indexWord( 3, 0 )]
176 && ! x[indexWord( 3, 1 )])
177 ) {
178 remPtr = altRemPtr;
179 }
180 if ( remPtr[indexWordHi( 3 )] & 0x80000000 ) {
181 signRem = ! signRem;
182 softfloat_negX96M( remPtr );
183 }
184 softfloat_normRoundPackMToExtF80M( signRem, expB + 2, remPtr, 80, zSPtr );
185 return;
186 /*------------------------------------------------------------------------
187 *------------------------------------------------------------------------*/
188 invalid:
190 return;
191 /*------------------------------------------------------------------------
192 *------------------------------------------------------------------------*/
193 copyA:
194 if ( expA < 1 ) {
195 sigA >>= 1 - expA;
196 expA = 0;
197 }
198 zSPtr->signExp = packToExtF80UI64( signRem, expA );
199 zSPtr->signif = sigA;
200
201}
void softfloat_normRoundPackMToExtF80M(bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M *)
#define packToExtF80UI64(sign, exp)
Definition internals.h:148
#define expExtF80UI64(a64)
Definition internals.h:147
void softfloat_invalidExtF80M(struct extFloat80M *)
#define signExtF80UI64(a64)
Definition internals.h:146
bool softfloat_tryPropagateNaNExtF80M(const struct extFloat80M *, const struct extFloat80M *, struct extFloat80M *)
int softfloat_normExtF80SigM(uint64_t *)
#define indexWord(total, n)
#define indexWordHi(total)
int_fast8_t softfloat_compare96M(const uint32_t *aPtr, const uint32_t *bPtr)
#define softfloat_negX96M(zPtr)
Definition primitives.h:992
#define softfloat_add96M(aPtr, bPtr, zPtr)
Definition primitives.h:915
#define softfloat_sub96M(aPtr, bPtr, zPtr)
#define softfloat_remStep96MBy32(remPtr, dist, bPtr, q, zPtr)
uint32_t softfloat_approxRecip32_1(uint32_t a)
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: