Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
softfloat.hpp
Go to the documentation of this file.
1#pragma once
2#ifdef SYS_VM_SOFTFLOAT
3#include <sysio/vm/exceptions.hpp>
4
5#include <cstdint>
6
7#include <softfloat.hpp>
8
9namespace sysio { namespace vm {
10inline constexpr uint32_t inv_float_eps = 0x4B000000;
11inline constexpr uint64_t inv_double_eps = 0x4330000000000000;
12
13inline bool is_nan( const float32_t f ) {
14 return f32_is_nan( f );
15}
16inline bool is_nan( const float64_t f ) {
17 return f64_is_nan( f );
18}
19
20inline float _sysio_f32_add( float a, float b ) {
21 return ::from_softfloat32( ::f32_add( ::to_softfloat32(a), ::to_softfloat32(b) ) );
22}
23
24inline float _sysio_f32_sub( float a, float b ) {
25 return ::from_softfloat32( ::f32_sub( ::to_softfloat32(a), ::to_softfloat32(b) ) );
26}
27
28inline float _sysio_f32_div( float a, float b ) {
29 return ::from_softfloat32( ::f32_div( ::to_softfloat32(a), ::to_softfloat32(b) ) );
30}
31
32inline float _sysio_f32_mul( float a, float b ) {
33 return ::from_softfloat32( ::f32_mul( ::to_softfloat32(a), ::to_softfloat32(b) ) );
34}
35
36inline float _sysio_f32_min( float af, float bf ) {
39 if (is_nan(a)) {
40 return af;
41 }
42 if (is_nan(b)) {
43 return bf;
44 }
45 if ( f32_sign_bit(a) != f32_sign_bit(b) ) {
46 return f32_sign_bit(a) ? af : bf;
47 }
48 return ::f32_lt(a,b) ? af : bf;
49}
50
51inline float _sysio_f32_max( float af, float bf ) {
54 if (is_nan(a)) {
55 return af;
56 }
57 if (is_nan(b)) {
58 return bf;
59 }
60 if ( f32_sign_bit(a) != f32_sign_bit(b) ) {
61 return f32_sign_bit(a) ? bf : af;
62 }
63 return ::f32_lt( a, b ) ? bf : af;
64}
65
66inline float _sysio_f32_copysign( float af, float bf ) {
69 a.v &= ~(1 << 31); // clear the sign bit
70 a.v = a.v | ((b.v >> 31) << 31); // add the sign of b
71 return from_softfloat32(a);
72}
73
74inline float _sysio_f32_abs( float af ) {
76 a.v &= ~(1 << 31);
77 return from_softfloat32(a);
78}
79
80inline float _sysio_f32_neg( float af ) {
82 uint32_t sign = a.v >> 31;
83 a.v &= ~(1 << 31);
84 a.v |= (!sign << 31);
85 return from_softfloat32(a);
86}
87
88inline float _sysio_f32_sqrt( float a ) {
90 return from_softfloat32(ret);
91}
92
93inline float _sysio_f32_ceil( float af ) {
95 int e = (int)(a.v >> 23 & 0xFF) - 0X7F;
96 uint32_t m;
97 if (e >= 23)
98 return af;
99 if (e >= 0) {
100 m = 0x007FFFFF >> e;
101 if ((a.v & m) == 0)
102 return af;
103 if (a.v >> 31 == 0)
104 a.v += m;
105 a.v &= ~m;
106 } else {
107 if (a.v >> 31)
108 a.v = 0x80000000; // return -0.0f
109 else if (a.v << 1)
110 a.v = 0x3F800000; // return 1.0f
111 }
112
113 return from_softfloat32(a);
114}
115
116inline float _sysio_f32_floor( float af ) {
118 int e = (int)(a.v >> 23 & 0xFF) - 0X7F;
119 uint32_t m;
120 if (e >= 23)
121 return af;
122 if (e >= 0) {
123 m = 0x007FFFFF >> e;
124 if ((a.v & m) == 0)
125 return af;
126 if (a.v >> 31)
127 a.v += m;
128 a.v &= ~m;
129 } else {
130 if (a.v >> 31 == 0)
131 a.v = 0;
132 else if (a.v << 1)
133 a.v = 0xBF800000; // return -1.0f
134 }
135 return from_softfloat32(a);
136}
137
138inline float _sysio_f32_trunc( float af ) {
140 int e = (int)(a.v >> 23 & 0xff) - 0x7f + 9;
141 uint32_t m;
142 if (e >= 23 + 9)
143 return af;
144 if (e < 9)
145 e = 1;
146 m = -1U >> e;
147 if ((a.v & m) == 0)
148 return af;
149 a.v &= ~m;
150 return from_softfloat32(a);
151}
152
153inline float _sysio_f32_nearest( float af ) {
155 int e = a.v>>23 & 0xff;
156 int s = a.v>>31;
157 float32_t y;
158 if (e >= 0x7f+23)
159 return af;
160 if (s)
161 y = ::f32_add( ::f32_sub( a, float32_t{inv_float_eps} ), float32_t{inv_float_eps} );
162 else
163 y = ::f32_sub( ::f32_add( a, float32_t{inv_float_eps} ), float32_t{inv_float_eps} );
164 if (::f32_eq( y, {0} ) )
165 return s ? -0.0f : 0.0f;
166 return from_softfloat32(y);
167}
168
169inline bool _sysio_f32_eq( float a, float b ) { return ::f32_eq( to_softfloat32(a), to_softfloat32(b) ); }
170inline bool _sysio_f32_ne( float a, float b ) { return !::f32_eq( to_softfloat32(a), to_softfloat32(b) ); }
171inline bool _sysio_f32_lt( float a, float b ) { return ::f32_lt( to_softfloat32(a), to_softfloat32(b) ); }
172inline bool _sysio_f32_le( float a, float b ) { return ::f32_le( to_softfloat32(a), to_softfloat32(b) ); }
173inline bool _sysio_f32_gt( float af, float bf ) {
176 if (is_nan(a))
177 return false;
178 if (is_nan(b))
179 return false;
180 return !::f32_le( a, b );
181}
182
183inline bool _sysio_f32_ge( float af, float bf ) {
186 if (is_nan(a))
187 return false;
188 if (is_nan(b))
189 return false;
190 return !::f32_lt( a, b );
191}
192
193inline double _sysio_f64_add( double a, double b ) {
195 return from_softfloat64(ret);
196}
197
198inline double _sysio_f64_sub( double a, double b ) {
200 return from_softfloat64(ret);
201}
202
203inline double _sysio_f64_div( double a, double b ) {
205 return from_softfloat64(ret);
206}
207
208inline double _sysio_f64_mul( double a, double b ) {
210 return from_softfloat64(ret);
211}
212
213inline double _sysio_f64_min( double af, double bf ) {
216 if (is_nan(a))
217 return af;
218 if (is_nan(b))
219 return bf;
220 if (f64_sign_bit(a) != f64_sign_bit(b))
221 return f64_sign_bit(a) ? af : bf;
222 return ::f64_lt( a, b ) ? af : bf;
223}
224
225inline double _sysio_f64_max( double af, double bf ) {
228 if (is_nan(a))
229 return af;
230 if (is_nan(b))
231 return bf;
232 if (f64_sign_bit(a) != f64_sign_bit(b))
233 return f64_sign_bit(a) ? bf : af;
234 return ::f64_lt( a, b ) ? bf : af;
235}
236
237inline double _sysio_f64_copysign( double af, double bf ) {
240 a.v &= ~(uint64_t(1) << 63); // clear the sign bit
241 a.v = a.v | ((b.v >> 63) << 63); // add the sign of b
242 return from_softfloat64(a);
243}
244
245inline double _sysio_f64_abs( double af ) {
247 a.v &= ~(uint64_t(1) << 63);
248 return from_softfloat64(a);
249}
250
251inline double _sysio_f64_neg( double af ) {
253 uint64_t sign = a.v >> 63;
254 a.v &= ~(uint64_t(1) << 63);
255 a.v |= (uint64_t(!sign) << 63);
256 return from_softfloat64(a);
257}
258
259inline double _sysio_f64_sqrt( double a ) {
261 return from_softfloat64(ret);
262}
263
264inline double _sysio_f64_ceil( double af ) {
265 float64_t a = to_softfloat64( af );
267 int e = a.v >> 52 & 0x7ff;
268 float64_t y;
269 if (e >= 0x3ff+52 || ::f64_eq( a, { 0 } ))
270 return af;
271 /* y = int(x) - x, where int(x) is an integer neighbor of x */
272 if (a.v >> 63)
273 y = ::f64_sub( ::f64_add( ::f64_sub( a, float64_t{inv_double_eps} ), float64_t{inv_double_eps} ), a );
274 else
275 y = ::f64_sub( ::f64_sub( ::f64_add( a, float64_t{inv_double_eps} ), float64_t{inv_double_eps} ), a );
276 /* special case because of non-nearest rounding modes */
277 if (e <= 0x3ff-1) {
278 return a.v >> 63 ? -0.0 : 1.0; //float64_t{0x8000000000000000} : float64_t{0xBE99999A3F800000}; //either -0.0 or 1
279 }
280 if (::f64_lt( y, to_softfloat64(0) )) {
281 ret = ::f64_add( ::f64_add( a, y ), to_softfloat64(1) ); // 0xBE99999A3F800000 } ); // plus 1
282 return from_softfloat64(ret);
283 }
284 ret = ::f64_add( a, y );
285 return from_softfloat64(ret);
286}
287
288inline double _sysio_f64_floor( double af ) {
289 float64_t a = to_softfloat64( af );
291 int e = a.v >> 52 & 0x7FF;
292 float64_t y;
293 if ( a.v == 0x8000000000000000) {
294 return af;
295 }
296 if (e >= 0x3FF+52 || a.v == 0) {
297 return af;
298 }
299 if (a.v >> 63)
300 y = ::f64_sub( ::f64_add( ::f64_sub( a, float64_t{inv_double_eps} ), float64_t{inv_double_eps} ), a );
301 else
302 y = ::f64_sub( ::f64_sub( ::f64_add( a, float64_t{inv_double_eps} ), float64_t{inv_double_eps} ), a );
303 if (e <= 0x3FF-1) {
304 return a.v>>63 ? -1.0 : 0.0; //float64_t{0xBFF0000000000000} : float64_t{0}; // -1 or 0
305 }
306 if ( !::f64_le( y, float64_t{0} ) ) {
308 return from_softfloat64(ret);
309 }
310 ret = ::f64_add( a, y );
311 return from_softfloat64(ret);
312}
313
314inline double _sysio_f64_trunc( double af ) {
315 float64_t a = to_softfloat64( af );
316 int e = (int)(a.v >> 52 & 0x7ff) - 0x3ff + 12;
317 uint64_t m;
318 if (e >= 52 + 12)
319 return af;
320 if (e < 12)
321 e = 1;
322 m = -1ULL >> e;
323 if ((a.v & m) == 0)
324 return af;
325 a.v &= ~m;
326 return from_softfloat64(a);
327}
328
329inline double _sysio_f64_nearest( double af ) {
330 float64_t a = to_softfloat64( af );
331 int e = (a.v >> 52 & 0x7FF);
332 int s = a.v >> 63;
333 float64_t y;
334 if ( e >= 0x3FF+52 )
335 return af;
336 if ( s )
337 y = ::f64_add( ::f64_sub( a, float64_t{inv_double_eps} ), float64_t{inv_double_eps} );
338 else
339 y = ::f64_sub( ::f64_add( a, float64_t{inv_double_eps} ), float64_t{inv_double_eps} );
340 if ( ::f64_eq( y, float64_t{0} ) )
341 return s ? -0.0 : 0.0;
342 return from_softfloat64(y);
343}
344
345inline bool _sysio_f64_eq( double a, double b ) { return ::f64_eq( to_softfloat64(a), to_softfloat64(b) ); }
346inline bool _sysio_f64_ne( double a, double b ) { return !::f64_eq( to_softfloat64(a), to_softfloat64(b) ); }
347inline bool _sysio_f64_lt( double a, double b ) { return ::f64_lt( to_softfloat64(a), to_softfloat64(b) ); }
348inline bool _sysio_f64_le( double a, double b ) { return ::f64_le( to_softfloat64(a), to_softfloat64(b) ); }
349inline bool _sysio_f64_gt( double af, double bf ) {
352 if (is_nan(a))
353 return false;
354 if (is_nan(b))
355 return false;
356 return !::f64_le( a, b );
357}
358
359inline bool _sysio_f64_ge( double af, double bf ) {
362 if (is_nan(a))
363 return false;
364 if (is_nan(b))
365 return false;
366 return !::f64_lt( a, b );
367}
368
369inline double _sysio_f32_promote( float a ) {
371}
372
373inline float _sysio_f64_demote( double a ) {
375}
376
377inline int32_t _sysio_f32_trunc_i32s( float af ) {
379 SYS_VM_ASSERT(!(_sysio_f32_ge(af, 2147483648.0f) || _sysio_f32_lt(af, -2147483648.0f)), wasm_interpreter_exception, "Error, f32.convert_s/i32 overflow" );
380
381 SYS_VM_ASSERT(!is_nan(a), wasm_interpreter_exception, "Error, f32.convert_s/i32 unrepresentable");
382 return f32_to_i32( to_softfloat32(_sysio_f32_trunc( af )), 0, false );
383}
384
385inline int32_t _sysio_f64_trunc_i32s( double af ) {
387 SYS_VM_ASSERT(!(_sysio_f64_ge(af, 2147483648.0) || _sysio_f64_lt(af, -2147483648.0)), wasm_interpreter_exception, "Error, f64.convert_s/i32 overflow");
388 SYS_VM_ASSERT(!is_nan(a), wasm_interpreter_exception, "Error, f64.convert_s/i32 unrepresentable");
389 return f64_to_i32( to_softfloat64(_sysio_f64_trunc( af )), 0, false );
390}
391
392inline uint32_t _sysio_f32_trunc_i32u( float af ) {
394 SYS_VM_ASSERT(!(_sysio_f32_ge(af, 4294967296.0f) || _sysio_f32_le(af, -1.0f)),wasm_interpreter_exception, "Error, f32.convert_u/i32 overflow");
395 SYS_VM_ASSERT(!is_nan(a), wasm_interpreter_exception, "Error, f32.convert_u/i32 unrepresentable");
396 return f32_to_ui32( to_softfloat32(_sysio_f32_trunc( af )), 0, false );
397}
398
399inline uint32_t _sysio_f64_trunc_i32u( double af ) {
401 SYS_VM_ASSERT(!(_sysio_f64_ge(af, 4294967296.0) || _sysio_f64_le(af, -1.0)), wasm_interpreter_exception, "Error, f64.convert_u/i32 overflow");
402 SYS_VM_ASSERT(!is_nan(a), wasm_interpreter_exception, "Error, f64.convert_u/i32 unrepresentable");
403 return f64_to_ui32( to_softfloat64(_sysio_f64_trunc( af )), 0, false );
404}
405
406inline int64_t _sysio_f32_trunc_i64s( float af ) {
408 SYS_VM_ASSERT(!(_sysio_f32_ge(af, 9223372036854775808.0f) || _sysio_f32_lt(af, -9223372036854775808.0f)), wasm_interpreter_exception, "Error, f32.convert_s/i64 overflow");
409 SYS_VM_ASSERT(!is_nan(a), wasm_interpreter_exception, "Error, f32.convert_s/i64 unrepresentable");
410 return f32_to_i64( to_softfloat32(_sysio_f32_trunc( af )), 0, false );
411}
412
413inline int64_t _sysio_f64_trunc_i64s( double af ) {
415 SYS_VM_ASSERT(!(_sysio_f64_ge(af, 9223372036854775808.0) || _sysio_f64_lt(af, -9223372036854775808.0)), wasm_interpreter_exception, "Error, f64.convert_s/i64 overflow");
416 SYS_VM_ASSERT(!is_nan(a), wasm_interpreter_exception, "Error, f64.convert_s/i64 unrepresentable");
417
418 return f64_to_i64( to_softfloat64(_sysio_f64_trunc( af )), 0, false );
419}
420
421inline uint64_t _sysio_f32_trunc_i64u( float af ) {
423 SYS_VM_ASSERT(!(_sysio_f32_ge(af, 18446744073709551616.0f) || _sysio_f32_le(af, -1.0f)), wasm_interpreter_exception, "Error, f32.convert_u/i64 overflow");
424 SYS_VM_ASSERT(!is_nan(a), wasm_interpreter_exception, "Error, f32.convert_u/i64 unrepresentable");
425 return f32_to_ui64( to_softfloat32(_sysio_f32_trunc( af )), 0, false );
426}
427
428inline uint64_t _sysio_f64_trunc_i64u( double af ) {
430 SYS_VM_ASSERT(!(_sysio_f64_ge(af, 18446744073709551616.0) || _sysio_f64_le(af, -1.0)), wasm_interpreter_exception, "Error, f64.convert_u/i64 overflow");
431 SYS_VM_ASSERT(!is_nan(a), wasm_interpreter_exception, "Error, f64.convert_u/i64 unrepresentable");
432 return f64_to_ui64( to_softfloat64(_sysio_f64_trunc( af )), 0, false );
433}
434
435inline float _sysio_i32_to_f32( int32_t a ) {
436 return from_softfloat32(i32_to_f32( a ));
437}
438
439inline float _sysio_i64_to_f32( int64_t a ) {
440 return from_softfloat32(i64_to_f32( a ));
441}
442
443inline float _sysio_ui32_to_f32( uint32_t a ) {
444 return from_softfloat32(ui32_to_f32( a ));
445}
446
447inline float _sysio_ui64_to_f32( uint64_t a ) {
448 return from_softfloat32(ui64_to_f32( a ));
449}
450
451inline double _sysio_i32_to_f64( int32_t a ) {
452 return from_softfloat64(i32_to_f64( a ));
453}
454
455inline double _sysio_i64_to_f64( int64_t a ) {
456 return from_softfloat64(i64_to_f64( a ));
457}
458
459inline double _sysio_ui32_to_f64( uint32_t a ) {
460 return from_softfloat64(ui32_to_f64( a ));
461}
462
463inline double _sysio_ui64_to_f64( uint64_t a ) {
464 return from_softfloat64(ui64_to_f64( a ));
465}
466}} //ns sysio::vm
467#endif
uint64_t y
Definition sha3.cpp:34
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
float32_t f32_add(float32_t a, float32_t b)
Definition f32_add.c:43
float32_t f32_div(float32_t a, float32_t b)
Definition f32_div.c:44
bool f32_eq(float32_t a, float32_t b)
Definition f32_eq.c:44
bool f32_le(float32_t a, float32_t b)
Definition f32_le.c:43
bool f32_lt(float32_t a, float32_t b)
Definition f32_lt.c:43
float32_t f32_mul(float32_t a, float32_t b)
Definition f32_mul.c:44
float32_t f32_sqrt(float32_t a)
Definition f32_sqrt.c:44
float32_t f32_sub(float32_t a, float32_t b)
Definition f32_sub.c:43
float64_t f32_to_f64(float32_t a)
Definition f32_to_f64.c:44
int_fast32_t f32_to_i32(float32_t a, uint_fast8_t roundingMode, bool exact)
Definition f32_to_i32.c:44
int_fast64_t f32_to_i64(float32_t a, uint_fast8_t roundingMode, bool exact)
Definition f32_to_i64.c:44
uint_fast32_t f32_to_ui32(float32_t a, uint_fast8_t roundingMode, bool exact)
Definition f32_to_ui32.c:44
uint_fast64_t f32_to_ui64(float32_t a, uint_fast8_t roundingMode, bool exact)
Definition f32_to_ui64.c:44
float64_t f64_add(float64_t a, float64_t b)
Definition f64_add.c:43
float64_t f64_div(float64_t a, float64_t b)
Definition f64_div.c:44
bool f64_eq(float64_t a, float64_t b)
Definition f64_eq.c:44
bool f64_le(float64_t a, float64_t b)
Definition f64_le.c:43
bool f64_lt(float64_t a, float64_t b)
Definition f64_lt.c:43
float64_t f64_mul(float64_t a, float64_t b)
Definition f64_mul.c:44
float64_t f64_sqrt(float64_t a)
Definition f64_sqrt.c:44
float64_t f64_sub(float64_t a, float64_t b)
Definition f64_sub.c:43
float32_t f64_to_f32(float64_t a)
Definition f64_to_f32.c:44
int_fast32_t f64_to_i32(float64_t a, uint_fast8_t roundingMode, bool exact)
Definition f64_to_i32.c:44
int_fast64_t f64_to_i64(float64_t a, uint_fast8_t roundingMode, bool exact)
Definition f64_to_i64.c:44
uint_fast32_t f64_to_ui32(float64_t a, uint_fast8_t roundingMode, bool exact)
Definition f64_to_ui32.c:44
uint_fast64_t f64_to_ui64(float64_t a, uint_fast8_t roundingMode, bool exact)
Definition f64_to_ui64.c:44
float32_t i32_to_f32(int32_t a)
Definition i32_to_f32.c:43
float64_t i32_to_f64(int32_t a)
Definition i32_to_f64.c:43
float32_t i64_to_f32(int64_t a)
Definition i64_to_f32.c:43
float64_t i64_to_f64(int64_t a)
Definition i64_to_f64.c:43
float64_t ui64_to_f64(uint64_t)
Definition ui64_to_f64.c:42
float32_t ui32_to_f32(uint32_t)
Definition ui32_to_f32.c:42
float32_t ui64_to_f32(uint64_t)
Definition ui64_to_f32.c:42
float64_t ui32_to_f64(uint32_t)
Definition ui32_to_f64.c:42
float32_t to_softfloat32(float f)
bool f64_is_nan(const float64_t f)
double from_softfloat64(float64_t d)
bool f64_sign_bit(float64_t f)
bool f32_sign_bit(float32_t f)
float64_t to_softfloat64(double d)
float from_softfloat32(float32_t f)
bool f32_is_nan(const float32_t f)
signed __int64 int64_t
Definition stdint.h:135
unsigned int uint32_t
Definition stdint.h:126
signed int int32_t
Definition stdint.h:123
unsigned __int64 uint64_t
Definition stdint.h:136
#define SYS_VM_ASSERT(expr, exc_type, msg)
Definition exceptions.hpp:8
CK_RV ret
char * s