45{
52 bool signZ;
60
61
62
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 }
83 expZ = expA;
84 sigZ = 0x0800 + sigA + sigB;
85 if ( ! (sigZ & 1) && (expZ < 0x1E) ) {
86 sigZ >>= 1;
88 }
89 sigZ <<= 3;
90 } else {
91
92
94 if ( expDiff < 0 ) {
95
96
97 if ( expB == 0x1F ) {
98 if ( sigB ) goto propagateNaN;
100 goto uiZ;
101 }
102 if ( expDiff <= -13 ) {
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 =
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;
141 }
142 }
143 }
145
146
147 propagateNaN:
149 goto uiZ;
150
151
152 addEpsilon:
155 if (
156 roundingMode
159 ) {
160 ++uiZ;
161 if ( (
uint16_t) (uiZ<<1) == 0xF800 ) {
164 }
165 }
166#ifdef SOFTFLOAT_ROUND_ODD
168 uiZ |= 1;
169 }
170#endif
171 }
173 goto uiZ;
174
175
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)
float16_t softfloat_roundPackToF16(bool, int_fast16_t, uint_fast16_t)
#define packToF16UI(sign, exp, sig)
THREAD_LOCAL uint_fast8_t softfloat_roundingMode
@ softfloat_flag_overflow
THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags
@ softfloat_round_near_even