/* SPDX-License-Identifier: MIT */ /* * Helper functions for manipulation & testing of integer values * like zero or sign-extensions. * * Copyright (C) 2017 Luc Van Oostenryck * */ #ifndef BITS_H #define BITS_H static inline unsigned long long sign_bit(unsigned size) { return 1ULL << (size - 1); } static inline unsigned long long sign_mask(unsigned size) { unsigned long long sbit = sign_bit(size); return sbit - 1; } static inline unsigned long long bits_mask(unsigned size) { unsigned long long sbit = sign_bit(size); return sbit | (sbit - 1); } static inline long long zero_extend(long long val, unsigned size) { return val & bits_mask(size); } static inline long long sign_extend(long long val, unsigned size) { if (val & sign_bit(size)) val |= ~sign_mask(size); return val; } /// // sign extend @val but only if exactly representable static inline long long sign_extend_safe(long long val, unsigned size) { unsigned long long mask = bits_mask(size); if (!(val & ~mask)) val = sign_extend(val, size); return val; } static inline long long bits_extend(long long val, unsigned size, int is_signed) { val = zero_extend(val, size); if (is_signed) val = sign_extend(val, size); return val; } #endif