Line data Source code
1 : /*
2 : * Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
3 : * All rights reserved.
4 : *
5 : * Permission is hereby granted, free of charge, to any person obtaining a copy
6 : * of this software and associated documentation files (the "Software"), to deal
7 : * in the Software without restriction, including without limitation the rights
8 : * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : * copies of the Software, and to permit persons to whom the Software is
10 : * furnished to do so, subject to the following conditions:
11 : *
12 : * The above copyright notice and this permission notice shall be included in
13 : * all copies or substantial portions of the Software.
14 : *
15 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : * THE SOFTWARE.
22 : */
23 :
24 : #include <config.h>
25 : #include <assert.h>
26 :
27 : #include "roken.h"
28 :
29 : #if defined(_MSC_VER)
30 : #include <intrin.h>
31 : #if defined(_WIN64)
32 : #pragma intrinsic(_BitScanReverse64)
33 : #else
34 : #pragma intrinsic(_BitScanReverse)
35 : #endif
36 : #endif
37 :
38 : ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
39 0 : rk_clzll(uint64_t x)
40 : {
41 : #if defined(_MSC_VER)
42 : unsigned long r = 0;
43 : #elif !(defined(__GNUC__) && __GNUC__ >= 4)
44 : int r = 0;
45 : #endif
46 :
47 0 : assert(x != 0);
48 :
49 : #if defined(_MSC_VER)
50 : # if defined(_WIN64)
51 : _BitScanReverse64(&r, x);
52 : # else
53 : if (_BitScanReverse(&r, (uint32_t)(x >> 32)))
54 : return 63 - (r + 32);
55 : _BitScanReverse(&r, (uint32_t)(x & 0xFFFFFFFF));
56 : # endif
57 :
58 : return 63 - r;
59 : #elif (defined(__GNUC__) && __GNUC__ >= 4)
60 0 : return __builtin_clzll(x);
61 : #else
62 : while (!(x & ((uint64_t)1 << 63))) {
63 : x <<= 1;
64 : ++r;
65 : }
66 :
67 : return r;
68 : #endif /* _MSC_VER || __GNUC__ */
69 : }
|