diff options
author | Lasse Collin <lasse.collin@tukaani.org> | 2008-01-15 13:32:13 +0200 |
---|---|---|
committer | Lasse Collin <lasse.collin@tukaani.org> | 2008-01-15 13:32:13 +0200 |
commit | 10437b5b567f6a025ff16c45a572e417a0a9cc26 (patch) | |
tree | ba8b5193ebc795865aa1bea387081b5ad77e52ef | |
parent | Fixed assembler detection in configure.ac, and added (diff) | |
download | xz-10437b5b567f6a025ff16c45a572e417a0a9cc26.tar.xz |
Added bsr.h.
-rw-r--r-- | src/liblzma/common/Makefile.am | 1 | ||||
-rw-r--r-- | src/liblzma/common/bsr.h | 61 |
2 files changed, 62 insertions, 0 deletions
diff --git a/src/liblzma/common/Makefile.am b/src/liblzma/common/Makefile.am index 4eb9d54e..a2eacfd8 100644 --- a/src/liblzma/common/Makefile.am +++ b/src/liblzma/common/Makefile.am @@ -24,6 +24,7 @@ libcommon_la_CPPFLAGS = \ libcommon_la_SOURCES = \ common.h \ sysdefs.h \ + bsr.h \ allocator.c \ block_private.h \ extra.c \ diff --git a/src/liblzma/common/bsr.h b/src/liblzma/common/bsr.h new file mode 100644 index 00000000..fd5d3b04 --- /dev/null +++ b/src/liblzma/common/bsr.h @@ -0,0 +1,61 @@ +/////////////////////////////////////////////////////////////////////////////// +// +/// \file bsr.h +/// \brief Bit scan reverse +// +// This code has been put into the public domain. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef LZMA_BSR_H +#define LZMA_BSR_H + +// NOTE: Both input and output variables for lzma_bsr must be uint32_t. + +#if defined(__GNUC__) && (defined (HAVE_ASM_X86) || defined(HAVE_ASM_X86_64)) +# define lzma_bsr(dest, n) \ + __asm__("bsrl %1, %0" : "=r" (dest) : "rm" (n)) + +#else +# define lzma_bsr(dest, n) dest = lzma_bsr_helper(n) + +static inline uint32_t +lzma_bsr_helper(uint32_t n) +{ + assert(n != 0); + + uint32_t i = 31; + + if ((n & UINT32_C(0xFFFF0000)) == 0) { + n <<= 16; + i = 15; + } + + if ((n & UINT32_C(0xFF000000)) == 0) { + n <<= 8; + i -= 8; + } + + if ((n & UINT32_C(0xF0000000)) == 0) { + n <<= 4; + i -= 4; + } + + if ((n & UINT32_C(0xC0000000)) == 0) { + n <<= 2; + i -= 2; + } + + if ((n & UINT32_C(0x80000000)) == 0) + --i; + + return i; +} + +#endif + +#endif |