@@ -2194,15 +2194,22 @@ PyFloat_Pack4(double x, char *data, int le)
21942194 /* correct y if x was a sNaN, transformed to qNaN by conversion */
21952195 if (isnan (x )) {
21962196 uint64_t v ;
2197- uint32_t u32 ;
21982197
21992198 memcpy (& v , & x , 8 );
2200- memcpy (& u32 , & y , 4 );
2201-
2199+ #ifndef __riscv
22022200 if ((v & (1ULL << 51 )) == 0 ) {
2201+ uint32_t u32 ;
2202+ memcpy (& u32 , & y , 4 );
22032203 u32 &= ~(1 << 22 ); /* make sNaN */
2204+ memcpy (& y , & u32 , 4 );
22042205 }
2206+ #else
2207+ uint32_t u32 ;
22052208
2209+ memcpy (& u32 , & y , 4 );
2210+ if ((v & (1ULL << 51 )) == 0 ) {
2211+ u32 &= ~(1 << 22 );
2212+ }
22062213 /* Workaround RISC-V: "If a NaN value is converted to a
22072214 * different floating-point type, the result is the
22082215 * canonical NaN of the new type". The canonical NaN here
@@ -2215,6 +2222,7 @@ PyFloat_Pack4(double x, char *data, int le)
22152222 u32 += (uint32_t )((v & 0x7ffffffffffffULL ) >> 29 );
22162223
22172224 memcpy (& y , & u32 , 4 );
2225+ #endif
22182226 }
22192227
22202228 unsigned char s [sizeof (float )];
@@ -2503,17 +2511,26 @@ PyFloat_Unpack4(const char *data, int le)
25032511
25042512 /* return sNaN double if x was sNaN float */
25052513 if (isnan (x )) {
2506- double y = x ; /* will make qNaN double */
25072514 uint32_t v ;
2508- uint64_t u64 ;
2509-
25102515 memcpy (& v , & x , 4 );
2511- memcpy (& u64 , & y , 8 );
25122516
2517+ #ifndef __riscv
25132518 if ((v & (1 << 22 )) == 0 ) {
2519+ double y = x ; /* will make qNaN double */
2520+ uint64_t u64 ;
2521+ memcpy (& u64 , & y , 8 );
25142522 u64 &= ~(1ULL << 51 ); /* make sNaN */
2523+ memcpy (& y , & u64 , 8 );
2524+ return y ;
25152525 }
2526+ #else
2527+ double y = x ;
2528+ uint64_t u64 ;
25162529
2530+ memcpy (& u64 , & y , 8 );
2531+ if ((v & (1 << 22 )) == 0 ) {
2532+ u64 &= ~(1ULL << 51 );
2533+ }
25172534 /* Workaround RISC-V, see PyFloat_Pack4() */
25182535 if (v & (1 << 31 )) {
25192536 u64 |= (1ULL << 63 ); /* set sign */
@@ -2524,6 +2541,7 @@ PyFloat_Unpack4(const char *data, int le)
25242541
25252542 memcpy (& y , & u64 , 8 );
25262543 return y ;
2544+ #endif
25272545 }
25282546
25292547 return x ;
0 commit comments