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

Go to the source code of this file.

Functions

extFloat80_t extF80_div (extFloat80_t a, extFloat80_t b)
 

Function Documentation

◆ extF80_div()

extFloat80_t extF80_div ( extFloat80_t a,
extFloat80_t b )

Definition at line 44 of file extF80_div.c.

45{
46 union { struct extFloat80M s; extFloat80_t f; } uA;
47 uint_fast16_t uiA64;
48 uint_fast64_t uiA0;
49 bool signA;
50 int_fast32_t expA;
51 uint_fast64_t sigA;
52 union { struct extFloat80M s; extFloat80_t f; } uB;
53 uint_fast16_t uiB64;
54 uint_fast64_t uiB0;
55 bool signB;
56 int_fast32_t expB;
57 uint_fast64_t sigB;
58 bool signZ;
59 struct exp32_sig64 normExpSig;
60 int_fast32_t expZ;
61 struct uint128 rem;
62 uint_fast32_t recip32;
63 uint_fast64_t sigZ;
64 int ix;
65 uint_fast64_t q64;
67 struct uint128 term;
68 uint_fast64_t sigZExtra;
69 struct uint128 uiZ;
70 uint_fast16_t uiZ64;
71 uint_fast64_t uiZ0;
72 union { struct extFloat80M s; extFloat80_t f; } uZ;
73
74 /*------------------------------------------------------------------------
75 *------------------------------------------------------------------------*/
76 uA.f = a;
77 uiA64 = uA.s.signExp;
78 uiA0 = uA.s.signif;
79 signA = signExtF80UI64( uiA64 );
80 expA = expExtF80UI64( uiA64 );
81 sigA = uiA0;
82 uB.f = b;
83 uiB64 = uB.s.signExp;
84 uiB0 = uB.s.signif;
85 signB = signExtF80UI64( uiB64 );
86 expB = expExtF80UI64( uiB64 );
87 sigB = uiB0;
88 signZ = signA ^ signB;
89 /*------------------------------------------------------------------------
90 *------------------------------------------------------------------------*/
91 if ( expA == 0x7FFF ) {
92 if ( sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN;
93 if ( expB == 0x7FFF ) {
94 if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN;
95 goto invalid;
96 }
97 goto infinity;
98 }
99 if ( expB == 0x7FFF ) {
100 if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN;
101 goto zero;
102 }
103 /*------------------------------------------------------------------------
104 *------------------------------------------------------------------------*/
105 if ( ! expB ) expB = 1;
106 if ( ! (sigB & UINT64_C( 0x8000000000000000 )) ) {
107 if ( ! sigB ) {
108 if ( ! sigA ) goto invalid;
110 goto infinity;
111 }
112 normExpSig = softfloat_normSubnormalExtF80Sig( sigB );
113 expB += normExpSig.exp;
114 sigB = normExpSig.sig;
115 }
116 if ( ! expA ) expA = 1;
117 if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) {
118 if ( ! sigA ) goto zero;
119 normExpSig = softfloat_normSubnormalExtF80Sig( sigA );
120 expA += normExpSig.exp;
121 sigA = normExpSig.sig;
122 }
123 /*------------------------------------------------------------------------
124 *------------------------------------------------------------------------*/
125 expZ = expA - expB + 0x3FFF;
126 if ( sigA < sigB ) {
127 --expZ;
128 rem = softfloat_shortShiftLeft128( 0, sigA, 32 );
129 } else {
130 rem = softfloat_shortShiftLeft128( 0, sigA, 31 );
131 }
132 recip32 = softfloat_approxRecip32_1( sigB>>32 );
133 sigZ = 0;
134 ix = 2;
135 for (;;) {
136 q64 = (uint_fast64_t) (uint32_t) (rem.v64>>2) * recip32;
137 q = (q64 + 0x80000000)>>32;
138 --ix;
139 if ( ix < 0 ) break;
140 rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );
141 term = softfloat_mul64ByShifted32To128( sigB, q );
142 rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
143 if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
144 --q;
145 rem = softfloat_add128( rem.v64, rem.v0, sigB>>32, sigB<<32 );
146 }
147 sigZ = (sigZ<<29) + q;
148 }
149 /*------------------------------------------------------------------------
150 *------------------------------------------------------------------------*/
151 if ( ((q + 1) & 0x3FFFFF) < 2 ) {
152 rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );
153 term = softfloat_mul64ByShifted32To128( sigB, q );
154 rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
155 term = softfloat_shortShiftLeft128( 0, sigB, 32 );
156 if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {
157 --q;
158 rem = softfloat_add128( rem.v64, rem.v0, term.v64, term.v0 );
159 } else if ( softfloat_le128( term.v64, term.v0, rem.v64, rem.v0 ) ) {
160 ++q;
161 rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );
162 }
163 if ( rem.v64 | rem.v0 ) q |= 1;
164 }
165 /*------------------------------------------------------------------------
166 *------------------------------------------------------------------------*/
167 sigZ = (sigZ<<6) + (q>>23);
168 sigZExtra = (uint64_t) ((uint_fast64_t) q<<41);
169 return
171 signZ, expZ, sigZ, sigZExtra, extF80_roundingPrecision );
172 /*------------------------------------------------------------------------
173 *------------------------------------------------------------------------*/
174 propagateNaN:
175 uiZ = softfloat_propagateNaNExtF80UI( uiA64, uiA0, uiB64, uiB0 );
176 uiZ64 = uiZ.v64;
177 uiZ0 = uiZ.v0;
178 goto uiZ;
179 /*------------------------------------------------------------------------
180 *------------------------------------------------------------------------*/
181 invalid:
183 uiZ64 = defaultNaNExtF80UI64;
184 uiZ0 = defaultNaNExtF80UI0;
185 goto uiZ;
186 /*------------------------------------------------------------------------
187 *------------------------------------------------------------------------*/
188 infinity:
189 uiZ64 = packToExtF80UI64( signZ, 0x7FFF );
190 uiZ0 = UINT64_C( 0x8000000000000000 );
191 goto uiZ;
192 /*------------------------------------------------------------------------
193 *------------------------------------------------------------------------*/
194 zero:
195 uiZ64 = packToExtF80UI64( signZ, 0 );
196 uiZ0 = 0;
197 uiZ:
198 uZ.s.signExp = uiZ64;
199 uZ.s.signif = uiZ0;
200 return uZ.f;
201
202}
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0)
void softfloat_raiseFlags(uint_fast8_t flags)
#define defaultNaNExtF80UI0
Definition specialize.h:194
#define defaultNaNExtF80UI64
Definition specialize.h:193
#define packToExtF80UI64(sign, exp)
Definition internals.h:148
#define expExtF80UI64(a64)
Definition internals.h:147
#define signExtF80UI64(a64)
Definition internals.h:146
uint32_t softfloat_approxRecip32_1(uint32_t a)
THREAD_LOCAL uint_fast8_t extF80_roundingPrecision
@ 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
struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b)
struct exp32_sig64 softfloat_normSubnormalExtF80Sig(uint_fast64_t sig)
extFloat80_t softfloat_roundPackToExtF80(bool sign, int_fast32_t exp, uint_fast64_t sig, uint_fast64_t sigExtra, uint_fast8_t roundingPrecision)
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
uint16_t uint_fast16_t
Definition stdint.h:155
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
uint16_t signExp
char * s
Here is the call graph for this function: