4757e84ae31ffba3b13590de0e6aa7f93a213f63
2 Copyright (c) 2020 Peter Hsu. All Rights Reserved. See LICENCE file for details.
6 #define F32_SIGN (0x1 << 31)
7 #define F64_SIGN (0x1L << 63)
9 #define sgnj32(a, b, n, x) ((FR(a).ui & ~F32_SIGN) | ((((x) ? FR(a).ui : (n) ? F32_SIGN : 0) ^ FR(b).ui) & F32_SIGN))
10 #define sgnj64(a, b, n, x) ((FR(a).ul & ~F64_SIGN) | ((((x) ? FR(a).ul : (n) ? F64_SIGN : 0) ^ FR(b).ul) & F64_SIGN))
17 #include "internals.h"
18 #include "softfloat_types.h"
19 #include "softfloat.h"
21 #define RM cpu->state.fcsr.rmode
22 #define SRM(m) softfloat_roundingMode=((m)==7?RM:(m))
23 #define SET_FPX /* set_fp_exceptions() */
25 static inline float32_t
defaultNaNF32UI() { union ui32_f32 u
; u
.ui
= 0x7FC00000; return u
.f
; }
26 static inline float64_t
defaultNaNF64UI() { union ui64_f64 u
; u
.ui
=0x7FF8000000000000L
; return u
.f
; }
27 #define f32_less(a, b) (f32_lt_quiet(a, b) || (f32_eq(a, b) && (a.v & F32_SIGN)))
28 #define f32_more(a, b) (f32_lt_quiet(b, a) || (f32_eq(b, a) && (b.v & F32_SIGN)))
29 static inline float32_t
f32_min(float32_t a
, float32_t b
) { return (isNaNF32UI(a
.v
) && isNaNF32UI(b
.v
)) ? defaultNaNF32UI() : (f32_more(a
, b
) || isNaNF32UI(b
.v
)) ? a
: b
; }
30 static inline float32_t
f32_max(float32_t a
, float32_t b
) { return (isNaNF32UI(a
.v
) && isNaNF32UI(b
.v
)) ? defaultNaNF32UI() : (f32_less(a
, b
) || isNaNF32UI(b
.v
)) ? a
: b
; }
31 #define f64_less(a, b) (f64_lt_quiet(a, b) || (f64_eq(a, b) && (a.v & F64_SIGN)))
32 #define f64_more(a, b) (f64_lt_quiet(b, a) || (f64_eq(b, a) && (b.v & F64_SIGN)))
33 static inline float64_t
f64_min(float64_t a
, float64_t b
) { return (isNaNF64UI(a
.v
) && isNaNF64UI(b
.v
)) ? defaultNaNF64UI() : (f64_more(a
, b
) || isNaNF64UI(b
.v
)) ? a
: b
; }
34 static inline float64_t
f64_max(float64_t a
, float64_t b
) { return (isNaNF64UI(a
.v
) && isNaNF64UI(b
.v
)) ? defaultNaNF64UI() : (f64_less(a
, b
) || isNaNF64UI(b
.v
)) ? a
: b
; }
42 #define SRM(rm) if (rm!=7) { tmp_rm=fegetround(); fesetround(riscv_to_c_rm(rm)); }
43 #define RRM(rm) if(rm!=7) fesetround(tmp_rm);
44 #define SET_FPX ;/* set_fp_exceptions() */
46 static inline long riscv_to_c_rm(long rm
)
49 case /* RNE */ 0x0: return FE_TONEAREST
;
50 case /* RTZ */ 0x1: return FE_TOWARDZERO
;
51 case /* RDN */ 0x2: return FE_DOWNWARD
;
52 case /* RUP */ 0x3: return FE_UPWARD
;
62 // Following copied from Spike
64 static inline unsigned long mulhu(unsigned long a
, unsigned long b
)
67 unsigned int y1
, y2
, y3
;
68 unsigned long a0
= (unsigned int)a
, a1
= a
>> 32;
69 unsigned long b0
= (unsigned int)b
, b1
= b
>> 32;
71 t
= a1
*b0
+ ((a0
*b0
) >> 32);
78 t
= a1
*b1
+ y2
+ (t
>> 32);
82 return ((unsigned long)y3
<< 32) | y2
;
85 static inline long mulh(long a
, long b
)
87 int negate
= (a
< 0) != (b
< 0);
88 unsigned long res
= mulhu(a
< 0 ? -a
: a
, b
< 0 ? -b
: b
);
89 return negate
? ~res
+ (a
* b
== 0) : res
;
92 static inline long mulhsu(long a
, unsigned long b
)
95 unsigned long res
= mulhu(a
< 0 ? -a
: a
, b
);
96 return negate
? ~res
+ (a
* b
== 0) : res
;