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 13 static inline unsigned long long sign_bit(unsigned size) 14 { 15 return 1ULL << (size - 1); 16 } 17 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 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 31 static inline long long zero_extend(long long val, unsigned size) 32 { 33 return val & bits_mask(size); 34 } 35 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 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 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 61 #endif 62