From 51f782f416a8aa05153a9f2dcef34d8bcb79f1ed Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 20 Nov 2006 12:13:09 +0000 Subject: [PATCH] Cope with big endian float word order on little endian machines --- aclocal.m4 | 27 +++++++++++++++++++++++++++ configure.ac | 1 + rts/StgPrimFloat.c | 17 ++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/aclocal.m4 b/aclocal.m4 index 619d414..9d1e1ca 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -4,6 +4,33 @@ # ensure we don't clash with any pre-supplied autoconf ones. +# FPTOOLS_FLOAT_WORD_ORDER_BIGENDIAN +# ---------------------------------- +# Little endian Arm on Linux with some ABIs has big endian word order +# in doubles. Define FLOAT_WORDS_BIGENDIAN if this is the case. +AC_DEFUN([FPTOOLS_FLOAT_WORD_ORDER_BIGENDIAN], + [AC_CACHE_CHECK([whether float word order is big endian], [fptools_cv_float_word_order_bigendian], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include ], + [#if defined(__FLOAT_WORD_ORDER) && __FLOAT_WORD_ORDER == BIG_ENDIAN + return 0; + #else + not float word order big endian + #endif] + )], + [fptools_cv_float_word_order_bigendian=yes], + [fptools_cv_float_word_order_bigendian=no]) + ]) + case $fptools_cv_float_word_order_bigendian in + yes) + AC_DEFINE([FLOAT_WORDS_BIGENDIAN], 1, + [Define to 1 if your processor stores words of floats with + the most significant byte first]) ;; + esac +]) + + # FP_EVAL_STDERR(COMMAND) # ----------------------- # Eval COMMAND, save its stderr (without lines resulting from shell tracing) diff --git a/configure.ac b/configure.ac index 37bf318..1d28aa8 100644 --- a/configure.ac +++ b/configure.ac @@ -1136,6 +1136,7 @@ AC_C_CONST dnl ** are we big endian? AC_C_BIGENDIAN +FPTOOLS_FLOAT_WORD_ORDER_BIGENDIAN dnl ** check for leading underscores in symbol names FP_LEADING_UNDERSCORE diff --git a/rts/StgPrimFloat.c b/rts/StgPrimFloat.c index 5bd6aeb..9521094 100644 --- a/rts/StgPrimFloat.c +++ b/rts/StgPrimFloat.c @@ -48,7 +48,7 @@ #define FMSBIT 0x80000000 #endif -#ifdef WORDS_BIGENDIAN +#if defined(WORDS_BIGENDIAN) || defined(FLOAT_WORDS_BIGENDIAN) #define L 1 #define H 0 #else @@ -307,11 +307,18 @@ union stg_ieee754_dbl unsigned int mantissa0:20; unsigned int mantissa1:32; #else +#if FLOAT_WORDS_BIGENDIAN + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; + unsigned int mantissa1:32; +#else unsigned int mantissa1:32; unsigned int mantissa0:20; unsigned int exponent:11; unsigned int negative:1; #endif +#endif } ieee; /* This format makes it easier to see if a NaN is a signalling NaN. */ struct { @@ -323,12 +330,20 @@ union stg_ieee754_dbl unsigned int mantissa0:19; unsigned int mantissa1:32; #else +#if FLOAT_WORDS_BIGENDIAN + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; + unsigned int mantissa1:32; +#else unsigned int mantissa1:32; unsigned int mantissa0:19; unsigned int quiet_nan:1; unsigned int exponent:11; unsigned int negative:1; #endif +#endif } ieee_nan; }; -- 1.7.10.4