*: deinline SWAP_xE64 on 32-bit CPUs. Wins !90 bytes both on 32 and 64 bits

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
diff --git a/include/libbb.h b/include/libbb.h
index b16157d..c161ed7 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -37,8 +37,6 @@
 #include <termios.h>
 #include <time.h>
 #include <unistd.h>
-/* Try to pull in PATH_MAX */
-#include <limits.h>
 #include <sys/param.h>
 #ifdef HAVE_MNTENT_H
 # include <mntent.h>
@@ -254,6 +252,11 @@
 #define errno (*bb_errno)
 #endif
 
+#if !(ULONG_MAX > 0xffffffff)
+/* Only 32-bit CPUs need this, 64-bit ones use inlined version */
+uint64_t bb_bswap_64(uint64_t x) FAST_FUNC;
+#endif
+
 unsigned long long monotonic_ns(void) FAST_FUNC;
 unsigned long long monotonic_us(void) FAST_FUNC;
 unsigned long long monotonic_ms(void) FAST_FUNC;
diff --git a/include/platform.h b/include/platform.h
index c255a17..b5c6685 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -150,6 +150,7 @@
 
 /* ---- Endian Detection ------------------------------------ */
 
+#include <limits.h>
 #if defined(__digital__) && defined(__unix__)
 # include <sex.h>
 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
@@ -189,6 +190,10 @@
 # error "Can't determine endianness"
 #endif
 
+#if ULONG_MAX > 0xffffffff
+# define bb_bswap_64(x) bswap_64(x)
+#endif
+
 /* SWAP_LEnn means "convert CPU<->little_endian by swapping bytes" */
 #if BB_BIG_ENDIAN
 # define SWAP_BE16(x) (x)
@@ -196,13 +201,13 @@
 # define SWAP_BE64(x) (x)
 # define SWAP_LE16(x) bswap_16(x)
 # define SWAP_LE32(x) bswap_32(x)
-# define SWAP_LE64(x) bswap_64(x)
+# define SWAP_LE64(x) bb_bswap_64(x)
 # define IF_BIG_ENDIAN(...) __VA_ARGS__
 # define IF_LITTLE_ENDIAN(...)
 #else
 # define SWAP_BE16(x) bswap_16(x)
 # define SWAP_BE32(x) bswap_32(x)
-# define SWAP_BE64(x) bswap_64(x)
+# define SWAP_BE64(x) bb_bswap_64(x)
 # define SWAP_LE16(x) (x)
 # define SWAP_LE32(x) (x)
 # define SWAP_LE64(x) (x)
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src
index 0fd7302..0955d73 100644
--- a/libbb/Kbuild.src
+++ b/libbb/Kbuild.src
@@ -14,6 +14,7 @@
 lib-y += ask_confirmation.o
 lib-y += bb_askpass.o
 lib-y += bb_basename.o
+lib-y += bb_bswap_64.o
 lib-y += bb_do_delay.o
 lib-y += bb_pwd.o
 lib-y += bb_qsort.o
diff --git a/libbb/bb_bswap_64.c b/libbb/bb_bswap_64.c
new file mode 100644
index 0000000..ce9d53b
--- /dev/null
+++ b/libbb/bb_bswap_64.c
@@ -0,0 +1,16 @@
+/*
+ * Utility routines.
+ *
+ * Copyright (C) 2010 Denys Vlasenko
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+
+#include "libbb.h"
+
+#if !(ULONG_MAX > 0xffffffff)
+uint64_t FAST_FUNC bb_bswap_64(uint64_t x)
+{
+	return bswap_64(x);
+}
+#endif
diff --git a/libbb/hash_sha.c b/libbb/hash_sha.c
index e7199d3..72d5092 100644
--- a/libbb/hash_sha.c
+++ b/libbb/hash_sha.c
@@ -51,16 +51,6 @@
 {
 	return (x >> n) | (x << (64 - n));
 }
-#if BB_LITTLE_ENDIAN
-/* ALWAYS_INLINE below sometimes hurts code size, using plain inline: */
-static inline uint64_t hton64(uint64_t v)
-{
-	return SWAP_BE64(v);
-}
-#else
-#define hton64(v) (v)
-#endif
-#define ntoh64(v) hton64(v)
 
 
 /* Some arch headers have conflicting defines */
