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

Go to the source code of this file.

Functions

float128_t f128_mul (float128_t a, float128_t b)
 

Function Documentation

◆ f128_mul()

float128_t f128_mul ( float128_t a,
float128_t b )

Definition at line 44 of file f128_mul.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 uint_fast64_t magBits;
58 struct exp32_sig128 normExpSig;
59 int_fast32_t expZ;
60 uint64_t sig256Z[4];
61 uint_fast64_t sigZExtra;
62 struct uint128 sigZ;
63 struct uint128_extra sig128Extra;
64 struct uint128 uiZ;
65 union ui128_f128 uZ;
66
67 /*------------------------------------------------------------------------
68 *------------------------------------------------------------------------*/
69 uA.f = a;
70 uiA64 = uA.ui.v64;
71 uiA0 = uA.ui.v0;
72 signA = signF128UI64( uiA64 );
73 expA = expF128UI64( uiA64 );
74 sigA.v64 = fracF128UI64( uiA64 );
75 sigA.v0 = uiA0;
76 uB.f = b;
77 uiB64 = uB.ui.v64;
78 uiB0 = uB.ui.v0;
79 signB = signF128UI64( uiB64 );
80 expB = expF128UI64( uiB64 );
81 sigB.v64 = fracF128UI64( uiB64 );
82 sigB.v0 = uiB0;
83 signZ = signA ^ signB;
84 /*------------------------------------------------------------------------
85 *------------------------------------------------------------------------*/
86 if ( expA == 0x7FFF ) {
87 if (
88 (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))
89 ) {
90 goto propagateNaN;
91 }
92 magBits = expB | sigB.v64 | sigB.v0;
93 goto infArg;
94 }
95 if ( expB == 0x7FFF ) {
96 if ( sigB.v64 | sigB.v0 ) goto propagateNaN;
97 magBits = expA | sigA.v64 | sigA.v0;
98 goto infArg;
99 }
100 /*------------------------------------------------------------------------
101 *------------------------------------------------------------------------*/
102 if ( ! expA ) {
103 if ( ! (sigA.v64 | sigA.v0) ) goto zero;
104 normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 );
105 expA = normExpSig.exp;
106 sigA = normExpSig.sig;
107 }
108 if ( ! expB ) {
109 if ( ! (sigB.v64 | sigB.v0) ) goto zero;
110 normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 );
111 expB = normExpSig.exp;
112 sigB = normExpSig.sig;
113 }
114 /*------------------------------------------------------------------------
115 *------------------------------------------------------------------------*/
116 expZ = expA + expB - 0x4000;
117 sigA.v64 |= UINT64_C( 0x0001000000000000 );
118 sigB = softfloat_shortShiftLeft128( sigB.v64, sigB.v0, 16 );
119 softfloat_mul128To256M( sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z );
120 sigZExtra = sig256Z[indexWord( 4, 1 )] | (sig256Z[indexWord( 4, 0 )] != 0);
121 sigZ =
123 sig256Z[indexWord( 4, 3 )], sig256Z[indexWord( 4, 2 )],
124 sigA.v64, sigA.v0
125 );
126 if ( UINT64_C( 0x0002000000000000 ) <= sigZ.v64 ) {
127 ++expZ;
128 sig128Extra =
130 sigZ.v64, sigZ.v0, sigZExtra, 1 );
131 sigZ = sig128Extra.v;
132 sigZExtra = sig128Extra.extra;
133 }
134 return
135 softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra );
136 /*------------------------------------------------------------------------
137 *------------------------------------------------------------------------*/
138 propagateNaN:
139 uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 );
140 goto uiZ;
141 /*------------------------------------------------------------------------
142 *------------------------------------------------------------------------*/
143 infArg:
144 if ( ! magBits ) {
146 uiZ.v64 = defaultNaNF128UI64;
147 uiZ.v0 = defaultNaNF128UI0;
148 goto uiZ;
149 }
150 uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 );
151 goto uiZ0;
152 /*------------------------------------------------------------------------
153 *------------------------------------------------------------------------*/
154 zero:
155 uiZ.v64 = packToF128UI64( signZ, 0, 0 );
156 uiZ0:
157 uiZ.v0 = 0;
158 uiZ:
159 uZ.ui = uiZ;
160 return uZ.f;
161
162}
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
#define indexWord(total, n)
@ 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
#define softfloat_mul128To256M
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_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist)
uint64_t uint_fast64_t
Definition stdint.h:157
#define UINT64_C(val)
Definition stdint.h:284
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: