The current generic C implementation, which is always used when the
public header is included from other programs (either directly or
through intreadwrite.h) compiles to a mess like this (gcc-4.6 on AMD64):
        movq    %rdi, %rdx
        shrq    $32, %rdx
        movl    %edx, %eax
        sall    $8, %edx
        shrl    $8, %eax
        andl    $-16711936, %edx
        andl    $16711935, %eax
        orl     %edx, %eax
        movl    %edi, %edx
        sall    $8, %edi
        shrl    $8, %edx
        andl    $-16711936, %edi
        roll    $16, %eax
        andl    $16711935, %edx
        orl     %edi, %edx
        roll    $16, %edx
        salq    $32, %rdx
        orq     %rdx, %rax
        ret
The builtin function produces just a bswap.

If the built-in functions behave particularly badly on some less common
architecture then additional checks to exclude those could be
beneficial; but in any case this should be enabled at least for
amd64/x86.
>From 389ae3dd6d726731874d316c3b88f3adb4ea8d38 Mon Sep 17 00:00:00 2001
From: Uoti Urpala <[email protected]>
Date: Sun, 24 Apr 2011 08:16:43 +0300
Subject: [PATCH] bswap.h: prefer GCC builtins to generic C

Use the built-in bswap functions provided by GCC if no architecture-
specific bswap implementation has been defined. This is particularly
beneficial when the header is used in other programs, as bswap.h
itself is an installed header but the architecture-specific
optimizations are not; thus even amd64/x86 fell back to the generic C
implementation, which creates horribly inefficient code when compiled
with GCC. This also affects intreadwrite.h which uses bswap.h.
---
 libavutil/bswap.h |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/libavutil/bswap.h b/libavutil/bswap.h
index c93825f..12ed043 100644
--- a/libavutil/bswap.h
+++ b/libavutil/bswap.h
@@ -65,16 +65,22 @@ static av_always_inline av_const uint16_t av_bswap16(uint16_t x)
 #ifndef av_bswap32
 static av_always_inline av_const uint32_t av_bswap32(uint32_t x)
 {
+#if AV_GCC_VERSION_AT_LEAST(4, 3)
+    return __builtin_bswap32(x);
+#else
     x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF);
     x= (x>>16) | (x<<16);
     return x;
+#endif
 }
 #endif
 
 #ifndef av_bswap64
 static inline uint64_t av_const av_bswap64(uint64_t x)
 {
-#if 0
+#if AV_GCC_VERSION_AT_LEAST(4, 3)
+    return __builtin_bswap64(x);
+#elif 0
     x= ((x<< 8)&0xFF00FF00FF00FF00ULL) | ((x>> 8)&0x00FF00FF00FF00FFULL);
     x= ((x<<16)&0xFFFF0000FFFF0000ULL) | ((x>>16)&0x0000FFFF0000FFFFULL);
     return (x>>32) | (x<<32);
-- 
1.7.5.rc1.5.g24078

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to