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

Go to the source code of this file.

Functions

float16_t softfloat_mulAddF16 (uint_fast16_t uiA, uint_fast16_t uiB, uint_fast16_t uiC, uint_fast8_t op)
 

Function Documentation

◆ softfloat_mulAddF16()

float16_t softfloat_mulAddF16 ( uint_fast16_t uiA,
uint_fast16_t uiB,
uint_fast16_t uiC,
uint_fast8_t op )

Definition at line 45 of file s_mulAddF16.c.

47{
48 bool signA;
49 int_fast8_t expA;
50 uint_fast16_t sigA;
51 bool signB;
52 int_fast8_t expB;
53 uint_fast16_t sigB;
54 bool signC;
55 int_fast8_t expC;
56 uint_fast16_t sigC;
57 bool signProd;
58 uint_fast16_t magBits, uiZ;
59 struct exp8_sig16 normExpSig;
60 int_fast8_t expProd;
61 uint_fast32_t sigProd;
62 bool signZ;
63 int_fast8_t expZ;
64 uint_fast16_t sigZ;
65 int_fast8_t expDiff;
66 uint_fast32_t sig32Z, sig32C;
67 int_fast8_t shiftDist;
68 union ui16_f16 uZ;
69
70 /*------------------------------------------------------------------------
71 *------------------------------------------------------------------------*/
72 signA = signF16UI( uiA );
73 expA = expF16UI( uiA );
74 sigA = fracF16UI( uiA );
75 signB = signF16UI( uiB );
76 expB = expF16UI( uiB );
77 sigB = fracF16UI( uiB );
78 signC = signF16UI( uiC ) ^ (op == softfloat_mulAdd_subC);
79 expC = expF16UI( uiC );
80 sigC = fracF16UI( uiC );
81 signProd = signA ^ signB ^ (op == softfloat_mulAdd_subProd);
82 /*------------------------------------------------------------------------
83 *------------------------------------------------------------------------*/
84 if ( expA == 0x1F ) {
85 if ( sigA || ((expB == 0x1F) && sigB) ) goto propagateNaN_ABC;
86 magBits = expB | sigB;
87 goto infProdArg;
88 }
89 if ( expB == 0x1F ) {
90 if ( sigB ) goto propagateNaN_ABC;
91 magBits = expA | sigA;
92 goto infProdArg;
93 }
94 if ( expC == 0x1F ) {
95 if ( sigC ) {
96 uiZ = 0;
97 goto propagateNaN_ZC;
98 }
99 uiZ = uiC;
100 goto uiZ;
101 }
102 /*------------------------------------------------------------------------
103 *------------------------------------------------------------------------*/
104 if ( ! expA ) {
105 if ( ! sigA ) goto zeroProd;
106 normExpSig = softfloat_normSubnormalF16Sig( sigA );
107 expA = normExpSig.exp;
108 sigA = normExpSig.sig;
109 }
110 if ( ! expB ) {
111 if ( ! sigB ) goto zeroProd;
112 normExpSig = softfloat_normSubnormalF16Sig( sigB );
113 expB = normExpSig.exp;
114 sigB = normExpSig.sig;
115 }
116 /*------------------------------------------------------------------------
117 *------------------------------------------------------------------------*/
118 expProd = expA + expB - 0xE;
119 sigA = (sigA | 0x0400)<<4;
120 sigB = (sigB | 0x0400)<<4;
121 sigProd = (uint_fast32_t) sigA * sigB;
122 if ( sigProd < 0x20000000 ) {
123 --expProd;
124 sigProd <<= 1;
125 }
126 signZ = signProd;
127 if ( ! expC ) {
128 if ( ! sigC ) {
129 expZ = expProd - 1;
130 sigZ = sigProd>>15 | ((sigProd & 0x7FFF) != 0);
131 goto roundPack;
132 }
133 normExpSig = softfloat_normSubnormalF16Sig( sigC );
134 expC = normExpSig.exp;
135 sigC = normExpSig.sig;
136 }
137 sigC = (sigC | 0x0400)<<3;
138 /*------------------------------------------------------------------------
139 *------------------------------------------------------------------------*/
140 expDiff = expProd - expC;
141 if ( signProd == signC ) {
142 /*--------------------------------------------------------------------
143 *--------------------------------------------------------------------*/
144 if ( expDiff <= 0 ) {
145 expZ = expC;
146 sigZ = sigC + softfloat_shiftRightJam32( sigProd, 16 - expDiff );
147 } else {
148 expZ = expProd;
149 sig32Z =
150 sigProd
152 (uint_fast32_t) sigC<<16, expDiff );
153 sigZ = sig32Z>>16 | ((sig32Z & 0xFFFF) != 0 );
154 }
155 if ( sigZ < 0x4000 ) {
156 --expZ;
157 sigZ <<= 1;
158 }
159 } else {
160 /*--------------------------------------------------------------------
161 *--------------------------------------------------------------------*/
162 sig32C = (uint_fast32_t) sigC<<16;
163 if ( expDiff < 0 ) {
164 signZ = signC;
165 expZ = expC;
166 sig32Z = sig32C - softfloat_shiftRightJam32( sigProd, -expDiff );
167 } else if ( ! expDiff ) {
168 expZ = expProd;
169 sig32Z = sigProd - sig32C;
170 if ( ! sig32Z ) goto completeCancellation;
171 if ( sig32Z & 0x80000000 ) {
172 signZ = ! signZ;
173 sig32Z = -sig32Z;
174 }
175 } else {
176 expZ = expProd;
177 sig32Z = sigProd - softfloat_shiftRightJam32( sig32C, expDiff );
178 }
179 shiftDist = softfloat_countLeadingZeros32( sig32Z ) - 1;
180 expZ -= shiftDist;
181 shiftDist -= 16;
182 if ( shiftDist < 0 ) {
183 sigZ =
184 sig32Z>>(-shiftDist)
185 | ((uint32_t) (sig32Z<<(shiftDist & 31)) != 0);
186 } else {
187 sigZ = (uint_fast16_t) sig32Z<<shiftDist;
188 }
189 }
190 roundPack:
191 return softfloat_roundPackToF16( signZ, expZ, sigZ );
192 /*------------------------------------------------------------------------
193 *------------------------------------------------------------------------*/
194 propagateNaN_ABC:
195 uiZ = softfloat_propagateNaNF16UI( uiA, uiB );
196 goto propagateNaN_ZC;
197 /*------------------------------------------------------------------------
198 *------------------------------------------------------------------------*/
199 infProdArg:
200 if ( magBits ) {
201 uiZ = packToF16UI( signProd, 0x1F, 0 );
202 if ( expC != 0x1F ) goto uiZ;
203 if ( sigC ) goto propagateNaN_ZC;
204 if ( signProd == signC ) goto uiZ;
205 }
207 uiZ = defaultNaNF16UI;
208 propagateNaN_ZC:
209 uiZ = softfloat_propagateNaNF16UI( uiZ, uiC );
210 goto uiZ;
211 /*------------------------------------------------------------------------
212 *------------------------------------------------------------------------*/
213 zeroProd:
214 uiZ = uiC;
215 if ( ! (expC | sigC) && (signProd != signC) ) {
216 completeCancellation:
217 uiZ =
220 }
221 uiZ:
222 uZ.ui = uiZ;
223 return uZ.f;
224
225}
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB)
void softfloat_raiseFlags(uint_fast8_t flags)
#define defaultNaNF16UI
Definition specialize.h:88
#define expF16UI(a)
Definition internals.h:84
#define signF16UI(a)
Definition internals.h:83
float16_t softfloat_roundPackToF16(bool, int_fast16_t, uint_fast16_t)
#define fracF16UI(a)
Definition internals.h:85
struct exp8_sig16 softfloat_normSubnormalF16Sig(uint_fast16_t)
@ softfloat_mulAdd_subProd
Definition internals.h:56
@ softfloat_mulAdd_subC
Definition internals.h:55
#define packToF16UI(sign, exp, sig)
Definition internals.h:86
uint32_t softfloat_shiftRightJam32(uint32_t a, uint_fast16_t dist)
THREAD_LOCAL uint_fast8_t softfloat_roundingMode
@ softfloat_flag_invalid
Definition softfloat.h:89
@ softfloat_round_min
Definition softfloat.h:74
#define softfloat_countLeadingZeros32
unsigned int uint32_t
Definition stdint.h:126
uint16_t uint_fast16_t
Definition stdint.h:155
int8_t int_fast8_t
Definition stdint.h:150
uint32_t uint_fast32_t
Definition stdint.h:156