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

Go to the source code of this file.

Functions

float64_t f64_div (float64_t a, float64_t b)
 

Function Documentation

◆ f64_div()

float64_t f64_div ( float64_t a,
float64_t b )

Definition at line 44 of file f64_div.c.

45{
46 union ui64_f64 uA;
47 uint_fast64_t uiA;
48 bool signA;
49 int_fast16_t expA;
50 uint_fast64_t sigA;
51 union ui64_f64 uB;
52 uint_fast64_t uiB;
53 bool signB;
54 int_fast16_t expB;
55 uint_fast64_t sigB;
56 bool signZ;
57 struct exp16_sig64 normExpSig;
58 int_fast16_t expZ;
59 uint32_t recip32, sig32Z, doubleTerm;
60 uint_fast64_t rem;
61 uint32_t q;
62 uint_fast64_t sigZ;
63 uint_fast64_t uiZ;
64 union ui64_f64 uZ;
65
66 /*------------------------------------------------------------------------
67 *------------------------------------------------------------------------*/
68 uA.f = a;
69 uiA = uA.ui;
70 signA = signF64UI( uiA );
71 expA = expF64UI( uiA );
72 sigA = fracF64UI( uiA );
73 uB.f = b;
74 uiB = uB.ui;
75 signB = signF64UI( uiB );
76 expB = expF64UI( uiB );
77 sigB = fracF64UI( uiB );
78 signZ = signA ^ signB;
79 /*------------------------------------------------------------------------
80 *------------------------------------------------------------------------*/
81 if ( expA == 0x7FF ) {
82 if ( sigA ) goto propagateNaN;
83 if ( expB == 0x7FF ) {
84 if ( sigB ) goto propagateNaN;
85 goto invalid;
86 }
87 goto infinity;
88 }
89 if ( expB == 0x7FF ) {
90 if ( sigB ) goto propagateNaN;
91 goto zero;
92 }
93 /*------------------------------------------------------------------------
94 *------------------------------------------------------------------------*/
95 if ( ! expB ) {
96 if ( ! sigB ) {
97 if ( ! (expA | sigA) ) goto invalid;
99 goto infinity;
100 }
101 normExpSig = softfloat_normSubnormalF64Sig( sigB );
102 expB = normExpSig.exp;
103 sigB = normExpSig.sig;
104 }
105 if ( ! expA ) {
106 if ( ! sigA ) goto zero;
107 normExpSig = softfloat_normSubnormalF64Sig( sigA );
108 expA = normExpSig.exp;
109 sigA = normExpSig.sig;
110 }
111 /*------------------------------------------------------------------------
112 *------------------------------------------------------------------------*/
113 expZ = expA - expB + 0x3FE;
114 sigA |= UINT64_C( 0x0010000000000000 );
115 sigB |= UINT64_C( 0x0010000000000000 );
116 if ( sigA < sigB ) {
117 --expZ;
118 sigA <<= 11;
119 } else {
120 sigA <<= 10;
121 }
122 sigB <<= 11;
123 recip32 = softfloat_approxRecip32_1( sigB>>32 ) - 2;
124 sig32Z = ((uint32_t) (sigA>>32) * (uint_fast64_t) recip32)>>32;
125 doubleTerm = sig32Z<<1;
126 rem =
127 ((sigA - (uint_fast64_t) doubleTerm * (uint32_t) (sigB>>32))<<28)
128 - (uint_fast64_t) doubleTerm * ((uint32_t) sigB>>4);
129 q = (((uint32_t) (rem>>32) * (uint_fast64_t) recip32)>>32) + 4;
130 sigZ = ((uint_fast64_t) sig32Z<<32) + ((uint_fast64_t) q<<4);
131 /*------------------------------------------------------------------------
132 *------------------------------------------------------------------------*/
133 if ( (sigZ & 0x1FF) < 4<<4 ) {
134 q &= ~7;
135 sigZ &= ~(uint_fast64_t) 0x7F;
136 doubleTerm = q<<1;
137 rem =
138 ((rem - (uint_fast64_t) doubleTerm * (uint32_t) (sigB>>32))<<28)
139 - (uint_fast64_t) doubleTerm * ((uint32_t) sigB>>4);
140 if ( rem & UINT64_C( 0x8000000000000000 ) ) {
141 sigZ -= 1<<7;
142 } else {
143 if ( rem ) sigZ |= 1;
144 }
145 }
146 return softfloat_roundPackToF64( signZ, expZ, sigZ );
147 /*------------------------------------------------------------------------
148 *------------------------------------------------------------------------*/
149 propagateNaN:
150 uiZ = softfloat_propagateNaNF64UI( uiA, uiB );
151 goto uiZ;
152 /*------------------------------------------------------------------------
153 *------------------------------------------------------------------------*/
154 invalid:
156 uiZ = defaultNaNF64UI;
157 goto uiZ;
158 /*------------------------------------------------------------------------
159 *------------------------------------------------------------------------*/
160 infinity:
161 uiZ = packToF64UI( signZ, 0x7FF, 0 );
162 goto uiZ;
163 /*------------------------------------------------------------------------
164 *------------------------------------------------------------------------*/
165 zero:
166 uiZ = packToF64UI( signZ, 0, 0 );
167 uiZ:
168 uZ.ui = uiZ;
169 return uZ.f;
170
171}
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB)
void softfloat_raiseFlags(uint_fast8_t flags)
#define defaultNaNF64UI
Definition specialize.h:158
float64_t softfloat_roundPackToF64(bool, int_fast16_t, uint_fast64_t)
struct exp16_sig64 softfloat_normSubnormalF64Sig(uint_fast64_t)
#define signF64UI(a)
Definition internals.h:125
#define packToF64UI(sign, exp, sig)
Definition internals.h:128
#define expF64UI(a)
Definition internals.h:126
#define fracF64UI(a)
Definition internals.h:127
uint32_t softfloat_approxRecip32_1(uint32_t a)
@ softfloat_flag_invalid
Definition softfloat.h:89
@ softfloat_flag_infinite
Definition softfloat.h:88
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
int16_t int_fast16_t
Definition stdint.h:151
float64_t f
Definition internals.h:47
Here is the call graph for this function: