Browse Source

Reorganize detection of platform byteswap macros and endian to be more robust using autoconf

Luke Dashjr 13 years ago
parent
commit
688190a0e5
2 changed files with 116 additions and 30 deletions
  1. 98 0
      configure.ac
  2. 18 30
      miner.h

+ 98 - 0
configure.ac

@@ -104,6 +104,29 @@ case $target in
 	;;
 esac
 
+
+m4_define([BFG_INCLUDE],
+	if test "x$2" = "x"; then
+		$1=''
+	else
+		$1="[#]include <$2>"
+	fi
+)
+
+m4_define([BFG_PREPROC_IFELSE],
+	BFG_INCLUDE([headerinclude], $2)
+	AC_COMPILE_IFELSE([
+		AC_LANG_PROGRAM([
+			${headerinclude}
+		], [
+			#if !( $1 )
+			#error "$1 false in preprocessor"
+			#endif
+		])
+	],$3,$4)
+)
+
+
 cpumining="no"
 
 AC_ARG_ENABLE([cpumining],
@@ -409,6 +432,81 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([static int __attribute__((warn_unused_result)
 			  AC_DEFINE([HAVE_WARN_UNUSED_RESULT], [1],
                                     [Define if __attribute__((warn_unused_result))]))
 
+
+# byteswap functions
+BSWAP=''
+for sym in __builtin_bswap __bswap_ bswap_ __swap swap OSSwapInt; do
+	AC_MSG_CHECKING([for ${sym}* functions])
+	for headerfile in '' byteswap.h endian.h sys/endian.h libkern/OSByteOrder.h; do
+		BFG_INCLUDE([headerinclude], [${headerfile}])
+		AC_LINK_IFELSE([
+			AC_LANG_PROGRAM([
+				${headerinclude}
+			], [
+				(void) ${sym}16(0);
+				(void) ${sym}32(0);
+				(void) ${sym}64(0);
+			])
+		], [
+			BSWAP="${sym}"
+			if test "x${headerfile}" = "x"; then
+				AC_MSG_RESULT([yes])
+			else
+				AC_MSG_RESULT([found in ${headerfile}])
+				AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$headerfile]), 1, [Define to use byteswap macros from <${headerfile}>])
+			fi
+			break 2
+		],[])
+	done
+	AC_MSG_RESULT([no])
+done
+if test "x$BSWAP" = "x"; then
+	true  # Substitutes are provided in miner.h
+elif test "x$BSWAP" = "xbswap_"; then
+	AC_MSG_CHECKING([if bswap_16 is already a macro])
+	BFG_PREPROC_IFELSE([defined(bswap_16)], $headerfile, [
+		AC_MSG_RESULT([yes])
+		BSWAP=""
+	],[
+		AC_MSG_RESULT([no])
+	])
+fi
+if test "x$BSWAP" != "x"; then
+	AC_DEFINE_UNQUOTED([bswap_16], ${BSWAP}16, [Define to 16-bit byteswap macro])
+	AC_DEFINE_UNQUOTED([bswap_32], ${BSWAP}32, [Define to 16-bit byteswap macro])
+	AC_DEFINE_UNQUOTED([bswap_64], ${BSWAP}64, [Define to 16-bit byteswap macro])
+fi
+
+# endian definition macros
+AC_MSG_CHECKING([for platform endian])
+found_endian=no
+for headerfile in '' endian.h sys/endian.h sys/param.h; do
+	for pfx in '' '__'; do
+		BFG_PREPROC_IFELSE([defined(${pfx}BYTE_ORDER) && defined(${pfx}BIG_ENDIAN) && defined(${pfx}LITTLE_ENDIAN) && (${pfx}BYTE_ORDER == ${pfx}BIG_ENDIAN || ${pfx}BYTE_ORDER == ${pfx}LITTLE_ENDIAN)], ${headerfile}, [
+			if test "x$headerfile" != "x"; then
+				headerfile=" (${headerfile})"
+			fi
+			BFG_PREPROC_IFELSE([${pfx}BYTE_ORDER == ${pfx}BIG_ENDIAN], ${headerfile}, [
+				AC_MSG_RESULT([big endian$headerfile])
+				AC_DEFINE(WORDS_BIGENDIAN, 1, [Define if your platform is big endian])
+			], [
+				AC_MSG_RESULT([little endian$headerfile])
+			])
+			found_endian=yes
+			break 2
+		],[true])
+	done
+done
+if test "x$found_endian" = "xno"; then
+	if $have_win32 || $have_cygwin; then
+		AC_MSG_RESULT([assuming little endian (Windows)])
+	else
+		# This is reported to have problems, so only use it if our own checks fail
+		AC_C_BIGENDIAN
+	fi
+fi
+
+
 if test "x$prefix" = xNONE; then
 	prefix=/usr/local
 fi

