forked from foobat/libanemo
127 lines
3.6 KiB
C++
127 lines
3.6 KiB
C++
/**
|
|
* @file width.hh
|
|
* @brief Provides width-related operations for integer types
|
|
*/
|
|
|
|
#ifndef LIBVIO_WIDTH_HH
|
|
#define LIBVIO_WIDTH_HH
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
|
|
namespace libvio {
|
|
|
|
/**
|
|
* @enum width_t
|
|
* @brief Enumeration representing different data widths
|
|
*/
|
|
enum class width_t {
|
|
byte = 1, ///< 1-byte width (8 bits)
|
|
half = 2, ///< 2-byte width (16 bits)
|
|
word = 4, ///< 4-byte width (32 bits)
|
|
dword = 8 ///< 8-byte width (64 bits)
|
|
};
|
|
|
|
/**
|
|
* @brief Truncates a value to the specified width by zeroing upper bits
|
|
* @tparam WORD_T The word type (uint32_t or uint64_t)
|
|
* @param value The input value to truncate
|
|
* @param width The target width to truncate to
|
|
* @return The truncated value with upper bits zeroed
|
|
*/
|
|
template <typename WORD_T>
|
|
constexpr WORD_T zero_truncate(WORD_T value, width_t width);
|
|
|
|
/**
|
|
* @brief Specialization of zero_truncate for uint32_t
|
|
* @param value The 32-bit input value to truncate
|
|
* @param width The target width to truncate to
|
|
* @return The truncated 32-bit value with upper bits zeroed
|
|
*/
|
|
template <>
|
|
constexpr uint32_t zero_truncate<uint32_t>(uint32_t value, width_t width) {
|
|
return value & ((1ull << (8 * static_cast<uint32_t>(width))) - 1);
|
|
}
|
|
|
|
/**
|
|
* @brief Specialization of zero_truncate for uint64_t
|
|
* @param value The 64-bit input value to truncate
|
|
* @param width The target width to truncate to
|
|
* @return The truncated 64-bit value with upper bits zeroed
|
|
*/
|
|
template <>
|
|
constexpr uint64_t zero_truncate<uint64_t>(uint64_t value, width_t width) {
|
|
return value & ((1ull << (8 * static_cast<uint64_t>(width))) - 1);
|
|
}
|
|
|
|
/**
|
|
* @brief Sign-extends a value to the full width of the type
|
|
* @tparam WORD_T The word type (uint32_t or uint64_t)
|
|
* @param value The input value to sign-extend
|
|
* @param width The original width of the input value
|
|
* @return The sign-extended value
|
|
*/
|
|
template <typename WORD_T>
|
|
constexpr WORD_T sign_extend(WORD_T value, width_t width);
|
|
|
|
/**
|
|
* @brief Specialization of sign_extend for uint32_t
|
|
* @param value The 32-bit input value to sign-extend
|
|
* @param width The original width of the input value
|
|
* @return The sign-extended 32-bit value
|
|
*/
|
|
template <>
|
|
constexpr uint32_t sign_extend<uint32_t>(uint32_t value, width_t width) {
|
|
switch (width) {
|
|
case width_t::byte:
|
|
return uint32_t(int32_t(int8_t(value)));
|
|
case width_t::half:
|
|
return uint32_t(int32_t(int16_t(value)));
|
|
default:
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Specialization of sign_extend for uint64_t
|
|
* @param value The 64-bit input value to sign-extend
|
|
* @param width The original width of the input value
|
|
* @return The sign-extended 64-bit value
|
|
*/
|
|
template <>
|
|
constexpr uint64_t sign_extend<uint64_t>(uint64_t value, width_t width) {
|
|
switch (width) {
|
|
case width_t::byte:
|
|
return uint64_t(int64_t(int8_t(value)));
|
|
case width_t::half:
|
|
return uint64_t(int64_t(int16_t(value)));
|
|
case width_t::word:
|
|
return uint64_t(int64_t(int32_t(value)));
|
|
default:
|
|
return value;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
namespace std {
|
|
|
|
/**
|
|
* @brief Converts a width_t enum value to its string representation
|
|
* @param width The width enum value to convert
|
|
* @return String representation of the width
|
|
*/
|
|
inline string to_string(libvio::width_t width) noexcept {
|
|
switch (width) {
|
|
case libvio::width_t::byte: return "byte";
|
|
case libvio::width_t::half: return "half";
|
|
case libvio::width_t::word: return "word";
|
|
case libvio::width_t::dword: return "dword";
|
|
default: return "unknown";
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|