Skip to content

Commit

Permalink
Revise the autoconf tests for double middle endianness.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mikesperber committed Jul 20, 2012
1 parent cab9edd commit eba4d24
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 55 deletions.
65 changes: 54 additions & 11 deletions aclocal.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
]])],
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
65 changes: 54 additions & 11 deletions erts/aclocal.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
]])],
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
65 changes: 54 additions & 11 deletions lib/erl_interface/aclocal.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
]])],
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
65 changes: 54 additions & 11 deletions lib/odbc/aclocal.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
]])],
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit eba4d24

Please sign in to comment.