[glib] Use __builtin_bswap* for GUINT*_SWAP_LE_BE if building with GCC



commit 57878d6042366070e80a109bf113ac03abb86cfd
Author: Sebastian DrÃge <slomo circular-chaos org>
Date:   Sat Mar 17 23:28:48 2012 -0400

    Use __builtin_bswap* for GUINT*_SWAP_LE_BE if building with GCC
    
    https://bugzilla.gnome.org/show_bug.cgi?id=531901

 glib/gtypes.h      |   38 ++++++++++++++++++++++++++++++--------
 glib/tests/utils.c |   24 ++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 8 deletions(-)
---
diff --git a/glib/gtypes.h b/glib/gtypes.h
index ca9e50d..7e4c8ea 100644
--- a/glib/gtypes.h
+++ b/glib/gtypes.h
@@ -181,6 +181,12 @@ typedef const gchar *   (*GTranslateFunc)       (const gchar   *str,
 /* Arch specific stuff for speed
  */
 #if defined (__GNUC__) && (__GNUC__ >= 2) && defined (__OPTIMIZE__)
+
+#  if __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3
+#    define GUINT32_SWAP_LE_BE(val) ((guint32) __builtin_bswap32 ((gint32) val))
+#    define GUINT64_SWAP_LE_BE(val) ((guint64) __builtin_bswap64 ((gint64) val))
+#  endif
+
 #  if defined (__i386__)
 #    define GUINT16_SWAP_LE_BE_IA32(val) \
        (G_GNUC_EXTENSION					\
@@ -236,8 +242,12 @@ typedef const gchar *   (*GTranslateFunc)       (const gchar   *str,
 	   __r.__ll; }))
      /* Possibly just use the constant version and let gcc figure it out? */
 #    define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_IA32 (val))
-#    define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_IA32 (val))
-#    define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_IA32 (val))
+#    ifndef GUINT32_SWAP_LE_BE
+#      define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_IA32 (val))
+#    endif
+#    ifndef GUINT64_SWAP_LE_BE
+#      define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_IA32 (val))
+#    endif
 #  elif defined (__ia64__)
 #    define GUINT16_SWAP_LE_BE_IA64(val) \
        (G_GNUC_EXTENSION					\
@@ -272,8 +282,12 @@ typedef const gchar *   (*GTranslateFunc)       (const gchar   *str,
 				   : "r" (__x));		\
 	   __v; }))
 #    define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_IA64 (val))
-#    define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_IA64 (val))
-#    define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_IA64 (val))
+#    ifndef GUINT32_SWAP_LE_BE
+#      define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_IA64 (val))
+#    endif
+#    ifndef GUINT64_SWAP_LE_BE
+#      define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_IA64 (val))
+#    endif
 #  elif defined (__x86_64__)
 #    define GUINT32_SWAP_LE_BE_X86_64(val) \
        (G_GNUC_EXTENSION					\
@@ -297,12 +311,20 @@ typedef const gchar *   (*GTranslateFunc)       (const gchar   *str,
 	   __v; }))
      /* gcc seems to figure out optimal code for this on its own */
 #    define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val))
-#    define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_X86_64 (val))
-#    define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_X86_64 (val))
+#    ifndef GUINT32_SWAP_LE_BE
+#      define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_X86_64 (val))
+#    endif
+#    ifndef GUINT64_SWAP_LE_BE
+#      define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_X86_64 (val))
+#    endif
 #  else /* generic gcc */
 #    define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val))
-#    define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val))
-#    define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT (val))
+#    ifndef GUINT32_SWAP_LE_BE
+#      define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val))
+#    endif
+#    ifndef GUINT64_SWAP_LE_BE
+#      define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT (val))
+#    endif
 #  endif
 #else /* generic */
 #  define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val))
diff --git a/glib/tests/utils.c b/glib/tests/utils.c
index b2c19b3..721a813 100644
--- a/glib/tests/utils.c
+++ b/glib/tests/utils.c
@@ -208,6 +208,29 @@ test_bits (void)
 }
 
 static void
+test_swap (void)
+{
+  guint16 a16, b16;
+  guint32 a32, b32;
+  guint64 a64, b64;
+
+  a16 = 0xaabb;
+  b16 = 0xbbaa;
+
+  g_assert_cmpint (GUINT16_SWAP_LE_BE (a16), ==, b16);
+
+  a32 = 0xaaaabbbb;
+  b32 = 0xbbbbaaaa;
+
+  g_assert_cmpint (GUINT32_SWAP_LE_BE (a32), ==, b32);
+
+  a64 = 0xaaaaaaaabbbbbbbb;
+  b64 = 0xbbbbbbbbaaaaaaaa;
+
+  g_assert_cmpint (GUINT64_SWAP_LE_BE (a64), ==, b64);
+}
+
+static void
 test_find_program (void)
 {
   gchar *res;
@@ -319,6 +342,7 @@ main (int   argc,
   g_test_add_func ("/utils/appname", test_appname);
   g_test_add_func ("/utils/tmpdir", test_tmpdir);
   g_test_add_func ("/utils/bits", test_bits);
+  g_test_add_func ("/utils/swap", test_swap);
   g_test_add_func ("/utils/find-program", test_find_program);
   g_test_add_func ("/utils/debug", test_debug);
   g_test_add_func ("/utils/codeset", test_codeset);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]