1 /** Count leading zeros. 2 */ 3 module nxt.clz; 4 5 import std.traits : Unqual; 6 7 /******************************************************************************* 8 * 9 * Count leading zeroes. 10 * 11 * Params: 12 * u = the unsigned value to scan 13 * 14 * Returns: 15 * The number of leading zero bits before the first one bit. If `u` is `0`, 16 * the result is undefined. 17 * 18 **************************************/ 19 version (DigitalMars) 20 { 21 pragma(inline, true) 22 U clz(U)(U u) @safe @nogc pure nothrow 23 if (is(Unqual!U == uint) || 24 is(Unqual!U == size_t)) 25 => (cast(U)(8 * U.sizeof - 1)) - bsr(u); 26 27 static if (isX86) 28 { 29 pragma(inline, true) 30 uint clz(U)(U u) @safe @nogc pure nothrow 31 if (is(Unqual!U == ulong)) 32 { 33 uint hi = u >> 32; 34 return hi ? 31 - bsr(hi) : 63 - bsr(cast(uint)u); 35 } 36 } 37 } 38 else version (GNU) 39 { 40 import gcc.builtins; 41 alias clz = __builtin_clz; 42 static if (isX86) 43 { 44 @safe @nogc pure nothrow uint 45 clz(ulong u) 46 { 47 uint hi = u >> 32; 48 return hi ? __builtin_clz(hi) : 32 + __builtin_clz(cast(uint)u); 49 } 50 } 51 else alias clz = __builtin_clzl; 52 } 53 else version (LDC) 54 { 55 import ldc.intrinsics; 56 pragma(inline, true) 57 U clz(U)(U u) @safe @nogc pure nothrow 58 if (is(Unqual!U == uint) || is(Unqual!U == size_t)) 59 => llvm_ctlz(u, false); 60 61 static if (isX86) 62 { 63 pragma(inline, true) 64 uint clz(U)(U u) @safe @nogc pure nothrow 65 if (is(Unqual!U == ulong)) 66 => cast(uint)llvm_ctlz(u, false); 67 } 68 } 69 70 version (X86_64) 71 { 72 private enum isAMD64 = true; 73 private enum isX86 = false; 74 } 75 else version (X86) 76 { 77 private enum isAMD64 = false; 78 private enum isX86 = true; 79 } 80 81 version (X86_64) 82 private enum hasSSE2 = true; 83 else 84 private enum hasSSE2 = false; 85 86 static import core.bitop; 87 88 alias bsr = core.bitop.bsr; 89 alias bsf = core.bitop.bsf; 90 91 @safe pure nothrow @nogc unittest 92 { 93 assert(clz(uint(0x01234567)) == 7); 94 assert(clz(ulong(0x0123456701234567)) == 7); 95 assert(clz(ulong(0x0000000001234567)) == 7+32); 96 assert(bsr(uint(0x01234567)) == 24); 97 assert(bsr(ulong(0x0123456701234567)) == 24+32); 98 assert(bsr(ulong(0x0000000001234567)) == 24); 99 assert(bsf(uint(0x76543210)) == 4); 100 assert(bsf(ulong(0x7654321076543210)) == 4); 101 assert(bsf(ulong(0x7654321000000000)) == 4+32); 102 } 103