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

Go to the source code of this file.

Functions

float128_t f128_rem (float128_t a, float128_t b)
 

Function Documentation

◆ f128_rem()

float128_t f128_rem ( float128_t a,
float128_t b )

Definition at line 44 of file f128_rem.c.

45{
46 union ui128_f128 uA;
47 uint_fast64_t uiA64, uiA0;
48 bool signA;
49 int_fast32_t expA;
50 struct uint128 sigA;
51 union ui128_f128 uB;
52 uint_fast64_t uiB64, uiB0;
53 int_fast32_t expB;
54 struct uint128 sigB;
55 struct exp32_sig128 normExpSig;
56 struct uint128 rem;
57 int_fast32_t expDiff;
58 uint_fast32_t q, recip32;
59 uint_fast64_t q64;
60 struct uint128 term, altRem, meanRem;
61 bool signRem;
62 struct uint128 uiZ;
63 union ui128_f128 uZ;
64
65 /*------------------------------------------------------------------------
66 *------------------------------------------------------------------------*/
67 uA.f = a;
68 uiA64 = uA.ui.v64;
69 uiA0 = uA.ui.v0;
70 signA = signF128UI64( uiA64 );
71 expA = expF128UI64( uiA64 );
72 sigA.v64 = fracF128UI64( uiA64 );
73 sigA.v0 = uiA0;
74 uB.f = b;
75 uiB64 = uB.ui.v64;
76 uiB0 = uB.ui.v0;
77 expB = expF128UI64( uiB64 );
78 sigB.v64 = fracF128UI64( uiB64 );
79 sigB.v0 = uiB0;
80 /*------------------------------------------------------------------------
81 *------------------------------------------------------------------------*/
82 if ( expA == 0x7FFF ) {
83 if (
84 (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))
85 ) {
86 goto propagateNaN;
87 }
88 goto invalid;
89 }
90 if ( expB == 0x7FFF ) {
91 if ( sigB.v64 | sigB.v0 ) goto propagateNaN;
92 return a;
93 }
94 /*------------------------------------------------------------------------
95 *------------------------------------------------------------------------*/
96 if ( ! expB ) {
97 if ( ! (sigB.v64 | sigB.v0) ) goto invalid;
98 normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 );
99 expB = normExpSig.exp;
100 sigB = normExpSig.sig;
101 }
102 if ( ! expA ) {
103 if ( ! (sigA.v64 | sigA.v0) ) return a;
104 normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 );
105 expA = normExpSig.exp;
106 sigA = normExpSig.sig;
107 }
108 /*------------------------------------------------------------------------
109 *------------------------------------------------------------------------*/
110 sigA.v64 |= UINT64_C( 0x0001000000000000 );
111 sigB.v64 |= UINT64_C( 0x0001000000000000 );
112 rem = sigA;
113 expDiff = expA - expB;
114 if ( expDiff < 1 ) {
115 if ( expDiff < -1 ) return a;
116 if ( expDiff ) {
117 --expB;
118 sigB = softfloat_add128( sigB.v64, sigB.v0, sigB.v64, sigB.v0 );
119 q = 0;
120 } else {
121 q = softfloat_le128( sigB.v64, sigB.v0, rem.v64, rem.v0 );
122 if ( q ) {
123 rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
124 }
125 }
126 } else {
127 recip32 = softfloat_approxRecip32_1( sigB.v64>>17 );
128 expDiff -= 30;
129 for (;;) {
130 q64 = (uint_fast64_t) (uint32_t) (rem.v64>>19) * recip32;
131 if ( expDiff < 0 ) break;
132 q = (q64 + 0x80000000)>>32;
133 rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );
134 term = softfloat_mul128By32( sigB.v64, sigB.v0, q );
135 rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
136 if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
137 rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
138 }
139 expDiff -= 29;
140 }
141 /*--------------------------------------------------------------------
142 | (`expDiff' cannot be less than -29 here.)
143 *--------------------------------------------------------------------*/
144 q = (uint32_t) (q64>>32)>>(~expDiff & 31);
145 rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, expDiff + 30 );
146 term = softfloat_mul128By32( sigB.v64, sigB.v0, q );
147 rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
148 if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
149 altRem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
150 goto selectRem;
151 }
152 }
153 /*------------------------------------------------------------------------
154 *------------------------------------------------------------------------*/
155 do {
156 altRem = rem;
157 ++q;
158 rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
159 } while ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) );
160 selectRem:
161 meanRem = softfloat_add128( rem.v64, rem.v0, altRem.v64, altRem.v0 );
162 if (
163 (meanRem.v64 & UINT64_C( 0x8000000000000000 ))
164 || (! (meanRem.v64 | meanRem.v0) && (q & 1))
165 ) {
166 rem = altRem;
167 }
168 signRem = signA;
169 if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
170 signRem = ! signRem;
171 rem = softfloat_sub128( 0, 0, rem.v64, rem.v0 );
172 }
173 return softfloat_normRoundPackToF128( signRem, expB - 1, rem.v64, rem.v0 );
174 /*------------------------------------------------------------------------
175 *------------------------------------------------------------------------*/
176 propagateNaN:
177 uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 );
178 goto uiZ;
179 /*------------------------------------------------------------------------
180 *------------------------------------------------------------------------*/
181 invalid:
183 uiZ.v64 = defaultNaNF128UI64;
184 uiZ.v0 = defaultNaNF128UI0;
185 uiZ:
186 uZ.ui = uiZ;
187 return uZ.f;
188
189}
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0)
void softfloat_raiseFlags(uint_fast8_t flags)
#define defaultNaNF128UI64
Definition specialize.h:337
#define defaultNaNF128UI0
Definition specialize.h:339
uint32_t softfloat_approxRecip32_1(uint32_t a)
@ 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
bool softfloat_le128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
Definition s_le128.c:43
struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b)
float128_t softfloat_normRoundPackToF128(bool sign, int_fast32_t exp, uint_fast64_t sig64, uint_fast64_t sig0)
struct exp32_sig128 softfloat_normSubnormalF128Sig(uint_fast64_t sig64, uint_fast64_t sig0)
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
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
Here is the call graph for this function: