aboutsummaryrefslogtreecommitdiffstats
path: root/lib/erl_interface
diff options
context:
space:
mode:
authorMike Sperber <[email protected]>2012-03-22 18:00:31 +0100
committerMike Sperber <[email protected]>2012-03-23 09:15:19 +0100
commit933e701dac1936c6f15c765b5687fbc623464ec7 (patch)
tree95bef4a51a14f512c23348e39cbfb336bc22475b /lib/erl_interface
parent3087769515ea9bfc75f7d7b8897bc897c7f13931 (diff)
downloadotp-933e701dac1936c6f15c765b5687fbc623464ec7.tar.gz
otp-933e701dac1936c6f15c765b5687fbc623464ec7.tar.bz2
otp-933e701dac1936c6f15c765b5687fbc623464ec7.zip
Unbreak floating point on middle-endian machines.
On some ARMs (and maybe other platforms), doubles are stored with the the two 32-bit words reversed with respect to more common architectures. The symptom is this: > io_lib:write(1.0). "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005299808824" Detect that and account for it when decoding floats.
Diffstat (limited to 'lib/erl_interface')
-rw-r--r--lib/erl_interface/aclocal.m463
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/erl_interface/aclocal.m4 b/lib/erl_interface/aclocal.m4
index 339a15a2bb..9c5bcd6dc6 100644
--- a/lib/erl_interface/aclocal.m4
+++ b/lib/erl_interface/aclocal.m4
@@ -59,6 +59,7 @@ AC_ARG_VAR(erl_xcomp_isysroot, [Absolute cross system root include path (only us
dnl Cross compilation variables
AC_ARG_VAR(erl_xcomp_bigendian, [big endian system: yes|no (only used when cross compiling)])
+AC_ARG_VAR(erl_xcomp_double_middle_endian, [double-middle-endian system: yes|no (only used when cross compiling)])
AC_ARG_VAR(erl_xcomp_linux_clock_gettime_correction, [clock_gettime() can be used for time correction: yes|no (only used when cross compiling)])
AC_ARG_VAR(erl_xcomp_linux_nptl, [have Native POSIX Thread Library: yes|no (only used when cross compiling)])
AC_ARG_VAR(erl_xcomp_linux_usable_sigusrx, [SIGUSR1 and SIGUSR2 can be used: yes|no (only used when cross compiling)])
@@ -606,6 +607,60 @@ ifelse([$5], , , [$5
fi
])
+dnl ----------------------------------------------------------------------
+dnl
+dnl AC_DOUBLE_MIDDLE_ENDIAN
+dnl
+dnl Checks whether doubles are represented in "middle-endian" format.
+dnl Sets ac_cv_double_middle_endian={no,yes,unknown} accordingly,
+dnl as well as DOUBLE_MIDDLE_ENDIAN.
+dnl
+dnl
+
+AC_DEFUN([AC_C_DOUBLE_MIDDLE_ENDIAN],
+[AC_CACHE_CHECK(whether double word ordering is middle-endian, ac_cv_c_double_middle_endian,
+[# It does not; compile a test program.
+AC_RUN_IFELSE(
+[AC_LANG_SOURCE([[int
+main(void)
+{
+ int i = 0;
+ int zero = 0;
+ union
+ {
+ double d;
+ char c[sizeof (double)];
+ } v;
+ v.d = 1.0;
+
+
+ while (i < sizeof(double) / 2)
+ {
+ if (v.c[i] != 0)
+ zero = 1;
+ ++i;
+ }
+ exit (zero);
+}
+]])],
+ [ac_cv_c_double_middle_endian=no],
+ [ac_cv_c_double_middle_endian=yes],
+ [ac_cv_c_double_middle=unknown])])
+case $ac_cv_c_double_middle_endian in
+ yes)
+ m4_default([$1],
+ [AC_DEFINE([DOUBLE_MIDDLE_ENDIAN], 1,
+ [Define to 1 if your processor stores the words in a double in
+ middle-endian format (like some ARMs).])]) ;;
+ no)
+ $2 ;;
+ *)
+ m4_default([$3],
+ [AC_MSG_ERROR([unknown double endianness
+presetting ac_cv_c_double_middle_endian=no (or yes) will help])]) ;;
+esac
+])# AC_C_DOUBLE_MIDDLE_ENDIAN
+
dnl ----------------------------------------------------------------------
dnl
@@ -1337,6 +1392,14 @@ if test "$ac_cv_c_bigendian" = "yes"; then
AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian])
fi
+case X$erl_xcomp_double_middle_endian in
+ X) ;;
+ Xyes|Xno) ac_cv_c_double_middle_endian=$erl_xcomp_double_middle_endian;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_double_middle_endian value: $erl_xcomp_double_middle_endian]);;
+esac
+
+AC_C_DOUBLE_MIDDLE_ENDIAN
+
AC_ARG_ENABLE(native-ethr-impls,
AS_HELP_STRING([--disable-native-ethr-impls],
[disable native ethread implementations]),