buf_size: fix handling of unknown flexible array sizes
[smatch.git] / bits.h
blobc0dc952eaed990f012532bf9c26e2124f8979a3f
1 /* SPDX-License-Identifier: MIT */
2 /*
3 * Helper functions for manipulation & testing of integer values
4 * like zero or sign-extensions.
6 * Copyright (C) 2017 Luc Van Oostenryck
8 */
10 #ifndef BITS_H
11 #define BITS_H
13 static inline unsigned long long sign_bit(unsigned size)
15 return 1ULL << (size - 1);
18 static inline unsigned long long sign_mask(unsigned size)
20 unsigned long long sbit = sign_bit(size);
21 return sbit - 1;
24 static inline unsigned long long bits_mask(unsigned size)
26 unsigned long long sbit = sign_bit(size);
27 return sbit | (sbit - 1);
31 static inline long long zero_extend(long long val, unsigned size)
33 return val & bits_mask(size);
36 static inline long long sign_extend(long long val, unsigned size)
38 if (val & sign_bit(size))
39 val |= ~sign_mask(size);
40 return val;
43 ///
44 // sign extend @val but only if exactly representable
45 static inline long long sign_extend_safe(long long val, unsigned size)
47 unsigned long long mask = bits_mask(size);
48 if (!(val & ~mask))
49 val = sign_extend(val, size);
50 return val;
53 static inline long long bits_extend(long long val, unsigned size, int is_signed)
55 val = zero_extend(val, size);
56 if (is_signed)
57 val = sign_extend(val, size);
58 return val;
61 #endif