Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
s_roundPackToExtF80.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include "platform.h"
#include "internals.h"
#include "softfloat.h"
Include dependency graph for s_roundPackToExtF80.c:

Go to the source code of this file.

Functions

extFloat80_t softfloat_roundPackToExtF80 (bool sign, int_fast32_t exp, uint_fast64_t sig, uint_fast64_t sigExtra, uint_fast8_t roundingPrecision)
 

Function Documentation

◆ softfloat_roundPackToExtF80()

extFloat80_t softfloat_roundPackToExtF80 ( bool sign,
int_fast32_t exp,
uint_fast64_t sig,
uint_fast64_t sigExtra,
uint_fast8_t roundingPrecision )

Definition at line 44 of file s_roundPackToExtF80.c.

51{
52 uint_fast8_t roundingMode;
53 bool roundNearEven;
54 uint_fast64_t roundIncrement, roundMask, roundBits;
55 bool isTiny, doIncrement;
56 struct uint64_extra sig64Extra;
57 union { struct extFloat80M s; extFloat80_t f; } uZ;
58
59 /*------------------------------------------------------------------------
60 *------------------------------------------------------------------------*/
61 roundingMode = softfloat_roundingMode;
62 roundNearEven = (roundingMode == softfloat_round_near_even);
63 if ( roundingPrecision == 80 ) goto precision80;
64 if ( roundingPrecision == 64 ) {
65 roundIncrement = UINT64_C( 0x0000000000000400 );
66 roundMask = UINT64_C( 0x00000000000007FF );
67 } else if ( roundingPrecision == 32 ) {
68 roundIncrement = UINT64_C( 0x0000008000000000 );
69 roundMask = UINT64_C( 0x000000FFFFFFFFFF );
70 } else {
71 goto precision80;
72 }
73 sig |= (sigExtra != 0);
74 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
75 roundIncrement =
76 (roundingMode
78 ? roundMask
79 : 0;
80 }
81 roundBits = sig & roundMask;
82 /*------------------------------------------------------------------------
83 *------------------------------------------------------------------------*/
84 if ( 0x7FFD <= (uint32_t) (exp - 1) ) {
85 if ( exp <= 0 ) {
86 /*----------------------------------------------------------------
87 *----------------------------------------------------------------*/
88 isTiny =
91 || (exp < 0)
92 || (sig <= (uint64_t) (sig + roundIncrement));
93 sig = softfloat_shiftRightJam64( sig, 1 - exp );
94 roundBits = sig & roundMask;
95 if ( roundBits ) {
98#ifdef SOFTFLOAT_ROUND_ODD
99 if ( roundingMode == softfloat_round_odd ) {
100 sig |= roundMask + 1;
101 }
102#endif
103 }
104 sig += roundIncrement;
105 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);
106 roundIncrement = roundMask + 1;
107 if ( roundNearEven && (roundBits<<1 == roundIncrement) ) {
108 roundMask |= roundIncrement;
109 }
110 sig &= ~roundMask;
111 goto packReturn;
112 }
113 if (
114 (0x7FFE < exp)
115 || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig))
116 ) {
117 goto overflow;
118 }
119 }
120 /*------------------------------------------------------------------------
121 *------------------------------------------------------------------------*/
122 if ( roundBits ) {
124#ifdef SOFTFLOAT_ROUND_ODD
125 if ( roundingMode == softfloat_round_odd ) {
126 sig = (sig & ~roundMask) | (roundMask + 1);
127 goto packReturn;
128 }
129#endif
130 }
131 sig = (uint64_t) (sig + roundIncrement);
132 if ( sig < roundIncrement ) {
133 ++exp;
134 sig = UINT64_C( 0x8000000000000000 );
135 }
136 roundIncrement = roundMask + 1;
137 if ( roundNearEven && (roundBits<<1 == roundIncrement) ) {
138 roundMask |= roundIncrement;
139 }
140 sig &= ~roundMask;
141 goto packReturn;
142 /*------------------------------------------------------------------------
143 *------------------------------------------------------------------------*/
144 precision80:
145 doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra);
146 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
147 doIncrement =
148 (roundingMode
150 && sigExtra;
151 }
152 /*------------------------------------------------------------------------
153 *------------------------------------------------------------------------*/
154 if ( 0x7FFD <= (uint32_t) (exp - 1) ) {
155 if ( exp <= 0 ) {
156 /*----------------------------------------------------------------
157 *----------------------------------------------------------------*/
158 isTiny =
161 || (exp < 0)
162 || ! doIncrement
163 || (sig < UINT64_C( 0xFFFFFFFFFFFFFFFF ));
164 sig64Extra =
165 softfloat_shiftRightJam64Extra( sig, sigExtra, 1 - exp );
166 exp = 0;
167 sig = sig64Extra.v;
168 sigExtra = sig64Extra.extra;
169 if ( sigExtra ) {
172#ifdef SOFTFLOAT_ROUND_ODD
173 if ( roundingMode == softfloat_round_odd ) {
174 sig |= 1;
175 goto packReturn;
176 }
177#endif
178 }
179 doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra);
180 if (
181 ! roundNearEven
182 && (roundingMode != softfloat_round_near_maxMag)
183 ) {
184 doIncrement =
185 (roundingMode
187 && sigExtra;
188 }
189 if ( doIncrement ) {
190 ++sig;
191 sig &=
193 (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
194 & roundNearEven);
195 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);
196 }
197 goto packReturn;
198 }
199 if (
200 (0x7FFE < exp)
201 || ((exp == 0x7FFE) && (sig == UINT64_C( 0xFFFFFFFFFFFFFFFF ))
202 && doIncrement)
203 ) {
204 /*----------------------------------------------------------------
205 *----------------------------------------------------------------*/
206 roundMask = 0;
207 overflow:
210 if (
211 roundNearEven
212 || (roundingMode == softfloat_round_near_maxMag)
213 || (roundingMode
215 ) {
216 exp = 0x7FFF;
217 sig = UINT64_C( 0x8000000000000000 );
218 } else {
219 exp = 0x7FFE;
220 sig = ~roundMask;
221 }
222 goto packReturn;
223 }
224 }
225 /*------------------------------------------------------------------------
226 *------------------------------------------------------------------------*/
227 if ( sigExtra ) {
229#ifdef SOFTFLOAT_ROUND_ODD
230 if ( roundingMode == softfloat_round_odd ) {
231 sig |= 1;
232 goto packReturn;
233 }
234#endif
235 }
236 if ( doIncrement ) {
237 ++sig;
238 if ( ! sig ) {
239 ++exp;
240 sig = UINT64_C( 0x8000000000000000 );
241 } else {
242 sig &=
244 (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
245 & roundNearEven);
246 }
247 }
248 /*------------------------------------------------------------------------
249 *------------------------------------------------------------------------*/
250 packReturn:
251 uZ.s.signExp = packToExtF80UI64( sign, exp );
252 uZ.s.signif = sig;
253 return uZ.f;
254
255}
void softfloat_raiseFlags(uint_fast8_t flags)
#define packToExtF80UI64(sign, exp)
Definition internals.h:148
uint64_t softfloat_shiftRightJam64(uint64_t a, uint_fast32_t dist)
THREAD_LOCAL uint_fast8_t softfloat_roundingMode
@ softfloat_flag_inexact
Definition softfloat.h:85
@ softfloat_flag_underflow
Definition softfloat.h:86
@ softfloat_flag_overflow
Definition softfloat.h:87
THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags
THREAD_LOCAL uint_fast8_t softfloat_detectTininess
@ 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
@ softfloat_round_near_maxMag
Definition softfloat.h:76
@ softfloat_tininess_beforeRounding
Definition softfloat.h:62
struct uint64_extra softfloat_shiftRightJam64Extra(uint64_t a, uint64_t extra, uint_fast32_t dist)
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
uint8_t uint_fast8_t
Definition stdint.h:154
unsigned __int64 uint64_t
Definition stdint.h:136
bool overflow
char * s
Here is the call graph for this function: