common: don't duplicate find_msb implementation

This commit is contained in:
Christophe Fergeau 2011-04-22 12:55:21 +02:00 committed by Marc-André Lureau
parent 8db40f4ae7
commit 29e175bb06
4 changed files with 95 additions and 67 deletions

View File

@ -6,6 +6,7 @@ NULL =
noinst_LTLIBRARIES = libspice-common.la
libspice_common_la_SOURCES = \
bitops.h \
canvas_utils.c \
canvas_utils.h \
draw.h \

89
common/bitops.h Normal file
View File

@ -0,0 +1,89 @@
/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (C) 2009 Red Hat, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef BITOPS_H
#define BITOPS_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
static inline int spice_bit_find_msb(uint32_t val)
{
uint32_t r;
__asm {
bsr eax, val
jnz found
mov eax, -1
found:
mov r, eax
}
return r + 1;
}
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
static inline int spice_bit_find_msb(unsigned int val)
{
int ret;
asm ("bsrl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:"
: "=r"(ret) : "r"(val));
return ret + 1;
}
#else
static inline int spice_bit_find_msb(unsigned int val)
{
signed char index = 31;
if(val == 0) {
return 0;
}
do {
if(val & 0x80000000) {
break;
}
val <<= 1;
} while(--index >= 0);
return index+1;
}
#endif
static inline int spice_bit_next_pow2(unsigned int val)
{
if ((val & (val - 1)) == 0) {
return val;
}
return 1 << spice_bit_find_msb(val);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -49,62 +49,10 @@ extern "C" {
#define GLC_ERROR_TEST_FINISH ;
#endif
#ifdef WIN32
static inline int find_msb(uint32_t val)
{
uint32_t r;
__asm {
bsr eax, val
jnz found
mov eax, -1
#include "bitops.h"
found:
mov r, eax
}
return r + 1;
}
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
static inline int find_msb(unsigned int val)
{
int ret;
asm ("bsrl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:"
: "=r"(ret) : "r"(val));
return ret + 1;
}
#else
static inline int find_msb(unsigned int val)
{
signed char index = 31;
if(val == 0) {
return 0;
}
do {
if(val & 0x80000000) {
break;
}
val <<= 1;
} while(--index >= 0);
return index+1;
}
#endif
static inline int gl_get_to_power_two(unsigned int val)
{
if ((val & (val - 1)) == 0) {
return val;
}
return 1 << find_msb(val);
}
#define find_msb spice_bit_find_msb
#define gl_get_to_power_two spice_bit_next_pow2
#ifdef __cplusplus
}

View File

@ -25,6 +25,7 @@
#include "quic.h"
#include <spice/macros.h>
#include "bitops.h"
//#define DEBUG
@ -707,17 +708,6 @@ static int decode_channel_run(Encoder *encoder, Channel *channel)
#else
static INLINE int find_msb(int x)
{
int r;
__asm__("bsrl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:" : "=r" (r) : "rm" (x));
return r + 1;
}
static INLINE void encode_run(Encoder *encoder, unsigned int len)
{
int odd = len & 1U;
@ -725,7 +715,7 @@ static INLINE void encode_run(Encoder *encoder, unsigned int len)
len &= ~1U;
while ((msb = find_msb(len))) {
while ((msb = spice_bit_find_msb(len))) {
len &= ~(1 << (msb - 1));
ASSERT(encoder->usr, msb < 32);
encode(encoder, (1 << (msb)) - 1, msb);