+ 18 - 30
miner.h

@@ -110,21 +110,19 @@ static inline int fsync (int fd)
   #include "libztex.h"
 #endif
 
-#if !defined(WIN32) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
-#define bswap_16 __builtin_bswap16
-#define bswap_32 __builtin_bswap32
-#define bswap_64 __builtin_bswap64
-#else
-#if HAVE_BYTESWAP_H
+#ifdef HAVE_BYTESWAP_H
 #include <byteswap.h>
-#elif defined(USE_SYS_ENDIAN_H)
+#endif
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+#ifdef HAVE_SYS_ENDIAN_H
 #include <sys/endian.h>
-#elif defined(__APPLE__)
+#endif
+#ifdef HAVE_LIBKERN_OSBYTEORDER_H
 #include <libkern/OSByteOrder.h>
-#define bswap_16 OSSwapInt16
-#define bswap_32 OSSwapInt32
-#define bswap_64 OSSwapInt64
-#else
+#endif
+#ifndef bswap_16
 #define	bswap_16(value)  \
  	((((value) & 0xff) << 8) | ((value) >> 8))
 
@@ -137,24 +135,16 @@ static inline int fsync (int fd)
  	    << 32) | \
  	(uint64_t)bswap_32((uint32_t)((value) >> 32)))
 #endif
-#endif /* !defined(__GLXBYTEORDER_H__) */
 
-#ifdef WIN32
-  #ifndef __LITTLE_ENDIAN
-    #define __LITTLE_ENDIAN 1234
-    #define __BIG_ENDIAN    4321
-  #endif
-  #ifndef __BYTE_ORDER
-    #define __BYTE_ORDER __LITTLE_ENDIAN
-  #endif
-#else
-  #include <endian.h>
+#if defined(WORDS_BIGENDIAN) && !defined(__BIG_ENDIAN__)
+/* uthash.h depends on __BIG_ENDIAN__ on BE platforms */
+#define __BIG_ENDIAN__ 1
 #endif
 
-/* This assumes htobe32 is a macro in endian.h, and if it doesn't exist, then
- * the others also won't exist */
+/* This assumes htobe32 is a macro and that if it doesn't exist, then the
+ * also won't exist */
 #ifndef htobe32
-# if __BYTE_ORDER == __LITTLE_ENDIAN
+# ifndef WORDS_BIGENDIAN
 #  define le32toh(x) (x)
 #  define le64toh(x) (x)
 #  define htole16(x) (x)
@@ -164,7 +154,7 @@ static inline int fsync (int fd)
 #  define be64toh(x) bswap_64(x)
 #  define htobe32(x) bswap_32(x)
 #  define htobe64(x) bswap_64(x)
-# elif __BYTE_ORDER == __BIG_ENDIAN
+# else
 #  define le32toh(x) bswap_32(x)
 #  define le64toh(x) bswap_64(x)
 #  define htole16(x) bswap_16(x)
@@ -174,8 +164,6 @@ static inline int fsync (int fd)
 #  define be64toh(x) (x)
 #  define htobe32(x) (x)
 #  define htobe64(x) (x)
-#else
-#error UNKNOWN BYTE ORDER
 #endif
 #endif
 
@@ -607,7 +595,7 @@ static inline void swap32yes(void*out, const void*in, size_t sz) {
 		(((uint32_t*)out)[swapcounter]) = swab32(((uint32_t*)in)[swapcounter]);
 }
 
-#ifdef __BIG_ENDIAN__
+#ifdef WORDS_BIGENDIAN
 #  define swap32tobe(out, in, sz)  (void)0
 #  define swap32tole(out, in, sz)  swap32yes(out, in, sz)
 #else