ilog2(): inline functions if practical

For many (most?) targets these will be very small functions, so inline
them.  However, just in case make these external library functions.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
H. Peter Anvin 2017-09-27 13:34:42 -07:00
parent fbce0bfb4e
commit 0a126062fb
12 changed files with 291 additions and 251 deletions

View file

@ -470,18 +470,19 @@ asm/directiv.$(O): asm/directiv.c asm/assemble.h asm/directiv.h asm/eval.h \
asm/float.h asm/listing.h asm/pptok.h asm/preproc.h asm/stdscan.h \
config/config.h config/msvc.h config/unknown.h config/watcom.h \
include/bytesex.h include/compiler.h include/error.h include/iflag.h \
include/labels.h include/nasm.h include/nasmint.h include/nasmlib.h \
include/opflags.h include/perfhash.h include/strlist.h include/tables.h \
output/outform.h x86/iflaggen.h x86/insnsi.h x86/regs.h
include/ilog2.h include/labels.h include/nasm.h include/nasmint.h \
include/nasmlib.h include/opflags.h include/perfhash.h include/strlist.h \
include/tables.h output/outform.h x86/iflaggen.h x86/insnsi.h x86/regs.h
asm/error.$(O): asm/error.c config/config.h config/msvc.h config/unknown.h \
config/watcom.h include/bytesex.h include/compiler.h include/error.h \
include/nasmint.h include/nasmlib.h
asm/eval.$(O): asm/eval.c asm/assemble.h asm/directiv.h asm/eval.h \
asm/float.h asm/pptok.h asm/preproc.h config/config.h config/msvc.h \
config/unknown.h config/watcom.h include/bytesex.h include/compiler.h \
include/error.h include/iflag.h include/labels.h include/nasm.h \
include/nasmint.h include/nasmlib.h include/opflags.h include/perfhash.h \
include/strlist.h include/tables.h x86/iflaggen.h x86/insnsi.h x86/regs.h
include/error.h include/iflag.h include/ilog2.h include/labels.h \
include/nasm.h include/nasmint.h include/nasmlib.h include/opflags.h \
include/perfhash.h include/strlist.h include/tables.h x86/iflaggen.h \
x86/insnsi.h x86/regs.h
asm/exprdump.$(O): asm/exprdump.c asm/directiv.h asm/pptok.h asm/preproc.h \
config/config.h config/msvc.h config/unknown.h config/watcom.h \
include/bytesex.h include/compiler.h include/nasm.h include/nasmint.h \
@ -628,8 +629,8 @@ nasmlib/hashtbl.$(O): nasmlib/hashtbl.c asm/directiv.h asm/pptok.h \
include/perfhash.h include/strlist.h include/tables.h x86/insnsi.h \
x86/regs.h
nasmlib/ilog2.$(O): nasmlib/ilog2.c config/config.h config/msvc.h \
config/unknown.h config/watcom.h include/bytesex.h include/compiler.h \
include/nasmint.h include/nasmlib.h
config/unknown.h config/watcom.h include/compiler.h include/ilog2.h \
include/nasmint.h
nasmlib/malloc.$(O): nasmlib/malloc.c config/config.h config/msvc.h \
config/unknown.h config/watcom.h include/bytesex.h include/compiler.h \
include/error.h include/nasmint.h include/nasmlib.h
@ -721,10 +722,10 @@ output/outbin.$(O): output/outbin.c asm/directiv.h asm/eval.h asm/pptok.h \
output/outcoff.$(O): output/outcoff.c asm/directiv.h asm/eval.h asm/pptok.h \
asm/preproc.h config/config.h config/msvc.h config/unknown.h \
config/watcom.h include/bytesex.h include/compiler.h include/error.h \
include/nasm.h include/nasmint.h include/nasmlib.h include/opflags.h \
include/perfhash.h include/raa.h include/saa.h include/strlist.h \
include/tables.h output/outform.h output/outlib.h output/pecoff.h \
x86/insnsi.h x86/regs.h
include/ilog2.h include/nasm.h include/nasmint.h include/nasmlib.h \
include/opflags.h include/perfhash.h include/raa.h include/saa.h \
include/strlist.h include/tables.h output/outform.h output/outlib.h \
output/pecoff.h x86/insnsi.h x86/regs.h
output/outdbg.$(O): output/outdbg.c asm/directiv.h asm/pptok.h asm/preproc.h \
asm/tokens.h config/config.h config/msvc.h config/unknown.h config/watcom.h \
include/bytesex.h include/compiler.h include/error.h include/iflag.h \
@ -758,10 +759,11 @@ output/outlib.$(O): output/outlib.c asm/directiv.h asm/pptok.h asm/preproc.h \
output/outmacho.$(O): output/outmacho.c asm/directiv.h asm/pptok.h \
asm/preproc.h config/config.h config/msvc.h config/unknown.h \
config/watcom.h include/bytesex.h include/compiler.h include/error.h \
include/labels.h include/nasm.h include/nasmint.h include/nasmlib.h \
include/opflags.h include/perfhash.h include/raa.h include/rbtree.h \
include/saa.h include/strlist.h include/tables.h include/ver.h \
output/dwarf.h output/outform.h output/outlib.h x86/insnsi.h x86/regs.h
include/ilog2.h include/labels.h include/nasm.h include/nasmint.h \
include/nasmlib.h include/opflags.h include/perfhash.h include/raa.h \
include/rbtree.h include/saa.h include/strlist.h include/tables.h \
include/ver.h output/dwarf.h output/outform.h output/outlib.h x86/insnsi.h \
x86/regs.h
output/outobj.$(O): output/outobj.c asm/directiv.h asm/eval.h asm/pptok.h \
asm/preproc.h asm/stdscan.h config/config.h config/msvc.h config/unknown.h \
config/watcom.h include/bytesex.h include/compiler.h include/error.h \

