xref: /spdk/lib/util/math.c (revision a6dbe3721eb3b5990707fc3e378c95e505dd8ab5)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2019 Intel Corporation. All rights reserved.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/stdinc.h"
7 #include "spdk/util.h"
8 #include "spdk/assert.h"
9 
10 /* The following will automatically generate several version of
11  * this function, targeted at different architectures. This
12  * is only supported by GCC 6 or newer. */
13 #if defined(__GNUC__) && __GNUC__ >= 6 && !defined(__clang__) \
14 	&& (defined(__i386__) || defined(__x86_64__)) \
15 	&& defined(__ELF__)
16 __attribute__((target_clones("bmi", "arch=core2", "arch=atom", "default")))
17 #endif
18 uint32_t
spdk_u32log2(uint32_t x)19 spdk_u32log2(uint32_t x)
20 {
21 	if (x == 0) {
22 		/* log(0) is undefined */
23 		return 0;
24 	}
25 	SPDK_STATIC_ASSERT(sizeof(x) == sizeof(unsigned int), "Incorrect size");
26 	return 31u - __builtin_clz(x);
27 }
28 
29 /* The following will automatically generate several version of
30  * this function, targeted at different architectures. This
31  * is only supported by GCC 6 or newer. */
32 #if defined(__GNUC__) && __GNUC__ >= 6 && !defined(__clang__) \
33 	&& (defined(__i386__) || defined(__x86_64__)) \
34 	&& defined(__ELF__)
35 __attribute__((target_clones("bmi", "arch=core2", "arch=atom", "default")))
36 #endif
37 uint64_t
spdk_u64log2(uint64_t x)38 spdk_u64log2(uint64_t x)
39 {
40 	if (x == 0) {
41 		/* log(0) is undefined */
42 		return 0;
43 	}
44 	SPDK_STATIC_ASSERT(sizeof(x) == sizeof(unsigned long long), "Incorrect size");
45 	return 63u - __builtin_clzll(x);
46 }
47