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

Go to the source code of this file.

Functions

float16_t softfloat_addMagsF16 (uint_fast16_t uiA, uint_fast16_t uiB)
 

Function Documentation

◆ softfloat_addMagsF16()

float16_t softfloat_addMagsF16 ( uint_fast16_t uiA,
uint_fast16_t uiB )

Definition at line 44 of file s_addMagsF16.c.

45{
46 int_fast8_t expA;
47 uint_fast16_t sigA;
48 int_fast8_t expB;
49 uint_fast16_t sigB;
50 int_fast8_t expDiff;
51 uint_fast16_t uiZ;
52 bool signZ;
53 int_fast8_t expZ;
54 uint_fast16_t sigZ;
55 uint_fast16_t sigX, sigY;
56 int_fast8_t shiftDist;
57 uint_fast32_t sig32Z;
58 int_fast8_t roundingMode;
59 union ui16_f16 uZ;
60
61 /*------------------------------------------------------------------------
62 *------------------------------------------------------------------------*/
63 expA = expF16UI( uiA );
64 sigA = fracF16UI( uiA );
65 expB = expF16UI( uiB );
66 sigB = fracF16UI( uiB );
67 /*------------------------------------------------------------------------
68 *------------------------------------------------------------------------*/
69 expDiff = expA - expB;
70 if ( ! expDiff ) {
71 /*--------------------------------------------------------------------
72 *--------------------------------------------------------------------*/
73 if ( ! expA ) {
74 uiZ = uiA + sigB;
75 goto uiZ;
76 }
77 if ( expA == 0x1F ) {
78 if ( sigA | sigB ) goto propagateNaN;
79 uiZ = uiA;
80 goto uiZ;
81 }
82 signZ = signF16UI( uiA );
83 expZ = expA;
84 sigZ = 0x0800 + sigA + sigB;
85 if ( ! (sigZ & 1) && (expZ < 0x1E) ) {
86 sigZ >>= 1;
87 goto pack;
88 }
89 sigZ <<= 3;
90 } else {
91 /*--------------------------------------------------------------------
92 *--------------------------------------------------------------------*/
93 signZ = signF16UI( uiA );
94 if ( expDiff < 0 ) {
95 /*----------------------------------------------------------------
96 *----------------------------------------------------------------*/
97 if ( expB == 0x1F ) {
98 if ( sigB ) goto propagateNaN;
99 uiZ = packToF16UI( signZ, 0x1F, 0 );
100 goto uiZ;
101 }
102 if ( expDiff <= -13 ) {
103 uiZ = packToF16UI( signZ, expB, sigB );
104 if ( expA | sigA ) goto addEpsilon;
105 goto uiZ;
106 }
107 expZ = expB;
108 sigX = sigB | 0x0400;
109 sigY = sigA + (expA ? 0x0400 : sigA);
110 shiftDist = 19 + expDiff;
111 } else {
112 /*----------------------------------------------------------------
113 *----------------------------------------------------------------*/
114 uiZ = uiA;
115 if ( expA == 0x1F ) {
116 if ( sigA ) goto propagateNaN;
117 goto uiZ;
118 }
119 if ( 13 <= expDiff ) {
120 if ( expB | sigB ) goto addEpsilon;
121 goto uiZ;
122 }
123 expZ = expA;
124 sigX = sigA | 0x0400;
125 sigY = sigB + (expB ? 0x0400 : sigB);
126 shiftDist = 19 - expDiff;
127 }
128 sig32Z =
129 ((uint_fast32_t) sigX<<19) + ((uint_fast32_t) sigY<<shiftDist);
130 if ( sig32Z < 0x40000000 ) {
131 --expZ;
132 sig32Z <<= 1;
133 }
134 sigZ = sig32Z>>16;
135 if ( sig32Z & 0xFFFF ) {
136 sigZ |= 1;
137 } else {
138 if ( ! (sigZ & 0xF) && (expZ < 0x1E) ) {
139 sigZ >>= 4;
140 goto pack;
141 }
142 }
143 }
144 return softfloat_roundPackToF16( signZ, expZ, sigZ );
145 /*------------------------------------------------------------------------
146 *------------------------------------------------------------------------*/
147 propagateNaN:
148 uiZ = softfloat_propagateNaNF16UI( uiA, uiB );
149 goto uiZ;
150 /*------------------------------------------------------------------------
151 *------------------------------------------------------------------------*/
152 addEpsilon:
153 roundingMode = softfloat_roundingMode;
154 if ( roundingMode != softfloat_round_near_even ) {
155 if (
156 roundingMode
157 == (signF16UI( uiZ ) ? softfloat_round_min
159 ) {
160 ++uiZ;
161 if ( (uint16_t) (uiZ<<1) == 0xF800 ) {
164 }
165 }
166#ifdef SOFTFLOAT_ROUND_ODD
167 else if ( roundingMode == softfloat_round_odd ) {
168 uiZ |= 1;
169 }
170#endif
171 }
173 goto uiZ;
174 /*------------------------------------------------------------------------
175 *------------------------------------------------------------------------*/
176 pack:
177 uiZ = packToF16UI( signZ, expZ, sigZ );
178 uiZ:
179 uZ.ui = uiZ;
180 return uZ.f;
181
182}
void pack(instruction_stream *stream, uint32_t field)
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB)
void softfloat_raiseFlags(uint_fast8_t flags)
#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
#define packToF16UI(sign, exp, sig)
Definition internals.h:86
THREAD_LOCAL uint_fast8_t softfloat_roundingMode
@ softfloat_flag_inexact
Definition softfloat.h:85
@ softfloat_flag_overflow
Definition softfloat.h:87
THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags
@ softfloat_round_odd
Definition softfloat.h:77
@ softfloat_round_max
Definition softfloat.h:75
@ softfloat_round_min
Definition softfloat.h:74
@ softfloat_round_near_even
Definition softfloat.h:72
unsigned short uint16_t
Definition stdint.h:125
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