bits.h 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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. #ifndef BITS_H
  10. #define BITS_H
  11. static inline unsigned long long sign_bit(unsigned size)
  12. {
  13. return 1ULL << (size - 1);
  14. }
  15. static inline unsigned long long sign_mask(unsigned size)
  16. {
  17. unsigned long long sbit = sign_bit(size);
  18. return sbit - 1;
  19. }
  20. static inline unsigned long long bits_mask(unsigned size)
  21. {
  22. unsigned long long sbit = sign_bit(size);
  23. return sbit | (sbit - 1);
  24. }
  25. static inline long long zero_extend(long long val, unsigned size)
  26. {
  27. return val & bits_mask(size);
  28. }
  29. static inline long long sign_extend(long long val, unsigned size)
  30. {
  31. if (val & sign_bit(size))
  32. val |= ~sign_mask(size);
  33. return val;
  34. }
  35. ///
  36. // sign extend @val but only if exactly representable
  37. static inline long long sign_extend_safe(long long val, unsigned size)
  38. {
  39. unsigned long long mask = bits_mask(size);
  40. if (!(val & ~mask))
  41. val = sign_extend(val, size);
  42. return val;
  43. }
  44. static inline long long bits_extend(long long val, unsigned size, int is_signed)
  45. {
  46. val = zero_extend(val, size);
  47. if (is_signed)
  48. val = sign_extend(val, size);
  49. return val;
  50. }
  51. #endif