@@ -89,26 +89,37 @@ bool CvtFpToInt( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst )
89
89
return true ;
90
90
}
91
91
92
+ enum RevFClass : uint32_t {
93
+ InfNeg = 1u << 0 ,
94
+ NormalNeg = 1u << 1 ,
95
+ SubNormalNeg = 1u << 2 ,
96
+ ZeroNeg = 1u << 3 ,
97
+ ZeroPos = 1u << 4 ,
98
+ SubNormalPos = 1u << 5 ,
99
+ NormalPos = 1u << 6 ,
100
+ InfPos = 1u << 7 ,
101
+ SignalingNaN = 1u << 8 ,
102
+ QuietNaN = 1u << 9 ,
103
+ };
104
+
92
105
// / fclass: Return FP classification like the RISC-V fclass instruction
93
106
template <typename T>
94
- unsigned fclass ( T val ) {
95
- bool quietNaN;
107
+ uint32_t fclass ( T val ) {
96
108
switch ( std::fpclassify ( val ) ) {
97
- case FP_INFINITE: return std::signbit ( val ) ? 1u : 1u << 7 ;
109
+ case FP_INFINITE: return std::signbit ( val ) ? InfNeg : InfPos;
110
+ case FP_NORMAL: return std::signbit ( val ) ? NormalNeg : NormalPos;
111
+ case FP_SUBNORMAL: return std::signbit ( val ) ? SubNormalNeg : SubNormalPos;
112
+ case FP_ZERO: return std::signbit ( val ) ? ZeroNeg : ZeroPos;
98
113
case FP_NAN:
99
114
if constexpr ( std::is_same_v<T, float > ) {
100
115
uint32_t i32 ;
101
116
memcpy ( &i32 , &val, sizeof ( i32 ) );
102
- quietNaN = ( i32 & uint32_t { 1 } << 22 ) != 0 ;
117
+ return ( i32 & uint32_t { 1 } << 22 ) != 0 ? QuietNaN : SignalingNaN ;
103
118
} else {
104
119
uint64_t i64 ;
105
120
memcpy ( &i64 , &val, sizeof ( i64 ) );
106
- quietNaN = ( i64 & uint64_t { 1 } << 51 ) != 0 ;
121
+ return ( i64 & uint64_t { 1 } << 51 ) != 0 ? QuietNaN : SignalingNaN ;
107
122
}
108
- return quietNaN ? 1u << 9 : 1u << 8 ;
109
- case FP_NORMAL: return std::signbit ( val ) ? 1u << 1 : 1u << 6 ;
110
- case FP_SUBNORMAL: return std::signbit ( val ) ? 1u << 2 : 1u << 5 ;
111
- case FP_ZERO: return std::signbit ( val ) ? 1u << 3 : 1u << 4 ;
112
123
default : return 0u ;
113
124
}
114
125
}
@@ -223,7 +234,7 @@ template<typename = void>
223
234
struct FMin {
224
235
template <typename T>
225
236
auto operator ()( T x, T y ) const {
226
- if ( fclass ( x ) == 1u << 8 || fclass ( y ) == 1u << 8 )
237
+ if ( fclass ( x ) == SignalingNaN || fclass ( y ) == SignalingNaN )
227
238
feraiseexcept ( FE_INVALID );
228
239
return std::fmin ( x, y );
229
240
}
@@ -234,7 +245,7 @@ template<typename = void>
234
245
struct FMax {
235
246
template <typename T>
236
247
auto operator ()( T x, T y ) const {
237
- if ( fclass ( x ) == 1u << 8 || fclass ( y ) == 1u << 8 )
248
+ if ( fclass ( x ) == SignalingNaN || fclass ( y ) == SignalingNaN )
238
249
feraiseexcept ( FE_INVALID );
239
250
return std::fmax ( x, y );
240
251
}
0 commit comments