• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Helper functions for manipulation & testing of integer values
4  * like zero or sign-extensions.
5  *
6  * Copyright (C) 2017 Luc Van Oostenryck
7  *
8  */
9 
10 #ifndef BITS_H
11 #define BITS_H
12 
sign_bit(unsigned size)13 static inline unsigned long long sign_bit(unsigned size)
14 {
15 	return 1ULL << (size - 1);
16 }
17 
sign_mask(unsigned size)18 static inline unsigned long long sign_mask(unsigned size)
19 {
20 	unsigned long long sbit = sign_bit(size);
21 	return sbit - 1;
22 }
23 
bits_mask(unsigned size)24 static inline unsigned long long bits_mask(unsigned size)
25 {
26 	unsigned long long sbit = sign_bit(size);
27 	return sbit | (sbit - 1);
28 }
29 
30 
zero_extend(long long val,unsigned size)31 static inline long long zero_extend(long long val, unsigned size)
32 {
33 	return val & bits_mask(size);
34 }
35 
sign_extend(long long val,unsigned size)36 static inline long long sign_extend(long long val, unsigned size)
37 {
38 	if (val & sign_bit(size))
39 		val |= ~sign_mask(size);
40 	return val;
41 }
42 
43 ///
44 // sign extend @val but only if exactly representable
sign_extend_safe(long long val,unsigned size)45 static inline long long sign_extend_safe(long long val, unsigned size)
46 {
47 	unsigned long long mask = bits_mask(size);
48 	if (!(val & ~mask))
49 		val = sign_extend(val, size);
50 	return val;
51 }
52 
bits_extend(long long val,unsigned size,int is_signed)53 static inline long long bits_extend(long long val, unsigned size, int is_signed)
54 {
55 	val = zero_extend(val, size);
56 	if (is_signed)
57 		val = sign_extend(val, size);
58 	return val;
59 }
60 
is_power_of_2(long long val)61 static inline int is_power_of_2(long long val)
62 {
63 	return val && !(val & (val - 1));
64 }
65 
66 ///
67 // log base 2 of an exact power-of-2
log2_exact(unsigned long long val)68 static inline int log2_exact(unsigned long long val)
69 {
70 	return 8 * sizeof(val) - __builtin_clzl(val) - 1;
71 }
72 
73 #endif
74