gh-145633: Remove support for ancient ARM platforms with mixed-endian doubles (#145634)

* Drop DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 macro.
* Use DOUBLE_IS_BIG/LITTLE_ENDIAN_IEEE754 to detect endianness of
  float/doubles.
* Drop "unknown_format" code path in PyFloat_Pack/Unpack*().

Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
Sergey B Kirpichev
2026-03-11 14:39:24 +03:00
committed by GitHub
parent bdf6de8c3f
commit dae85c4d93
14 changed files with 134 additions and 590 deletions
-8
View File
@@ -224,11 +224,6 @@ endian processor, or ``0`` on little endian processor.
Return value: ``0`` if all is OK, ``-1`` if error (and an exception is set,
most likely :exc:`OverflowError`).
There are two problems on non-IEEE platforms:
* What this does is undefined if *x* is a NaN or infinity.
* ``-0.0`` and ``+0.0`` produce the same bytes string.
.. c:function:: int PyFloat_Pack2(double x, char *p, int le)
Pack a C double as the IEEE 754 binary16 half-precision format.
@@ -256,9 +251,6 @@ Return value: The unpacked double. On error, this is ``-1.0`` and
:c:func:`PyErr_Occurred` is true (and an exception is set, most likely
:exc:`OverflowError`).
Note that on a non-IEEE platform this will refuse to unpack a bytes string that
represents a NaN or infinity.
.. c:function:: double PyFloat_Unpack2(const char *p, int le)
Unpack the IEEE 754 binary16 half-precision format as a C double.
+9 -1
View File
@@ -12,7 +12,6 @@ extern "C" {
/* runtime lifecycle */
extern void _PyFloat_InitState(PyInterpreterState *);
extern PyStatus _PyFloat_InitTypes(PyInterpreterState *);
extern void _PyFloat_FiniType(PyInterpreterState *);
@@ -42,6 +41,15 @@ extern double _Py_parse_inf_or_nan(const char *p, char **endptr);
extern int _Py_convert_int_to_double(PyObject **v, double *dbl);
/* Should match endianness of the platform in most (all?) cases. */
#ifdef DOUBLE_IS_BIG_ENDIAN_IEEE754
# define _PY_FLOAT_BIG_ENDIAN 1
# define _PY_FLOAT_LITTLE_ENDIAN 0
#else
# define _PY_FLOAT_BIG_ENDIAN 0
# define _PY_FLOAT_LITTLE_ENDIAN 1
#endif
#ifdef __cplusplus
}
+1 -2
View File
@@ -182,8 +182,7 @@ extern void _Py_set_387controlword(unsigned short);
// (extended precision), and we don't know how to change
// the rounding precision.
#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \
!defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \
!defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
!defined(DOUBLE_IS_BIG_ENDIAN_IEEE754)
# define _PY_SHORT_FLOAT_REPR 0
#endif
+2 -6
View File
@@ -13,7 +13,7 @@ extern "C" {
#include "pycore_debug_offsets.h" // _Py_DebugOffsets_INIT()
#include "pycore_dtoa.h" // _dtoa_state_INIT()
#include "pycore_faulthandler.h" // _faulthandler_runtime_state_INIT
#include "pycore_floatobject.h" // _py_float_format_unknown
#include "pycore_floatobject.h" // _py_float_format_*
#include "pycore_function.h"
#include "pycore_hamt.h" // _PyHamt_BitmapNode_Type
#include "pycore_import.h" // IMPORTS_INIT
@@ -84,10 +84,6 @@ extern PyTypeObject _PyExc_MemoryError;
.stoptheworld = { \
.is_global = 1, \
}, \
.float_state = { \
.float_format = _py_float_format_unknown, \
.double_format = _py_float_format_unknown, \
}, \
.types = { \
.next_version_tag = _Py_TYPE_VERSION_NEXT, \
}, \
@@ -233,4 +229,4 @@ extern PyTypeObject _PyExc_MemoryError;
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_RUNTIME_INIT_H */
#endif /* !Py_INTERNAL_RUNTIME_INIT_H */
-12
View File
@@ -35,17 +35,6 @@ struct _pymem_allocators {
PyObjectArenaAllocator obj_arena;
};
enum _py_float_format_type {
_py_float_format_unknown,
_py_float_format_ieee_big_endian,
_py_float_format_ieee_little_endian,
};
struct _Py_float_runtime_state {
enum _py_float_format_type float_format;
enum _py_float_format_type double_format;
};
struct pyhash_runtime_state {
struct {
#ifndef MS_WINDOWS
@@ -270,7 +259,6 @@ struct pyruntimestate {
} audit_hooks;
struct _py_object_runtime_state object_state;
struct _Py_float_runtime_state float_state;
struct _Py_unicode_runtime_state unicode_state;
struct _types_runtime_state types;
struct _Py_time_runtime_state time;
-1
View File
@@ -18,7 +18,6 @@
#undef SIZEOF_UINTPTR_T
#undef SIZEOF_PTHREAD_T
#undef WORDS_BIGENDIAN
#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754
#undef DOUBLE_IS_BIG_ENDIAN_IEEE754
#undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754
#undef HAVE_GCC_ASM_FOR_X87
@@ -0,0 +1,3 @@
Remove support for ancient ARM platforms (ARMv4L and ARMv5L OABI boards),
using mixed-endian representation
for doubles. Patch by Sergey B Kirpichev.
+2 -2
View File
@@ -290,7 +290,7 @@ PyDoc_STRVAR(float___getformat____doc__,
"\n"
"It exists mainly to be used in Python\'s test suite.\n"
"\n"
"This function returns whichever of \'unknown\', \'IEEE, big-endian\' or \'IEEE,\n"
"This function returns whichever of \'IEEE, big-endian\' or \'IEEE,\n"
"little-endian\' best describes the format of floating-point numbers used by the\n"
"C type named by typestr.");
@@ -353,4 +353,4 @@ float___format__(PyObject *self, PyObject *arg)
exit:
return return_value;
}
/*[clinic end generated code: output=927035897ea3573f input=a9049054013a1b77]*/
/*[clinic end generated code: output=f0b2af257213c8b0 input=a9049054013a1b77]*/
+113 -523
View File
@@ -1666,15 +1666,6 @@ float___getnewargs___impl(PyObject *self)
return Py_BuildValue("(d)", ((PyFloatObject *)self)->ob_fval);
}
/* this is for the benefit of the pack/unpack routines below */
typedef enum _py_float_format_type float_format_type;
#define unknown_format _py_float_format_unknown
#define ieee_big_endian_format _py_float_format_ieee_big_endian
#define ieee_little_endian_format _py_float_format_ieee_little_endian
#define float_format (_PyRuntime.float_state.float_format)
#define double_format (_PyRuntime.float_state.double_format)
/*[clinic input]
@permit_long_docstring_body
@@ -1689,45 +1680,25 @@ You probably don't want to use this function.
It exists mainly to be used in Python's test suite.
This function returns whichever of 'unknown', 'IEEE, big-endian' or 'IEEE,
This function returns whichever of 'IEEE, big-endian' or 'IEEE,
little-endian' best describes the format of floating-point numbers used by the
C type named by typestr.
[clinic start generated code]*/
static PyObject *
float___getformat___impl(PyTypeObject *type, const char *typestr)
/*[clinic end generated code: output=2bfb987228cc9628 input=d2735823bfe8e81e]*/
/*[clinic end generated code: output=2bfb987228cc9628 input=0ae1ba35d192f704]*/
{
float_format_type r;
if (strcmp(typestr, "double") == 0) {
r = double_format;
}
else if (strcmp(typestr, "float") == 0) {
r = float_format;
}
else {
if (strcmp(typestr, "double") != 0 && strcmp(typestr, "float") != 0) {
PyErr_SetString(PyExc_ValueError,
"__getformat__() argument 1 must be "
"'double' or 'float'");
return NULL;
}
switch (r) {
case unknown_format:
return PyUnicode_FromString("unknown");
case ieee_little_endian_format:
return PyUnicode_FromString("IEEE, little-endian");
case ieee_big_endian_format:
return PyUnicode_FromString("IEEE, big-endian");
default:
PyErr_SetString(PyExc_RuntimeError,
"insane float_format or double_format");
return NULL;
}
return PyUnicode_FromString(_PY_FLOAT_LITTLE_ENDIAN ?
"IEEE, little-endian" : "IEEE, big-endian");
}
static PyObject *
float_getreal(PyObject *v, void *Py_UNUSED(closure))
{
@@ -1878,67 +1849,6 @@ PyTypeObject PyFloat_Type = {
.tp_version_tag = _Py_TYPE_VERSION_FLOAT,
};
static void
_init_global_state(void)
{
float_format_type detected_double_format, detected_float_format;
/* We attempt to determine if this machine is using IEEE
floating-point formats by peering at the bits of some
carefully chosen values. If it looks like we are on an
IEEE platform, the float packing/unpacking routines can
just copy bits, if not they resort to arithmetic & shifts
and masks. The shifts & masks approach works on all finite
values, but what happens to infinities, NaNs and signed
zeroes on packing is an accident, and attempting to unpack
a NaN or an infinity will raise an exception.
Note that if we're on some whacked-out platform which uses
IEEE formats but isn't strictly little-endian or big-
endian, we will fall back to the portable shifts & masks
method. */
#if SIZEOF_DOUBLE == 8
{
double x = 9006104071832581.0;
if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
detected_double_format = ieee_big_endian_format;
else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
detected_double_format = ieee_little_endian_format;
else
detected_double_format = unknown_format;
}
#else
detected_double_format = unknown_format;
#endif
#if SIZEOF_FLOAT == 4
{
float y = 16711938.0;
if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
detected_float_format = ieee_big_endian_format;
else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
detected_float_format = ieee_little_endian_format;
else
detected_float_format = unknown_format;
}
#else
detected_float_format = unknown_format;
#endif
double_format = detected_double_format;
float_format = detected_float_format;
}
void
_PyFloat_InitState(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return;
}
_init_global_state();
}
PyStatus
_PyFloat_InitTypes(PyInterpreterState *interp)
{
@@ -2092,278 +2002,87 @@ int
PyFloat_Pack4(double x, char *data, int le)
{
unsigned char *p = (unsigned char *)data;
if (float_format == unknown_format) {
unsigned char sign;
int e;
double f;
unsigned int fbits;
int incr = 1;
if (le) {
p += 3;
incr = -1;
}
if (x < 0) {
sign = 1;
x = -x;
}
else
sign = 0;
f = frexp(x, &e);
/* Normalize f to be in the range [1.0, 2.0) */
if (0.5 <= f && f < 1.0) {
f *= 2.0;
e--;
}
else if (f == 0.0)
e = 0;
else {
PyErr_SetString(PyExc_SystemError,
"frexp() result out of range");
return -1;
}
if (e >= 128)
goto Overflow;
else if (e < -126) {
/* Gradual underflow */
f = ldexp(f, 126 + e);
e = 0;
}
else if (!(e == 0 && f == 0.0)) {
e += 127;
f -= 1.0; /* Get rid of leading 1 */
}
f *= 8388608.0; /* 2**23 */
fbits = (unsigned int)(f + 0.5); /* Round */
assert(fbits <= 8388608);
if (fbits >> 23) {
/* The carry propagated out of a string of 23 1 bits. */
fbits = 0;
++e;
if (e >= 255)
goto Overflow;
}
/* First byte */
*p = (sign << 7) | (e >> 1);
p += incr;
/* Second byte */
*p = (char) (((e & 1) << 7) | (fbits >> 16));
p += incr;
/* Third byte */
*p = (fbits >> 8) & 0xFF;
p += incr;
/* Fourth byte */
*p = fbits & 0xFF;
/* Done */
return 0;
float y = (float)x;
int i, incr = 1;
if (isinf(y) && !isinf(x)) {
PyErr_SetString(PyExc_OverflowError,
"float too large to pack with f format");
return -1;
}
else {
float y = (float)x;
int i, incr = 1;
if (isinf(y) && !isinf(x))
goto Overflow;
/* correct y if x was a sNaN, transformed to qNaN by conversion */
if (isnan(x)) {
uint64_t v;
/* correct y if x was a sNaN, transformed to qNaN by conversion */
if (isnan(x)) {
uint64_t v;
memcpy(&v, &x, 8);
memcpy(&v, &x, 8);
#ifndef __riscv
if ((v & (1ULL << 51)) == 0) {
uint32_t u32;
memcpy(&u32, &y, 4);
/* if have payload, make sNaN */
if (u32 & 0x3fffff) {
u32 &= ~(1 << 22);
}
memcpy(&y, &u32, 4);
}
#else
if ((v & (1ULL << 51)) == 0) {
uint32_t u32;
memcpy(&u32, &y, 4);
/* Workaround RISC-V: "If a NaN value is converted to a
* different floating-point type, the result is the
* canonical NaN of the new type". The canonical NaN here
* is a positive qNaN with zero payload. */
if (v & (1ULL << 63)) {
u32 |= (1 << 31); /* set sign */
}
/* add payload */
u32 -= (u32 & 0x3fffff);
u32 += (uint32_t)((v & 0x7ffffffffffffULL) >> 29);
/* if have payload, make sNaN */
if ((v & (1ULL << 51)) == 0 && (u32 & 0x3fffff)) {
if (u32 & 0x3fffff) {
u32 &= ~(1 << 22);
}
memcpy(&y, &u32, 4);
}
#else
uint32_t u32;
memcpy(&u32, &y, 4);
/* Workaround RISC-V: "If a NaN value is converted to a
* different floating-point type, the result is the
* canonical NaN of the new type". The canonical NaN here
* is a positive qNaN with zero payload. */
if (v & (1ULL << 63)) {
u32 |= (1 << 31); /* set sign */
}
/* add payload */
u32 -= (u32 & 0x3fffff);
u32 += (uint32_t)((v & 0x7ffffffffffffULL) >> 29);
/* if have payload, make sNaN */
if ((v & (1ULL << 51)) == 0 && (u32 & 0x3fffff)) {
u32 &= ~(1 << 22);
}
memcpy(&y, &u32, 4);
#endif
}
unsigned char s[sizeof(float)];
memcpy(s, &y, sizeof(float));
if ((float_format == ieee_little_endian_format && !le)
|| (float_format == ieee_big_endian_format && le)) {
p += 3;
incr = -1;
}
for (i = 0; i < 4; i++) {
*p = s[i];
p += incr;
}
return 0;
}
Overflow:
PyErr_SetString(PyExc_OverflowError,
"float too large to pack with f format");
return -1;
unsigned char s[sizeof(float)];
memcpy(s, &y, sizeof(float));
if ((_PY_FLOAT_LITTLE_ENDIAN && !le) || (_PY_FLOAT_BIG_ENDIAN && le)) {
p += 3;
incr = -1;
}
for (i = 0; i < 4; i++) {
*p = s[i];
p += incr;
}
return 0;
}
int
PyFloat_Pack8(double x, char *data, int le)
{
unsigned char *p = (unsigned char *)data;
if (double_format == unknown_format) {
unsigned char sign;
int e;
double f;
unsigned int fhi, flo;
int incr = 1;
unsigned char as_bytes[8];
memcpy(as_bytes, &x, 8);
const unsigned char *s = as_bytes;
int i, incr = 1;
if (le) {
p += 7;
incr = -1;
}
if (x < 0) {
sign = 1;
x = -x;
}
else
sign = 0;
f = frexp(x, &e);
/* Normalize f to be in the range [1.0, 2.0) */
if (0.5 <= f && f < 1.0) {
f *= 2.0;
e--;
}
else if (f == 0.0)
e = 0;
else {
PyErr_SetString(PyExc_SystemError,
"frexp() result out of range");
return -1;
}
if (e >= 1024)
goto Overflow;
else if (e < -1022) {
/* Gradual underflow */
f = ldexp(f, 1022 + e);
e = 0;
}
else if (!(e == 0 && f == 0.0)) {
e += 1023;
f -= 1.0; /* Get rid of leading 1 */
}
/* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
f *= 268435456.0; /* 2**28 */
fhi = (unsigned int)f; /* Truncate */
assert(fhi < 268435456);
f -= (double)fhi;
f *= 16777216.0; /* 2**24 */
flo = (unsigned int)(f + 0.5); /* Round */
assert(flo <= 16777216);
if (flo >> 24) {
/* The carry propagated out of a string of 24 1 bits. */
flo = 0;
++fhi;
if (fhi >> 28) {
/* And it also propagated out of the next 28 bits. */
fhi = 0;
++e;
if (e >= 2047)
goto Overflow;
}
}
/* First byte */
*p = (sign << 7) | (e >> 4);
p += incr;
/* Second byte */
*p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24));
p += incr;
/* Third byte */
*p = (fhi >> 16) & 0xFF;
p += incr;
/* Fourth byte */
*p = (fhi >> 8) & 0xFF;
p += incr;
/* Fifth byte */
*p = fhi & 0xFF;
p += incr;
/* Sixth byte */
*p = (flo >> 16) & 0xFF;
p += incr;
/* Seventh byte */
*p = (flo >> 8) & 0xFF;
p += incr;
/* Eighth byte */
*p = flo & 0xFF;
/* p += incr; */
/* Done */
return 0;
Overflow:
PyErr_SetString(PyExc_OverflowError,
"float too large to pack with d format");
return -1;
if ((_PY_FLOAT_LITTLE_ENDIAN && !le) || (_PY_FLOAT_BIG_ENDIAN && le)) {
p += 7;
incr = -1;
}
else {
unsigned char as_bytes[8];
memcpy(as_bytes, &x, 8);
const unsigned char *s = as_bytes;
int i, incr = 1;
if ((double_format == ieee_little_endian_format && !le)
|| (double_format == ieee_big_endian_format && le)) {
p += 7;
incr = -1;
}
for (i = 0; i < 8; i++) {
*p = *s++;
p += incr;
}
return 0;
for (i = 0; i < 8; i++) {
*p = *s++;
p += incr;
}
return 0;
}
double
@@ -2426,208 +2145,79 @@ double
PyFloat_Unpack4(const char *data, int le)
{
unsigned char *p = (unsigned char *)data;
if (float_format == unknown_format) {
unsigned char sign;
int e;
unsigned int f;
double x;
int incr = 1;
float x;
if (le) {
p += 3;
incr = -1;
if ((_PY_FLOAT_LITTLE_ENDIAN && !le) || (_PY_FLOAT_BIG_ENDIAN && le)) {
char buf[4];
char *d = &buf[3];
int i;
for (i = 0; i < 4; i++) {
*d-- = *p++;
}
/* First byte */
sign = (*p >> 7) & 1;
e = (*p & 0x7F) << 1;
p += incr;
/* Second byte */
e |= (*p >> 7) & 1;
f = (*p & 0x7F) << 16;
p += incr;
if (e == 255) {
PyErr_SetString(
PyExc_ValueError,
"can't unpack IEEE 754 special value "
"on non-IEEE platform");
return -1;
}
/* Third byte */
f |= *p << 8;
p += incr;
/* Fourth byte */
f |= *p;
x = (double)f / 8388608.0;
/* XXX This sadly ignores Inf/NaN issues */
if (e == 0)
e = -126;
else {
x += 1.0;
e -= 127;
}
x = ldexp(x, e);
if (sign)
x = -x;
return x;
memcpy(&x, buf, 4);
}
else {
float x;
memcpy(&x, p, 4);
}
if ((float_format == ieee_little_endian_format && !le)
|| (float_format == ieee_big_endian_format && le)) {
char buf[4];
char *d = &buf[3];
int i;
for (i = 0; i < 4; i++) {
*d-- = *p++;
}
memcpy(&x, buf, 4);
}
else {
memcpy(&x, p, 4);
}
/* return sNaN double if x was sNaN float */
if (isnan(x)) {
uint32_t v;
memcpy(&v, &x, 4);
/* return sNaN double if x was sNaN float */
if (isnan(x)) {
uint32_t v;
memcpy(&v, &x, 4);
#ifndef __riscv
if ((v & (1 << 22)) == 0) {
double y = x; /* will make qNaN double */
uint64_t u64;
memcpy(&u64, &y, 8);
u64 &= ~(1ULL << 51); /* make sNaN */
memcpy(&y, &u64, 8);
return y;
}
#else
double y = x;
if ((v & (1 << 22)) == 0) {
double y = x; /* will make qNaN double */
uint64_t u64;
memcpy(&u64, &y, 8);
if ((v & (1 << 22)) == 0) {
u64 &= ~(1ULL << 51);
}
/* Workaround RISC-V, see PyFloat_Pack4() */
if (v & (1 << 31)) {
u64 |= (1ULL << 63); /* set sign */
}
/* add payload */
u64 -= (u64 & 0x7ffffffffffffULL);
u64 += ((v & 0x3fffffULL) << 29);
u64 &= ~(1ULL << 51); /* make sNaN */
memcpy(&y, &u64, 8);
return y;
#endif
}
#else
double y = x;
uint64_t u64;
return x;
memcpy(&u64, &y, 8);
if ((v & (1 << 22)) == 0) {
u64 &= ~(1ULL << 51);
}
/* Workaround RISC-V, see PyFloat_Pack4() */
if (v & (1 << 31)) {
u64 |= (1ULL << 63); /* set sign */
}
/* add payload */
u64 -= (u64 & 0x7ffffffffffffULL);
u64 += ((v & 0x3fffffULL) << 29);
memcpy(&y, &u64, 8);
return y;
#endif
}
return x;
}
double
PyFloat_Unpack8(const char *data, int le)
{
unsigned char *p = (unsigned char *)data;
if (double_format == unknown_format) {
unsigned char sign;
int e;
unsigned int fhi, flo;
double x;
int incr = 1;
double x;
if (le) {
p += 7;
incr = -1;
if ((_PY_FLOAT_LITTLE_ENDIAN && !le) || (_PY_FLOAT_BIG_ENDIAN && le)) {
char buf[8];
char *d = &buf[7];
int i;
for (i = 0; i < 8; i++) {
*d-- = *p++;
}
/* First byte */
sign = (*p >> 7) & 1;
e = (*p & 0x7F) << 4;
p += incr;
/* Second byte */
e |= (*p >> 4) & 0xF;
fhi = (*p & 0xF) << 24;
p += incr;
if (e == 2047) {
PyErr_SetString(
PyExc_ValueError,
"can't unpack IEEE 754 special value "
"on non-IEEE platform");
return -1.0;
}
/* Third byte */
fhi |= *p << 16;
p += incr;
/* Fourth byte */
fhi |= *p << 8;
p += incr;
/* Fifth byte */
fhi |= *p;
p += incr;
/* Sixth byte */
flo = *p << 16;
p += incr;
/* Seventh byte */
flo |= *p << 8;
p += incr;
/* Eighth byte */
flo |= *p;
x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
x /= 268435456.0; /* 2**28 */
if (e == 0)
e = -1022;
else {
x += 1.0;
e -= 1023;
}
x = ldexp(x, e);
if (sign)
x = -x;
return x;
memcpy(&x, buf, 8);
}
else {
double x;
if ((double_format == ieee_little_endian_format && !le)
|| (double_format == ieee_big_endian_format && le)) {
char buf[8];
char *d = &buf[7];
int i;
for (i = 0; i < 8; i++) {
*d-- = *p++;
}
memcpy(&x, buf, 8);
}
else {
memcpy(&x, p, 8);
}
return x;
memcpy(&x, p, 8);
}
return x;
}
+2 -4
View File
@@ -139,8 +139,7 @@
#ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754
# define IEEE_8087
#endif
#if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \
defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
#if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754)
# define IEEE_MC68k
#endif
#if defined(IEEE_8087) + defined(IEEE_MC68k) != 1
@@ -149,8 +148,7 @@
/* The code below assumes that the endianness of integers matches the
endianness of the two 32-bit words of a double. Check this. */
#if defined(WORDS_BIGENDIAN) && (defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) || \
defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754))
#if defined(WORDS_BIGENDIAN) && defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754)
#error "doubles and ints have incompatible endianness"
#endif
-2
View File
@@ -706,8 +706,6 @@ pycore_init_global_objects(PyInterpreterState *interp)
{
PyStatus status;
_PyFloat_InitState(interp);
status = _PyUnicode_InitGlobalObjects(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
Generated Vendored
-13
View File
@@ -26212,20 +26212,7 @@ printf "%s\n" "#define DOUBLE_IS_BIG_ENDIAN_IEEE754 1" >>confdefs.h
printf "%s\n" "#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1" >>confdefs.h
;;
*)
case $host_cpu in #(
*arm*) :
# Some ARM platforms use a mixed-endian representation for
# doubles. While Python doesn't currently have full support
# for these platforms (see e.g., issue 1762561), we can at
# least make sure that float <-> string conversions work.
# FLOAT_WORDS_BIGENDIAN doesn't actually detect this case,
# but if it's not big or little, then it must be this?
printf "%s\n" "#define DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 1" >>confdefs.h
;; #(
*) :
as_fn_error $? "Unknown float word ordering. You need to manually preset ax_cv_c_float_words_bigendian=no (or yes) according to your system." "$LINENO" 5 ;;
esac ;;
esac
+2 -12
View File
@@ -6178,21 +6178,11 @@ AX_C_FLOAT_WORDS_BIGENDIAN(
[AC_DEFINE([DOUBLE_IS_LITTLE_ENDIAN_IEEE754], [1],
[Define if C doubles are 64-bit IEEE 754 binary format,
stored with the least significant byte first])],
[AS_CASE([$host_cpu],
[*arm*], [# Some ARM platforms use a mixed-endian representation for
# doubles. While Python doesn't currently have full support
# for these platforms (see e.g., issue 1762561), we can at
# least make sure that float <-> string conversions work.
# FLOAT_WORDS_BIGENDIAN doesn't actually detect this case,
# but if it's not big or little, then it must be this?
AC_DEFINE([DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754], [1],
[Define if C doubles are 64-bit IEEE 754 binary format,
stored in ARM mixed-endian order (byte order 45670123)])],
[AC_MSG_ERROR([m4_normalize([
[AC_MSG_ERROR([m4_normalize([
Unknown float word ordering. You need to manually
preset ax_cv_c_float_words_bigendian=no (or yes)
according to your system.
])])])])
])])])
# The short float repr introduced in Python 3.1 requires the
# correctly-rounded string <-> double conversion functions from
-4
View File
@@ -32,10 +32,6 @@
/* The Android API level. */
#undef ANDROID_API_LEVEL
/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM
mixed-endian order (byte order 45670123) */
#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754
/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most
significant byte first */
#undef DOUBLE_IS_BIG_ENDIAN_IEEE754