diff --git a/libc/intrin/bsf.h b/libc/intrin/bsf.h index 1a24bf821..090270d11 100644 --- a/libc/intrin/bsf.h +++ b/libc/intrin/bsf.h @@ -6,7 +6,6 @@ COSMOPOLITAN_C_START_ int _bsf(int) pureconst; int _bsfl(long) pureconst; int _bsfll(long long) pureconst; -int _bsf128(uintmax_t) pureconst; #if defined(__GNUC__) && !defined(__STRICT_ANSI__) #define _bsf(x) __builtin_ctz(x) diff --git a/libc/intrin/bsr.c b/libc/intrin/bsr.c index b8d8646dc..81a30e1ff 100644 --- a/libc/intrin/bsr.c +++ b/libc/intrin/bsr.c @@ -17,40 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/bsr.h" - -static const char kDebruijn[64] = { - 0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61, - 54, 58, 35, 52, 50, 42, 21, 44, 38, 32, 29, 23, 17, 11, 4, 62, - 46, 55, 26, 59, 40, 36, 15, 53, 34, 51, 20, 43, 31, 22, 10, 45, - 25, 39, 14, 33, 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63, -}; - -/** - * Returns binary logarithm of 𝑥. - * - * ctz(𝑥) 31^clz(𝑥) clz(𝑥) - * uint32 𝑥 _bsf(𝑥) tzcnt(𝑥) ffs(𝑥) _bsr(𝑥) lzcnt(𝑥) - * 0x00000000 wut 32 0 wut 32 - * 0x00000001 0 0 1 0 31 - * 0x80000001 0 0 1 31 0 - * 0x80000000 31 31 32 31 0 - * 0x00000010 4 4 5 4 27 - * 0x08000010 4 4 5 27 4 - * 0x08000000 27 27 28 27 4 - * 0xffffffff 0 0 1 31 0 - * - * @param x is a 64-bit integer - * @return number in range 0..63 or undefined if 𝑥 is 0 - */ -int(_bsrl)(long x) { - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - x |= x >> 32; - return kDebruijn[(x * 0x03f79d71b4cb0a89) >> 58]; -} +// clang-format off /** * Returns binary logarithm of 𝑥. @@ -70,7 +37,11 @@ int(_bsrl)(long x) { * @return number in range 0..31 or undefined if 𝑥 is 0 */ int(_bsr)(int x) { - return _bsrl((unsigned)x); + int r = 0; + if(x & 0xFFFF0000u) { x >>= 16; r |= 16; } + if(x & 0xFF00) { x >>= 8; r |= 8; } + if(x & 0xF0) { x >>= 4; r |= 4; } + if(x & 0xC) { x >>= 2; r |= 2; } + if(x & 0x2) { r |= 1; } + return r; } - -__weak_reference(_bsrl, _bsrll); diff --git a/libc/intrin/bsr128.S b/libc/intrin/bsrl.c similarity index 51% rename from libc/intrin/bsr128.S rename to libc/intrin/bsrl.c index cabcba96e..675f4f54a 100644 --- a/libc/intrin/bsr128.S +++ b/libc/intrin/bsrl.c @@ -1,7 +1,7 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ @@ -16,31 +16,40 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.internal.h" +#include "libc/intrin/bsr.h" -// Returns binary logarithm of integer 𝑥. -// -// uint32 𝑥 _bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥) -// 0x00000000 wut 32 0 wut 32 -// 0x00000001 0 0 1 0 31 -// 0x80000001 0 0 1 31 0 -// 0x80000000 31 31 32 31 0 -// 0x00000010 4 4 5 4 27 -// 0x08000010 4 4 5 27 4 -// 0x08000000 27 27 28 27 4 -// 0xffffffff 0 0 1 31 0 -// -// @param rsi:rdi is 128-bit unsigned 𝑥 value -// @return eax number in range [0,128) or undef if 𝑥 is 0 -// @see also treasure trove of nearly identical functions - .ftrace1 -_bsr128: - .ftrace2 - .leafprologue - bsr %rsi,%rax - jnz 2f - bsr %rdi,%rax -1: .leafepilogue -2: add $64,%eax - jmp 1b - .endfn _bsr128,globl +static const char kDebruijn[64] = { + 0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61, + 54, 58, 35, 52, 50, 42, 21, 44, 38, 32, 29, 23, 17, 11, 4, 62, + 46, 55, 26, 59, 40, 36, 15, 53, 34, 51, 20, 43, 31, 22, 10, 45, + 25, 39, 14, 33, 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63, +}; + +/** + * Returns binary logarithm of 𝑥. + * + * ctz(𝑥) 31^clz(𝑥) clz(𝑥) + * uint32 𝑥 _bsf(𝑥) tzcnt(𝑥) ffs(𝑥) _bsr(𝑥) lzcnt(𝑥) + * 0x00000000 wut 32 0 wut 32 + * 0x00000001 0 0 1 0 31 + * 0x80000001 0 0 1 31 0 + * 0x80000000 31 31 32 31 0 + * 0x00000010 4 4 5 4 27 + * 0x08000010 4 4 5 27 4 + * 0x08000000 27 27 28 27 4 + * 0xffffffff 0 0 1 31 0 + * + * @param x is a 64-bit integer + * @return number in range 0..63 or undefined if 𝑥 is 0 + */ +int(_bsrl)(long x) { + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + return kDebruijn[(x * 0x03f79d71b4cb0a89) >> 58]; +} + +__weak_reference(_bsrl, _bsrll);