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