View file

@ -369,19 +369,19 @@ asm\directbl.$(O): asm\directbl.c asm\directiv.h config\msvc.h \
asm\directiv.$(O): asm\directiv.c asm\assemble.h asm\directiv.h asm\eval.h \
asm\float.h asm\listing.h asm\pptok.h asm\preproc.h asm\stdscan.h \
config\msvc.h config\unknown.h config\watcom.h include\bytesex.h \
include\compiler.h include\error.h include\iflag.h include\labels.h \
include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h \
include\perfhash.h include\strlist.h include\tables.h output\outform.h \
x86\iflaggen.h x86\insnsi.h x86\regs.h
include\compiler.h include\error.h include\iflag.h include\ilog2.h \
include\labels.h include\nasm.h include\nasmint.h include\nasmlib.h \
include\opflags.h include\perfhash.h include\strlist.h include\tables.h \
output\outform.h x86\iflaggen.h x86\insnsi.h x86\regs.h
asm\error.$(O): asm\error.c config\msvc.h config\unknown.h config\watcom.h \
include\bytesex.h include\compiler.h include\error.h include\nasmint.h \
include\nasmlib.h
asm\eval.$(O): asm\eval.c asm\assemble.h asm\directiv.h asm\eval.h \
asm\float.h asm\pptok.h asm\preproc.h config\msvc.h config\unknown.h \
config\watcom.h include\bytesex.h include\compiler.h include\error.h \
include\iflag.h include\labels.h include\nasm.h include\nasmint.h \
include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h \
include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h
include\iflag.h include\ilog2.h include\labels.h include\nasm.h \
include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h \
include\strlist.h include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h
asm\exprdump.$(O): asm\exprdump.c asm\directiv.h asm\pptok.h asm\preproc.h \
config\msvc.h config\unknown.h config\watcom.h include\bytesex.h \
include\compiler.h include\nasm.h include\nasmint.h include\nasmlib.h \
@ -522,8 +522,7 @@ nasmlib\hashtbl.$(O): nasmlib\hashtbl.c asm\directiv.h asm\pptok.h \
include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h \
include\strlist.h include\tables.h x86\insnsi.h x86\regs.h
nasmlib\ilog2.$(O): nasmlib\ilog2.c config\msvc.h config\unknown.h \
config\watcom.h include\bytesex.h include\compiler.h include\nasmint.h \
include\nasmlib.h
config\watcom.h include\compiler.h include\ilog2.h include\nasmint.h
nasmlib\malloc.$(O): nasmlib\malloc.c config\msvc.h config\unknown.h \
config\watcom.h include\bytesex.h include\compiler.h include\error.h \
include\nasmint.h include\nasmlib.h
@ -609,10 +608,11 @@ output\outbin.$(O): output\outbin.c asm\directiv.h asm\eval.h asm\pptok.h \
output\outform.h output\outlib.h x86\insnsi.h x86\regs.h
output\outcoff.$(O): output\outcoff.c asm\directiv.h asm\eval.h asm\pptok.h \
asm\preproc.h config\msvc.h config\unknown.h config\watcom.h \
include\bytesex.h include\compiler.h include\error.h include\nasm.h \
include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h \
include\raa.h include\saa.h include\strlist.h include\tables.h \
output\outform.h output\outlib.h output\pecoff.h x86\insnsi.h x86\regs.h
include\bytesex.h include\compiler.h include\error.h include\ilog2.h \
include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h \
include\perfhash.h include\raa.h include\saa.h include\strlist.h \
include\tables.h output\outform.h output\outlib.h output\pecoff.h \
x86\insnsi.h x86\regs.h
output\outdbg.$(O): output\outdbg.c asm\directiv.h asm\pptok.h asm\preproc.h \
asm\tokens.h config\msvc.h config\unknown.h config\watcom.h \
include\bytesex.h include\compiler.h include\error.h include\iflag.h \
@ -644,11 +644,11 @@ output\outlib.$(O): output\outlib.c asm\directiv.h asm\pptok.h asm\preproc.h \
include\tables.h output\outlib.h x86\insnsi.h x86\regs.h
output\outmacho.$(O): output\outmacho.c asm\directiv.h asm\pptok.h \
asm\preproc.h config\msvc.h config\unknown.h config\watcom.h \
include\bytesex.h include\compiler.h include\error.h include\labels.h \
include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h \
include\perfhash.h include\raa.h include\rbtree.h include\saa.h \
include\strlist.h include\tables.h include\ver.h output\dwarf.h \
output\outform.h output\outlib.h x86\insnsi.h x86\regs.h
include\bytesex.h include\compiler.h include\error.h include\ilog2.h \
include\labels.h include\nasm.h include\nasmint.h include\nasmlib.h \
include\opflags.h include\perfhash.h include\raa.h include\rbtree.h \
include\saa.h include\strlist.h include\tables.h include\ver.h \
output\dwarf.h output\outform.h output\outlib.h x86\insnsi.h x86\regs.h
output\outobj.$(O): output\outobj.c asm\directiv.h asm\eval.h asm\pptok.h \
asm\preproc.h asm\stdscan.h config\msvc.h config\unknown.h config\watcom.h \
include\bytesex.h include\compiler.h include\error.h include\nasm.h \

View file

@ -343,19 +343,19 @@ asm/directbl.$(O): asm/directbl.c asm/directiv.h config/msvc.h &
asm/directiv.$(O): asm/directiv.c asm/assemble.h asm/directiv.h asm/eval.h &
asm/float.h asm/listing.h asm/pptok.h asm/preproc.h asm/stdscan.h &
config/msvc.h config/unknown.h config/watcom.h include/bytesex.h &
include/compiler.h include/error.h include/iflag.h include/labels.h &
include/nasm.h include/nasmint.h include/nasmlib.h include/opflags.h &
include/perfhash.h include/strlist.h include/tables.h output/outform.h &
x86/iflaggen.h x86/insnsi.h x86/regs.h
include/compiler.h include/error.h include/iflag.h include/ilog2.h &
include/labels.h include/nasm.h include/nasmint.h include/nasmlib.h &
include/opflags.h include/perfhash.h include/strlist.h include/tables.h &
output/outform.h x86/iflaggen.h x86/insnsi.h x86/regs.h
asm/error.$(O): asm/error.c config/msvc.h config/unknown.h config/watcom.h &
include/bytesex.h include/compiler.h include/error.h include/nasmint.h &
include/nasmlib.h
asm/eval.$(O): asm/eval.c asm/assemble.h asm/directiv.h asm/eval.h &
asm/float.h asm/pptok.h asm/preproc.h config/msvc.h config/unknown.h &
config/watcom.h include/bytesex.h include/compiler.h include/error.h &
include/iflag.h include/labels.h include/nasm.h include/nasmint.h &
include/nasmlib.h include/opflags.h include/perfhash.h include/strlist.h &
include/tables.h x86/iflaggen.h x86/insnsi.h x86/regs.h
include/iflag.h include/ilog2.h include/labels.h include/nasm.h &
include/nasmint.h include/nasmlib.h include/opflags.h include/perfhash.h &
include/strlist.h include/tables.h x86/iflaggen.h x86/insnsi.h x86/regs.h
asm/exprdump.$(O): asm/exprdump.c asm/directiv.h asm/pptok.h asm/preproc.h &
config/msvc.h config/unknown.h config/watcom.h include/bytesex.h &
include/compiler.h include/nasm.h include/nasmint.h include/nasmlib.h &
@ -496,8 +496,7 @@ nasmlib/hashtbl.$(O): nasmlib/hashtbl.c asm/directiv.h asm/pptok.h &
include/nasmint.h include/nasmlib.h include/opflags.h include/perfhash.h &
include/strlist.h include/tables.h x86/insnsi.h x86/regs.h
nasmlib/ilog2.$(O): nasmlib/ilog2.c config/msvc.h config/unknown.h &
config/watcom.h include/bytesex.h include/compiler.h include/nasmint.h &
include/nasmlib.h
config/watcom.h include/compiler.h include/ilog2.h include/nasmint.h
nasmlib/malloc.$(O): nasmlib/malloc.c config/msvc.h config/unknown.h &
config/watcom.h include/bytesex.h include/compiler.h include/error.h &
include/nasmint.h include/nasmlib.h
@ -583,10 +582,11 @@ output/outbin.$(O): output/outbin.c asm/directiv.h asm/eval.h asm/pptok.h &
output/outform.h output/outlib.h x86/insnsi.h x86/regs.h
output/outcoff.$(O): output/outcoff.c asm/directiv.h asm/eval.h asm/pptok.h &
asm/preproc.h config/msvc.h config/unknown.h config/watcom.h &
include/bytesex.h include/compiler.h include/error.h include/nasm.h &
include/nasmint.h include/nasmlib.h include/opflags.h include/perfhash.h &
include/raa.h include/saa.h include/strlist.h include/tables.h &
output/outform.h output/outlib.h output/pecoff.h x86/insnsi.h x86/regs.h
include/bytesex.h include/compiler.h include/error.h include/ilog2.h &
include/nasm.h include/nasmint.h include/nasmlib.h include/opflags.h &
include/perfhash.h include/raa.h include/saa.h include/strlist.h &
include/tables.h output/outform.h output/outlib.h output/pecoff.h &
x86/insnsi.h x86/regs.h
output/outdbg.$(O): output/outdbg.c asm/directiv.h asm/pptok.h asm/preproc.h &
asm/tokens.h config/msvc.h config/unknown.h config/watcom.h &
include/bytesex.h include/compiler.h include/error.h include/iflag.h &
@ -618,11 +618,11 @@ output/outlib.$(O): output/outlib.c asm/directiv.h asm/pptok.h asm/preproc.h &
include/tables.h output/outlib.h x86/insnsi.h x86/regs.h
output/outmacho.$(O): output/outmacho.c asm/directiv.h asm/pptok.h &
asm/preproc.h config/msvc.h config/unknown.h config/watcom.h &
include/bytesex.h include/compiler.h include/error.h include/labels.h &
include/nasm.h include/nasmint.h include/nasmlib.h include/opflags.h &
include/perfhash.h include/raa.h include/rbtree.h include/saa.h &
include/strlist.h include/tables.h include/ver.h output/dwarf.h &
output/outform.h output/outlib.h x86/insnsi.h x86/regs.h
include/bytesex.h include/compiler.h include/error.h include/ilog2.h &
include/labels.h include/nasm.h include/nasmint.h include/nasmlib.h &
include/opflags.h include/perfhash.h include/raa.h include/rbtree.h &
include/saa.h include/strlist.h include/tables.h include/ver.h &
output/dwarf.h output/outform.h output/outlib.h x86/insnsi.h x86/regs.h
output/outobj.$(O): output/outobj.c asm/directiv.h asm/eval.h asm/pptok.h &
asm/preproc.h asm/stdscan.h config/msvc.h config/unknown.h config/watcom.h &
include/bytesex.h include/compiler.h include/error.h include/nasm.h &

