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

Go to the source code of this file.

Functions

float128_t f128_div (float128_t a, float128_t b)
 

Function Documentation

◆ f128_div()

float128_t f128_div ( float128_t a,
float128_t b )

Definition at line 44 of file f128_div.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 bool signB;
54 int_fast32_t expB;
55 struct uint128 sigB;
56 bool signZ;
57 struct exp32_sig128 normExpSig;
58 int_fast32_t expZ;
59 struct uint128 rem;
60 uint_fast32_t recip32;
61 int ix;
62 uint_fast64_t q64;
64 struct uint128 term;
65 uint_fast32_t qs[3];
66 uint_fast64_t sigZExtra;
67 struct uint128 sigZ, uiZ;
68 union ui128_f128 uZ;
69
70 /*------------------------------------------------------------------------
71 *------------------------------------------------------------------------*/
72 uA.f = a;
73 uiA64 = uA.ui.v64;
74 uiA0 = uA.ui.v0;
75 signA = signF128UI64( uiA64 );
76 expA = expF128UI64( uiA64 );
77 sigA.v64 = fracF128UI64( uiA64 );
78 sigA.v0 = uiA0;
79 uB.f = b;
80 uiB64 = uB.ui.v64;
81 uiB0 = uB.ui.v0;
82 signB = signF128UI64( uiB64 );
83 expB = expF128UI64( uiB64 );
84 sigB.v64 = fracF128UI64( uiB64 );
85 sigB.v0 = uiB0;
86 signZ = signA ^ signB;
87 /*------------------------------------------------------------------------
88 *------------------------------------------------------------------------*/
89 if ( expA == 0x7FFF ) {
90 if ( sigA.v64 | sigA.v0 ) goto propagateNaN;
91 if ( expB == 0x7FFF ) {
92 if ( sigB.v64 | sigB.v0 ) goto propagateNaN;
93 goto invalid;
94 }
95 goto infinity;
96 }
97 if ( expB == 0x7FFF ) {
98 if ( sigB.v64 | sigB.v0 ) goto propagateNaN;
99 goto zero;
100 }
101 /*------------------------------------------------------------------------
102 *------------------------------------------------------------------------*/
103 if ( ! expB ) {
104 if ( ! (sigB.v64 | sigB.v0) ) {
105 if ( ! (expA | sigA.v64 | sigA.v0) ) goto invalid;
107 goto infinity;
108 }
109 normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 );
110 expB = normExpSig.exp;
111 sigB = normExpSig.sig;
112 }
113 if ( ! expA ) {
114 if ( ! (sigA.v64 | sigA.v0) ) goto zero;
115 normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 );
116 expA = normExpSig.exp;
117 sigA = normExpSig.sig;
118 }
119 /*------------------------------------------------------------------------
120 *------------------------------------------------------------------------*/
121 expZ = expA - expB + 0x3FFE;
122 sigA.v64 |= UINT64_C( 0x0001000000000000 );
123 sigB.v64 |= UINT64_C( 0x0001000000000000 );
124 rem = sigA;
125 if ( softfloat_lt128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 ) ) {
126 --expZ;
127 rem = softfloat_add128( sigA.v64, sigA.v0, sigA.v64, sigA.v0 );
128 }
129 recip32 = softfloat_approxRecip32_1( sigB.v64>>17 );
130 ix = 3;
131 for (;;) {
132 q64 = (uint_fast64_t) (uint32_t) (rem.v64>>19) * recip32;
133 q = (q64 + 0x80000000)>>32;
134 --ix;
135 if ( ix < 0 ) break;
136 rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );
137 term = softfloat_mul128By32( sigB.v64, sigB.v0, q );
138 rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
139 if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
140 --q;
141 rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
142 }
143 qs[ix] = q;
144 }
145 /*------------------------------------------------------------------------
146 *------------------------------------------------------------------------*/
147 if ( ((q + 1) & 7) < 2 ) {
148 rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );
149 term = softfloat_mul128By32( sigB.v64, sigB.v0, q );
150 rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
151 if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
152 --q;
153 rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
154 } else if ( softfloat_le128( sigB.v64, sigB.v0, rem.v64, rem.v0 ) ) {
155 ++q;
156 rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 );
157 }
158 if ( rem.v64 | rem.v0 ) q |= 1;
159 }
160 /*------------------------------------------------------------------------
161 *------------------------------------------------------------------------*/
162 sigZExtra = (uint64_t) ((uint_fast64_t) q<<60);
163 term = softfloat_shortShiftLeft128( 0, qs[1], 54 );
164 sigZ =
166 (uint_fast64_t) qs[2]<<19, ((uint_fast64_t) qs[0]<<25) + (q>>4),
167 term.v64, term.v0
168 );
169 return
170 softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra );
171 /*------------------------------------------------------------------------
172 *------------------------------------------------------------------------*/
173 propagateNaN:
174 uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 );
175 goto uiZ;
176 /*------------------------------------------------------------------------
177 *------------------------------------------------------------------------*/
178 invalid:
180 uiZ.v64 = defaultNaNF128UI64;
181 uiZ.v0 = defaultNaNF128UI0;
182 goto uiZ;
183 /*------------------------------------------------------------------------
184 *------------------------------------------------------------------------*/
185 infinity:
186 uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 );
187 goto uiZ0;
188 /*------------------------------------------------------------------------
189 *------------------------------------------------------------------------*/
190 zero:
191 uiZ.v64 = packToF128UI64( signZ, 0, 0 );
192 uiZ0:
193 uiZ.v0 = 0;
194 uiZ:
195 uZ.ui = uiZ;
196 return uZ.f;
197
198}
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
@ softfloat_flag_infinite
Definition softfloat.h:88
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
bool softfloat_lt128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
Definition s_lt128.c:43
struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b)
struct exp32_sig128 softfloat_normSubnormalF128Sig(uint_fast64_t sig64, uint_fast64_t sig0)
float128_t softfloat_roundPackToF128(bool sign, int_fast32_t exp, uint_fast64_t sig64, uint_fast64_t sig0, uint_fast64_t sigExtra)
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
unsigned __int64 uint64_t
Definition stdint.h:136
Here is the call graph for this function:
Here is the caller graph for this function: