aboutsummaryrefslogtreecommitdiffstats
path: root/lib/erl_interface/aclocal.m4
diff options
context:
space:
mode:
authorMike Sperber <[email protected]>2012-07-20 11:27:47 +0200
committerMike Sperber <[email protected]>2012-07-20 11:27:47 +0200
commiteba4d247740189c3b8045edeaf8224651e77a3e0 (patch)
tree3ecc4b2fbf77064be8a493aeef36ea0ff3ecfe9f /lib/erl_interface/aclocal.m4
parentcab9edd0a6f1fad2c3ec9661b39627756ad9d2ba (diff)
downloadotp-eba4d247740189c3b8045edeaf8224651e77a3e0.tar.gz
otp-eba4d247740189c3b8045edeaf8224651e77a3e0.tar.bz2
otp-eba4d247740189c3b8045edeaf8224651e77a3e0.zip
Revise the autoconf tests for double middle endianness.
The previous iteration didn't work for big-endian systems. Now use code very close to what Erts does internally. Also, only warn when the double endianness is unknown - i.e. when we're cross-compiling.
Diffstat (limited to 'lib/erl_interface/aclocal.m4')
-rw-r--r--lib/erl_interface/aclocal.m465
1 files changed, 54 insertions, 11 deletions
diff --git a/lib/erl_interface/aclocal.m4 b/lib/erl_interface/aclocal.m4
index 9c5bcd6dc6..a76594d86f 100644
--- a/lib/erl_interface/aclocal.m4
+++ b/lib/erl_interface/aclocal.m4
@@ -621,25 +621,68 @@ 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
+[AC_LANG_SOURCE([[#include <stdlib.h>
+
+int
main(void)
{
int i = 0;
int zero = 0;
+ int bigendian;
+ int zero_index = 0;
+
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+
+ /* we'll use the one with 32-bit words */
+ union
+ {
+ double d;
+ unsigned int c[2];
+ } vint;
+
+ union
+ {
+ double d;
+ unsigned long c[2];
+ } vlong;
+
union
{
double d;
- char c[sizeof (double)];
- } v;
- v.d = 1.0;
-
-
- while (i < sizeof(double) / 2)
+ unsigned short c[2];
+ } vshort;
+
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ u.l = 1;
+ bigendian = (u.c[sizeof (long int) - 1] == 1);
+
+ zero_index = bigendian ? 1 : 0;
+
+ vint.d = 1.0;
+ vlong.d = 1.0;
+ vshort.d = 1.0;
+
+ if (sizeof(unsigned int) == 4)
+ {
+ if (vint.c[zero_index] != 0)
+ zero = 1;
+ }
+ else if (sizeof(unsigned long) == 4)
+ {
+ if (vlong.c[zero_index] != 0)
+ zero = 1;
+ }
+ else if (sizeof(unsigned short) == 4)
{
- if (v.c[i] != 0)
+ if (vshort.c[zero_index] != 0)
zero = 1;
- ++i;
}
+
exit (zero);
}
]])],
@@ -656,7 +699,7 @@ case $ac_cv_c_double_middle_endian in
$2 ;;
*)
m4_default([$3],
- [AC_MSG_ERROR([unknown double endianness
+ [AC_MSG_WARN([unknown double endianness
presetting ac_cv_c_double_middle_endian=no (or yes) will help])]) ;;
esac
])# AC_C_DOUBLE_MIDDLE_ENDIAN
@@ -1394,7 +1437,7 @@ fi
case X$erl_xcomp_double_middle_endian in
X) ;;
- Xyes|Xno) ac_cv_c_double_middle_endian=$erl_xcomp_double_middle_endian;;
+ Xyes|Xno|Xunknown) 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