View file

@ -44,6 +44,7 @@
#include "nasm.h"
#include "nasmlib.h"
#include "ilog2.h"
#include "error.h"
#include "float.h"
#include "stdscan.h"

View file

@ -45,6 +45,7 @@
#include "nasm.h"
#include "nasmlib.h"
#include "ilog2.h"
#include "error.h"
#include "eval.h"
#include "labels.h"

View file

@ -207,6 +207,29 @@ char *strsep(char **, const char *);
size_t strnlen(const char *s, size_t maxlen);
#endif
/*
* Hack to support external-linkage inline functions
*/
#ifdef __GNUC__
# ifdef __GNUC_STDC_INLINE__
# define HAVE_STDC_INLINE
# else
# define HAVE_GNU_INLINE
# endif
#elif defined(__STDC_VERSION__)
# if __STDC_VERSION__ >= 199901L
# define HAVE_STDC_INLINE
# endif
#endif
#ifdef HAVE_STDC_INLINE
# define extern_inline inline
#elif defined(HAVE_GNU_INLINE)
# define extern_inline extern inline
#else
# define inline_prototypes
#endif
/*
* Hints to the compiler that a particular branch of code is more or
* less likely to be taken.

View file

@ -4,9 +4,7 @@
#include <string.h>
#include "compiler.h"
int ilog2_32(uint32_t v);
#include "ilog2.h"
#include "iflaggen.h"
#define IF_GENBIT(bit) (UINT32_C(1) << (bit))

207
include/ilog2.h Normal file
View file

@ -0,0 +1,207 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2017 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
#ifndef ILOG2_H
#define ILOG2_H
#include "compiler.h"
#include <limits.h>
#ifdef ILOG2_C /* For generating the out-of-line functions */
# undef extern_inline
# define extern_inline
# define inline_prototypes
#endif
#ifdef inline_prototypes
extern int const_func ilog2_32(uint32_t v);
extern int const_func ilog2_64(uint64_t v);
extern int const_func ilog2_64(uint64_t vv);
extern int const_func alignlog2_32(uint32_t v);
#endif
#ifdef extern_inline
#define ROUND(v, a, w) \
do { \
if (v & (((UINT32_C(1) << w) - 1) << w)) { \
a += w; \
v >>= w; \
} \
} while (0)
#if defined(__GNUC__) && defined(__x86_64__)
extern_inline int const_func ilog2_32(uint32_t v)
{
int n;
__asm__("bsrl %1,%0"
: "=r" (n)
: "rm" (v), "0" (0));
return n;
}
#elif defined(__GNUC__) && defined(__i386__)
extern_inline int const_func ilog2_32(uint32_t v)
{
int n;
#ifdef __i686__
__asm__("bsrl %1,%0 ; cmovz %2,%0\n"
: "=&r" (n)
: "rm" (v), "r" (0));
#else
__asm__("bsrl %1,%0 ; jnz 1f ; xorl %0,%0\n"
"1:"
: "=&r" (n)
: "rm" (v));
#endif
return n;
}
#elif defined(HAVE___BUILTIN_CLZ) && INT_MAX == 2147483647
extern_inline int const_func ilog2_32(uint32_t v)
{
if (!v)
return 0;
return __builtin_clz(v) ^ 31;
}
#elif defined(HAVE__BITSCANREVERSE)
extern_inline int const_func ilog2_32(uint32_t v)
{
unsigned long ix;
return _BitScanReverse(&ix, v) ? v : 0;
}
#else
extern_inline int const_func ilog2_32(uint32_t v)
{
int p = 0;
ROUND(v, p, 16);
ROUND(v, p, 8);
ROUND(v, p, 4);
ROUND(v, p, 2);
ROUND(v, p, 1);
return p;
}
#endif
#if defined(__GNUC__) && defined(__x86_64__)
extern_inline int const_func ilog2_64(uint64_t v)
{
uint64_t n;
__asm__("bsrq %1,%0"
: "=r" (n)
: "rm" (v), "0" (UINT64_C(0)));
return n;
}
#elif defined(HAVE__BUILTIN_CLZLL) && LLONG_MAX == 9223372036854775807LL
extern_inline int const_func ilog2_64(uint64_t v)
{
if (!v)
return 0;
return __builtin_clzll(v) ^ 63;
}
#elif defined(HAVE__BITSCANREVERSE64)
extern_inline int const_func ilog2_64(uint64_t v)
{
unsigned long ix;
return _BitScanReverse64(&ix, v) ? ix : 0;
}
#else
extern_inline int const_func ilog2_64(uint64_t vv)
{
int p = 0;
uint32_t v;
v = vv >> 32;
if (v)
p += 32;
else
v = vv;
ROUND(v, p, 16);
ROUND(v, p, 8);
ROUND(v, p, 4);
ROUND(v, p, 2);
ROUND(v, p, 1);
return p;
}
#endif
/*
* v == 0 ? 0 : is_power2(x) ? ilog2_X(v) : -1
*/
extern_inline int const_func alignlog2_32(uint32_t v)
{
if (unlikely(v & (v-1)))
return -1; /* invalid alignment */
return ilog2_32(v);
}
extern_inline int const_func alignlog2_64(uint64_t v)
{
if (unlikely(v & (v-1)))
return -1; /* invalid alignment */
return ilog2_64(v);
}
#undef ROUND
#endif /* extern_inline */
#endif /* ILOG2_H */

