55
66#include "Python.h"
77#include "pycore_abstract.h" // _PyNumber_Index()
8+ #include "pycore_bitutils.h" // _Py_bswap16()
89#include "pycore_dtoa.h" // _Py_dg_dtoa()
910#include "pycore_floatobject.h" // _PyFloat_FormatAdvancedWriter()
1011#include "pycore_freelist.h" // _Py_FREELIST_FREE(), _Py_FREELIST_POP()
@@ -1894,7 +1895,6 @@ _PyFloat_DebugMallocStats(FILE *out)
18941895int
18951896PyFloat_Pack2 (double x , char * data , int le )
18961897{
1897- unsigned char * p = (unsigned char * )data ;
18981898#if _Py_HAVE_FLOAT16
18991899 /* Conversion can change NaNs type or alter payload. Here we
19001900 just fallback to the generic code, instead of providing
@@ -1906,25 +1906,22 @@ PyFloat_Pack2(double x, char *data, int le)
19061906 goto Overflow ;
19071907 }
19081908
1909- unsigned char s [sizeof (_Float16 )];
1910-
1911- memcpy (s , & y , sizeof (_Float16 ));
19121909 if ((_PY_FLOAT_LITTLE_ENDIAN && !le ) || (_PY_FLOAT_BIG_ENDIAN && le )) {
1913- p [1 ] = s [0 ];
1914- p [0 ] = s [1 ];
1910+ uint16_t word ;
1911+ memcpy (& word , & y , 2 );
1912+ word = _Py_bswap16 (word );
1913+ memcpy (data , & word , 2 );
19151914 }
19161915 else {
1917- p [0 ] = s [0 ];
1918- p [1 ] = s [1 ];
1916+ memcpy (data , & y , sizeof (_Float16 ));
19191917 }
19201918 return 0 ;
19211919 }
19221920#endif
19231921 unsigned char sign ;
19241922 int e ;
19251923 double f ;
1926- unsigned short bits ;
1927- int incr = 1 ;
1924+ uint16_t bits ;
19281925
19291926 if (x == 0.0 ) {
19301927 sign = (copysign (1.0 , x ) == -1.0 );
@@ -2004,18 +2001,10 @@ PyFloat_Pack2(double x, char *data, int le)
20042001 bits |= (e << 10 ) | (sign << 15 );
20052002
20062003 /* Write out result. */
2007- if (le ) {
2008- p += 1 ;
2009- incr = -1 ;
2004+ if ((_PY_FLOAT_LITTLE_ENDIAN && !le ) || (_PY_FLOAT_BIG_ENDIAN && le )) {
2005+ bits = _Py_bswap16 (bits );
20102006 }
2011-
2012- /* First byte */
2013- * p = (unsigned char )((bits >> 8 ) & 0xFF );
2014- p += incr ;
2015-
2016- /* Second byte */
2017- * p = (unsigned char )(bits & 0xFF );
2018-
2007+ memcpy (data , & bits , 2 );
20192008 return 0 ;
20202009
20212010 Overflow :
@@ -2027,10 +2016,7 @@ PyFloat_Pack2(double x, char *data, int le)
20272016int
20282017PyFloat_Pack4 (double x , char * data , int le )
20292018{
2030- unsigned char * p = (unsigned char * )data ;
20312019 float y = (float )x ;
2032- int i , incr = 1 ;
2033-
20342020 if (isinf (y ) && !isinf (x )) {
20352021 PyErr_SetString (PyExc_OverflowError ,
20362022 "float too large to pack with f format" );
@@ -2054,8 +2040,8 @@ PyFloat_Pack4(double x, char *data, int le)
20542040 }
20552041#else
20562042 uint32_t u32 ;
2057-
20582043 memcpy (& u32 , & y , 4 );
2044+
20592045 /* Workaround RISC-V: "If a NaN value is converted to a
20602046 * different floating-point type, the result is the
20612047 * canonical NaN of the new type". The canonical NaN here
@@ -2075,38 +2061,29 @@ PyFloat_Pack4(double x, char *data, int le)
20752061#endif
20762062 }
20772063
2078- unsigned char s [sizeof (float )];
2079- memcpy (s , & y , sizeof (float ));
2080-
20812064 if ((_PY_FLOAT_LITTLE_ENDIAN && !le ) || (_PY_FLOAT_BIG_ENDIAN && le )) {
2082- p += 3 ;
2083- incr = -1 ;
2065+ uint32_t word ;
2066+ memcpy (& word , & y , 4 );
2067+ word = _Py_bswap32 (word );
2068+ memcpy (data , & word , 4 );
20842069 }
2085-
2086- for (i = 0 ; i < 4 ; i ++ ) {
2087- * p = s [i ];
2088- p += incr ;
2070+ else {
2071+ memcpy (data , & y , sizeof (float ));
20892072 }
20902073 return 0 ;
20912074}
20922075
20932076int
20942077PyFloat_Pack8 (double x , char * data , int le )
20952078{
2096- unsigned char * p = (unsigned char * )data ;
2097- unsigned char as_bytes [8 ];
2098- memcpy (as_bytes , & x , 8 );
2099- const unsigned char * s = as_bytes ;
2100- int i , incr = 1 ;
2101-
21022079 if ((_PY_FLOAT_LITTLE_ENDIAN && !le ) || (_PY_FLOAT_BIG_ENDIAN && le )) {
2103- p += 7 ;
2104- incr = -1 ;
2080+ uint64_t word ;
2081+ memcpy (& word , & x , 8 );
2082+ word = _Py_bswap64 (word );
2083+ memcpy (data , & word , 8 );
21052084 }
2106-
2107- for (i = 0 ; i < 8 ; i ++ ) {
2108- * p = * s ++ ;
2109- p += incr ;
2085+ else {
2086+ memcpy (data , & x , 8 );
21102087 }
21112088 return 0 ;
21122089}
0 commit comments