Buckets:
| /* ---------------------------------------------------------------------------- | |
| Copyright (c) 2019-2024 Microsoft Research, Daan Leijen | |
| This is free software; you can redistribute it and/or modify it under the | |
| terms of the MIT license. A copy of the license can be found in the file | |
| "LICENSE" at the root of this distribution. | |
| -----------------------------------------------------------------------------*/ | |
| /* ---------------------------------------------------------------------------- | |
| Bit operation, and platform dependent definition (MI_INTPTR_SIZE etc) | |
| ---------------------------------------------------------------------------- */ | |
| // ------------------------------------------------------ | |
| // Size of a pointer. | |
| // We assume that `sizeof(void*)==sizeof(intptr_t)` | |
| // and it holds for all platforms we know of. | |
| // | |
| // However, the C standard only requires that: | |
| // p == (void*)((intptr_t)p)) | |
| // but we also need: | |
| // i == (intptr_t)((void*)i) | |
| // or otherwise one might define an intptr_t type that is larger than a pointer... | |
| // ------------------------------------------------------ | |
| typedef int64_t mi_ssize_t; | |
| typedef int32_t mi_ssize_t; | |
| /* -------------------------------------------------------------------------------- | |
| Architecture | |
| -------------------------------------------------------------------------------- */ | |
| // Define big endian if needed | |
| // #define MI_BIG_ENDIAN 1 | |
| // maximum virtual address bits in a user-space pointer | |
| // use a flat page-map or a 2-level one | |
| /* -------------------------------------------------------------------------------- | |
| Builtin's | |
| -------------------------------------------------------------------------------- */ | |
| /* -------------------------------------------------------------------------------- | |
| Popcount and count trailing/leading zero's | |
| -------------------------------------------------------------------------------- */ | |
| size_t _mi_popcount_generic(size_t x); | |
| static inline size_t mi_popcount(size_t x) { | |
| return mi_builtinz(popcount)(x); | |
| return mi_msc_builtinz(__popcnt)(x); | |
| return (size_t)_mm_popcnt_u64(x); | |
| return (x<=1 ? x : _mi_popcount_generic(x)); | |
| } | |
| size_t _mi_clz_generic(size_t x); | |
| size_t _mi_ctz_generic(size_t x); | |
| static inline size_t mi_ctz(size_t x) { | |
| size_t r; | |
| __asm ("tzcnt\t%1, %0" : "=r"(r) : "r"(x) : "cc"); | |
| return r; | |
| return _tzcnt_u64(x); | |
| unsigned long idx; | |
| return (mi_msc_builtinz(_BitScanForward)(&idx, x) ? (size_t)idx : MI_SIZE_BITS); | |
| return (x!=0 ? (size_t)mi_builtinz(ctz)(x) : MI_SIZE_BITS); | |
| size_t r = MI_SIZE_BITS; // bsf leaves destination unmodified if the argument is 0 (see <https://github.com/llvm/llvm-project/pull/102885>) | |
| __asm ("bsf\t%1, %0" : "+r"(r) : "r"(x) : "cc"); | |
| return r; | |
| return (x!=0 ? (mi_popcount(x^(x-1))-1) : MI_SIZE_BITS); | |
| return (x!=0 ? _mi_ctz_generic(x) : MI_SIZE_BITS); | |
| } | |
| static inline size_t mi_clz(size_t x) { | |
| size_t r; | |
| __asm ("lzcnt\t%1, %0" : "=r"(r) : "r"(x) : "cc"); | |
| return r; | |
| return _lzcnt_u64(x); | |
| unsigned long idx; | |
| return (mi_msc_builtinz(_BitScanReverse)(&idx, x) ? MI_SIZE_BITS - 1 - (size_t)idx : MI_SIZE_BITS); | |
| return (x!=0 ? (size_t)mi_builtinz(clz)(x) : MI_SIZE_BITS); | |
| if (x==0) return MI_SIZE_BITS; | |
| size_t r; | |
| __asm ("bsr\t%1, %0" : "=r"(r) : "r"(x) : "cc"); | |
| return (MI_SIZE_BITS - 1 - r); | |
| return (x!=0 ? _mi_clz_generic(x) : MI_SIZE_BITS); | |
| } | |
| /* -------------------------------------------------------------------------------- | |
| find trailing/leading zero (bit scan forward/reverse) | |
| -------------------------------------------------------------------------------- */ | |
| // Bit scan forward: find the least significant bit that is set (i.e. count trailing zero's) | |
| // return false if `x==0` (with `*idx` undefined) and true otherwise, | |
| // with the `idx` is set to the bit index (`0 <= *idx < MI_BFIELD_BITS`). | |
| static inline bool mi_bsf(size_t x, size_t* idx) { | |
| // on x64 the carry flag is set on zero which gives better codegen | |
| bool is_zero; | |
| __asm ( "tzcnt\t%2, %1" : "=@ccc"(is_zero), "=r"(*idx) : "r"(x) : "cc" ); | |
| return !is_zero; | |
| unsigned long i; | |
| return (mi_msc_builtinz(_BitScanForward)(&i, x) ? (*idx = (size_t)i, true) : false); | |
| return (x!=0 ? (*idx = mi_ctz(x), true) : false); | |
| } | |
| // Bit scan reverse: find the most significant bit that is set | |
| // return false if `x==0` (with `*idx` undefined) and true otherwise, | |
| // with the `idx` is set to the bit index (`0 <= *idx < MI_BFIELD_BITS`). | |
| static inline bool mi_bsr(size_t x, size_t* idx) { | |
| unsigned long i; | |
| return (mi_msc_builtinz(_BitScanReverse)(&i, x) ? (*idx = (size_t)i, true) : false); | |
| return (x!=0 ? (*idx = MI_SIZE_BITS - 1 - mi_clz(x), true) : false); | |
| } | |
| /* -------------------------------------------------------------------------------- | |
| rotate | |
| -------------------------------------------------------------------------------- */ | |
| static inline size_t mi_rotr(size_t x, size_t r) { | |
| return mi_builtin(rotateright64)(x,r); | |
| return mi_builtin(rotateright32)(x,r); | |
| return _rotr64(x, (int)r); | |
| return _lrotr(x,(int)r); | |
| // The term `(-rshift)&(BITS-1)` is written instead of `BITS - rshift` to | |
| // avoid UB when `rshift==0`. See <https://blog.regehr.org/archives/1063> | |
| const unsigned int rshift = (unsigned int)(r) & (MI_SIZE_BITS-1); | |
| return ((x >> rshift) | (x << ((-rshift) & (MI_SIZE_BITS-1)))); | |
| } | |
| static inline size_t mi_rotl(size_t x, size_t r) { | |
| return mi_builtin(rotateleft64)(x,r); | |
| return mi_builtin(rotateleft32)(x,r); | |
| return _rotl64(x, (int)r); | |
| return _lrotl(x, (int)r); | |
| // The term `(-rshift)&(BITS-1)` is written instead of `BITS - rshift` to | |
| // avoid UB when `rshift==0`. See <https://blog.regehr.org/archives/1063> | |
| const unsigned int rshift = (unsigned int)(r) & (MI_SIZE_BITS-1); | |
| return ((x << rshift) | (x >> ((-rshift) & (MI_SIZE_BITS-1)))); | |
| } | |
| static inline uint32_t mi_rotl32(uint32_t x, uint32_t r) { | |
| return mi_builtin(rotateleft32)(x,r); | |
| return _lrotl(x, (int)r); | |
| // The term `(-rshift)&(BITS-1)` is written instead of `BITS - rshift` to | |
| // avoid UB when `rshift==0`. See <https://blog.regehr.org/archives/1063> | |
| const unsigned int rshift = (unsigned int)(r) & 31; | |
| return ((x << rshift) | (x >> ((-rshift) & 31))); | |
| } | |
Xet Storage Details
- Size:
- 12.3 kB
- Xet hash:
- 534e40eee4da9017c229414563447be26f9fc31058fb87cc21077d6ed658a58a
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.