View file

@ -414,16 +414,4 @@ static inline int64_t const_func signed_bits(int64_t value, int bits)
/* check if value is power of 2 */
#define is_power2(v) ((v) && ((v) & ((v) - 1)) == 0)
/*
* floor(log2(v))
*/
int const_func ilog2_32(uint32_t v);
int const_func ilog2_64(uint64_t v);
/*
* v == 0 ? 0 : is_power2(x) ? ilog2_X(v) : -1
*/
int const_func alignlog2_32(uint32_t v);
int const_func alignlog2_64(uint64_t v);
#endif

View file

@ -1,184 +1,2 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2017 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
#include "compiler.h"
#include "nasmlib.h"
#include <limits.h>
#define ROUND(v, a, w) \
do { \
if (v & (((UINT32_C(1) << w) - 1) << w)) { \
a += w; \
v >>= w; \
} \
} while (0)
#if defined(__GNUC__) && defined(__x86_64__)
int ilog2_32(uint32_t v)
{
int n;
__asm__("bsrl %1,%0"
: "=r" (n)
: "rm" (v), "0" (0));
return n;
}
#elif defined(__GNUC__) && defined(__i386__)
int ilog2_32(uint32_t v)
{
int n;
#ifdef __i686__
__asm__("bsrl %1,%0 ; cmovz %2,%0\n"
: "=&r" (n)
: "rm" (v), "r" (0));
#else
__asm__("bsrl %1,%0 ; jnz 1f ; xorl %0,%0\n"
"1:"
: "=&r" (n)
: "rm" (v));
#endif
return n;
}
#elif defined(HAVE___BUILTIN_CLZ) && INT_MAX == 2147483647
int ilog2_32(uint32_t v)
{
if (!v)
return 0;
return __builtin_clz(v) ^ 31;
}
#elif defined(HAVE__BITSCANREVERSE)
int ilog2_32(uint32_t v)
{
unsigned long ix;
return _BitScanReverse(&ix, v) ? v : 0;
}
#else
int ilog2_32(uint32_t v)
{
int p = 0;
ROUND(v, p, 16);
ROUND(v, p, 8);
ROUND(v, p, 4);
ROUND(v, p, 2);
ROUND(v, p, 1);
return p;
}
#endif
#if defined(__GNUC__) && defined(__x86_64__)
int ilog2_64(uint64_t v)
{
uint64_t n;
__asm__("bsrq %1,%0"
: "=r" (n)
: "rm" (v), "0" (UINT64_C(0)));
return n;
}
#elif defined(HAVE__BUILTIN_CLZLL) && LLONG_MAX == 9223372036854775807LL
int ilog2_64(uint64_t v)
{
if (!v)
return 0;
return __builtin_clzll(v) ^ 63;
}
#elif defined(HAVE__BITSCANREVERSE64)
int ilog2_64(uint64_t v)
{
unsigned long ix;
return _BitScanReverse64(&ix, v) ? ix : 0;
}
#else
int ilog2_64(uint64_t vv)
{
int p = 0;
uint32_t v;
v = vv >> 32;
if (v)
p += 32;
else
v = vv;
ROUND(v, p, 16);
ROUND(v, p, 8);
ROUND(v, p, 4);
ROUND(v, p, 2);
ROUND(v, p, 1);
return p;
}
#endif
/*
* v == 0 ? 0 : is_power2(x) ? ilog2_X(v) : -1
*/
int alignlog2_32(uint32_t v)
{
if (unlikely(v & (v-1)))
return -1; /* invalid alignment */
return ilog2_32(v);
}
int alignlog2_64(uint64_t v)
{
if (unlikely(v & (v-1)))
return -1; /* invalid alignment */
return ilog2_64(v);
}
#define ILOG2_C
#include "ilog2.h"

View file

@ -46,6 +46,7 @@
#include "nasm.h"
#include "nasmlib.h"
#include "ilog2.h"
#include "error.h"
#include "saa.h"
#include "raa.h"

View file

@ -45,6 +45,7 @@
#include "nasm.h"
#include "nasmlib.h"
#include "ilog2.h"
#include "labels.h"
#include "error.h"
#include "saa.h"