@@ -274,7 +264,7 @@
 
 	/* Compute the message schedule according to FIPS 180-2:6.3.2 step 2.  */
 	for (t = 0; t < 16; ++t)
-		W[t] = ntoh64(words[t]);
+		W[t] = SWAP_BE64(words[t]);
 	for (/*t = 16*/; t < 80; ++t)
 		W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16];
 
@@ -475,7 +465,7 @@
 		if (remaining >= 8) {
 			/* Store the 64-bit counter of bits in the buffer in BE format */
 			uint64_t t = ctx->total64 << 3;
-			t = hton64(t);
+			t = SWAP_BE64(t);
 			/* wbuffer is suitably aligned for this */
 			*(uint64_t *) (&ctx->wbuffer[64 - 8]) = t;
 		}
@@ -509,10 +499,10 @@
 			/* Store the 128-bit counter of bits in the buffer in BE format */
 			uint64_t t;
 			t = ctx->total64[0] << 3;
-			t = hton64(t);
+			t = SWAP_BE64(t);
 			*(uint64_t *) (&ctx->wbuffer[128 - 8]) = t;
 			t = (ctx->total64[1] << 3) | (ctx->total64[0] >> 61);
-			t = hton64(t);
+			t = SWAP_BE64(t);
 			*(uint64_t *) (&ctx->wbuffer[128 - 16]) = t;
 		}
 		sha512_process_block128(ctx);
@@ -524,7 +514,7 @@
 	if (BB_LITTLE_ENDIAN) {
 		unsigned i;
 		for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
-			ctx->hash[i] = hton64(ctx->hash[i]);
+			ctx->hash[i] = SWAP_BE64(ctx->hash[i]);
 	}
 	memcpy(resbuf, ctx->hash, sizeof(ctx->hash));
 }
diff --git a/networking/udhcp/dumpleases.c b/networking/udhcp/dumpleases.c
index 341815a..46610fc 100644
--- a/networking/udhcp/dumpleases.c
+++ b/networking/udhcp/dumpleases.c
@@ -6,17 +6,6 @@
 #include "dhcpd.h"
 #include "unicode.h"
 
-#if BB_LITTLE_ENDIAN
-static inline uint64_t hton64(uint64_t v)
-{
-        return SWAP_BE64(v);
-}
-#else
-#define hton64(v) (v)
-#endif
-#define ntoh64(v) hton64(v)
-
-
 int dumpleases_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int dumpleases_main(int argc UNUSED_PARAM, char **argv)
 {
@@ -54,7 +43,7 @@
 	/*     "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */
 
 	xread(fd, &written_at, sizeof(written_at));
-	written_at = ntoh64(written_at);
+	written_at = SWAP_BE64(written_at);
 	curr = time(NULL);
 	if (curr < written_at)
 		written_at = curr; /* lease file from future! :) */
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index 68b2085..49bcafb 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -11,16 +11,6 @@
 #include "common.h"
 #include "dhcpd.h"
 
-#if BB_LITTLE_ENDIAN
-static inline uint64_t hton64(uint64_t v)
-{
-        return SWAP_BE64(v);
-}
-#else
-#define hton64(v) (v)
-#endif
-#define ntoh64(v) hton64(v)
-
 /* on these functions, make sure your datatype matches */
 static int FAST_FUNC read_str(const char *line, void *arg)
 {
@@ -140,7 +130,7 @@
 
 	curr = written_at = time(NULL);
 
-	written_at = hton64(written_at);
+	written_at = SWAP_BE64(written_at);
 	full_write(fd, &written_at, sizeof(written_at));
 
 	for (i = 0; i < server_config.max_leases; i++) {
@@ -190,7 +180,7 @@
 
 	if (full_read(fd, &written_at, sizeof(written_at)) != sizeof(written_at))
 		goto ret;
-	written_at = ntoh64(written_at);
+	written_at = SWAP_BE64(written_at);
 
 	time_passed = time(NULL) - written_at;
 	/* Strange written_at, or lease file from old version of udhcpd