diff --git a/cppreg_Defines.h b/cppreg_Defines.h index f71d301..acd375e 100644 --- a/cppreg_Defines.h +++ b/cppreg_Defines.h @@ -28,13 +28,23 @@ namespace cppreg { using Address_t = std::uintptr_t; - //! Type alias for register and field widths. + //! Enumeration type for register size in bits. /** - * This limit the implementation to a maximum size of 256 bits for any - * register or field. - * This corresponds to the number of bits in the a register or field. + * This is used to enforce the supported register sizes. */ - using Width_t = std::uint8_t; + enum class RegBitSize { + b8, //!< 8-bit register. + b16, //!< 16-bit register. + b32 //!< 32-bit register. + }; + +// //! Type alias for register and field widths. +// /** +// * This limit the implementation to a maximum size of 256 bits for any +// * register or field. +// * This corresponds to the number of bits in the a register or field. +// */ + using FieldWidth_t = std::uint8_t; //! Type alias for register and field offsets. @@ -44,7 +54,7 @@ namespace cppreg { * Given that we consider 32 bits address space and 32 bits register this * should be enough. */ - using Offset_t = std::uint8_t; + using FieldOffset_t = std::uint8_t; //! Shorthand for max value as a mask. diff --git a/policies/AccessPolicy.h b/policies/AccessPolicy.h index 3fcb3b5..879d2a8 100644 --- a/policies/AccessPolicy.h +++ b/policies/AccessPolicy.h @@ -41,7 +41,7 @@ namespace cppreg { * The mask and offset are used to define a specific field within the * register. */ - template + template struct RegisterRead { //! Boolean flag for trivial implementation. @@ -94,7 +94,7 @@ namespace cppreg { * This write implementation is used only when the value to be written is * not a constant expression. */ - template + template struct RegisterWrite { //! Boolean flag for trivial implementation. @@ -152,7 +152,9 @@ namespace cppreg { * This write implementation is used only when the value to be written is * a constant expression. */ - template + template < + typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value + > struct RegisterWriteConstant { //! Boolean flag for trivial implementation. @@ -204,7 +206,7 @@ namespace cppreg { * @param mmio_device Pointer to register mapped memory. * @return The value at the field location. */ - template + template inline static T read(const MMIO_t& mmio_device) noexcept { return RegisterRead::read(mmio_device); }; @@ -224,7 +226,7 @@ namespace cppreg { * @param mmio_device Pointer to register mapped memory. * @param value Value to be written at the field location. */ - template + template inline static void write(MMIO_t& mmio_device, const T value) noexcept { RegisterWrite::write(mmio_device, value); @@ -239,7 +241,9 @@ namespace cppreg { * @tparam value Value to be written at the field location. * @param mmio_device Pointer to register mapped memory. */ - template + template < + typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value + > inline static void write(MMIO_t& mmio_device) noexcept { RegisterWriteConstant ::write(mmio_device); @@ -300,7 +304,7 @@ namespace cppreg { * @param mmio_device Pointer to register mapped memory. * @param value Value to be written at the field location. */ - template + template inline static void write(MMIO_t& mmio_device, const T value) noexcept { @@ -319,7 +323,9 @@ namespace cppreg { * @tparam value Value to be written at the field location. * @param mmio_device Pointer to register mapped memory. */ - template + template < + typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value + > inline static void write(MMIO_t& mmio_device) noexcept { // For write-only fields we can only write to the whole register. diff --git a/register/Field.h b/register/Field.h index 0c283b9..d27db10 100644 --- a/register/Field.h +++ b/register/Field.h @@ -39,8 +39,8 @@ namespace cppreg { */ template < typename BaseRegister, - Width_t FieldWidth, - Offset_t FieldOffset, + FieldWidth_t field_width, + FieldOffset_t field_offset, typename AccessPolicy > struct Field { @@ -58,10 +58,10 @@ namespace cppreg { using policy = AccessPolicy; //! Field width. - constexpr static const Width_t width = FieldWidth; + constexpr static const FieldWidth_t width = field_width; //! Field offset. - constexpr static const Offset_t offset = FieldOffset; + constexpr static const FieldOffset_t offset = field_offset; //! Field mask. constexpr static const type mask = make_shifted_mask(width, @@ -80,7 +80,7 @@ namespace cppreg { */ template struct check_overflow : internals::check_overflow< - parent_register::size, + type, value, (mask >> offset) > {}; @@ -226,7 +226,7 @@ namespace cppreg { "field width is larger than parent register size"); static_assert(parent_register::size >= width + offset, "offset + width is larger than parent register size"); - static_assert(FieldWidth != 0u, + static_assert(width != 0u, "defining a Field type of width 0u is not allowed"); }; diff --git a/register/Mask.h b/register/Mask.h index d29fb7e..36dd140 100644 --- a/register/Mask.h +++ b/register/Mask.h @@ -28,12 +28,12 @@ namespace cppreg { * @return The mask value. */ template - constexpr Mask_t make_mask(const Width_t width) noexcept { + constexpr Mask_t make_mask(const FieldWidth_t width) noexcept { return width == 0 ? 0u : static_cast( - (make_mask(Width_t(width - 1)) << 1) | 1 + (make_mask(FieldWidth_t(width - 1)) << 1) | 1 ); }; @@ -46,8 +46,8 @@ namespace cppreg { * @return The mask value. */ template - constexpr Mask_t make_shifted_mask(const Width_t width, - const Offset_t offset) noexcept { + constexpr Mask_t make_shifted_mask(const FieldWidth_t width, + const FieldOffset_t offset) noexcept { return static_cast(make_mask(width) << offset); }; diff --git a/register/MergeWrite.h b/register/MergeWrite.h index 93963c6..e5f530f 100644 --- a/register/MergeWrite.h +++ b/register/MergeWrite.h @@ -46,7 +46,7 @@ namespace cppreg { template < typename Register, typename Register::type mask, - Offset_t offset, + FieldOffset_t offset, typename Register::type value > class MergeWrite_tmpl { @@ -130,7 +130,7 @@ namespace cppreg { inline typename std::enable_if< (internals::check_overflow< - Register::size, new_value, (F::mask >> F::offset) + typename Register::type, new_value, (F::mask >> F::offset) >::value), T >::type&& diff --git a/register/Overflow.h b/register/Overflow.h index b5ba809..bbd5684 100644 --- a/register/Overflow.h +++ b/register/Overflow.h @@ -21,7 +21,7 @@ namespace internals { //! Overflow check implementation. /** - * @tparam W Width of the register or field type. + * @tparam T Data type. * @tparam value Value to check. * @tparam limit Overflow limit value. * @@ -30,9 +30,9 @@ namespace internals { * There is overflow if value if strictly larger than limit. */ template < - Width_t W, - typename RegisterType::type value, - typename RegisterType::type limit + typename T, + T value, + T limit > struct check_overflow : std::integral_constant {}; diff --git a/register/Register.h b/register/Register.h index b5486fb..3df39b9 100644 --- a/register/Register.h +++ b/register/Register.h @@ -23,8 +23,8 @@ namespace cppreg { //! Register data structure. /** - * @tparam RegAddress Register address. - * @tparam RegWidth Register total width (i.e., size). + * @tparam reg_address Register address. + * @tparam reg_size Register size enum value. * @tparam ResetValue Register reset value (0x0 if unknown). * @tparam UseShadow shadow Boolean flag to enable shadow value. * @@ -35,30 +35,31 @@ namespace cppreg { * create custom types. */ template < - Address_t RegAddress, - Width_t RegWidth, - typename RegisterType::type ResetValue = 0x0, - bool UseShadow = false + Address_t reg_address, + RegBitSize reg_size, + typename TypeTraits::type reset_value = 0x0, + bool use_shadow = false > struct Register { //! Register base type. - using type = typename RegisterType::type; + using type = typename TypeTraits::type; //! MMIO pointer type. using MMIO_t = volatile type; - //! Register base address. - constexpr static const Address_t base_address = RegAddress; + //! Boolean flag for shadow value management. + using shadow = Shadow; - //! Register total width. - constexpr static const Width_t size = RegWidth; + //! Register base address. + constexpr static const Address_t base_address = reg_address; + + //! Register size in bits. + constexpr static const std::uint8_t size = + TypeTraits::bit_size; //! Register reset value. - constexpr static const type reset = ResetValue; - - //! Boolean flag for shadow value management. - using shadow = Shadow; + constexpr static const type reset = reset_value; //! Memory modifier. /** @@ -109,7 +110,7 @@ namespace cppreg { inline static typename std::enable_if< internals::check_overflow< - size, value, (F::mask >> F::offset) + type, value, (F::mask >> F::offset) >::value, T >::type&& @@ -118,8 +119,8 @@ namespace cppreg { }; // Sanity check. - static_assert(RegWidth != 0u, - "defining a Register type of width 0u is not allowed"); + static_assert(size != 0u, + "defining a Register type of zero size is not allowed"); }; diff --git a/register/RegisterPack.h b/register/RegisterPack.h index 4a16dd4..6325140 100644 --- a/register/RegisterPack.h +++ b/register/RegisterPack.h @@ -24,20 +24,20 @@ namespace internals { //! Memory map implementation. /** - * @tparam Address Memory base address. - * @tparam N Memory size in bytes. - * @tparam W Width in bits of the memory "elements". + * @tparam address Memory base address. + * @tparam n Memory size in bytes. + * @tparam reg_size Register bit size for the array elements. * * This structure is used to map an array structure onto a memory region. * The width parameter will correspond to the register size. */ - template + template struct memory_map { //! Array type. using mem_array_t = std::array< - volatile typename RegisterType::type, - N / sizeof(typename RegisterType::type) + volatile typename TypeTraits::type, + n / sizeof(typename TypeTraits::type) >; //! Static reference to memory array. @@ -49,24 +49,25 @@ namespace internals { }; //! Memory array reference definition. - template - typename memory_map::mem_array_t& - memory_map::array = *( - reinterpret_cast::mem_array_t*>( - Address + template + typename memory_map::mem_array_t& + memory_map::array = *( + reinterpret_cast + ::mem_array_t*>( + address ) ); //! is_aligned implementation. /** - * @tparam Address Address to be checked for alignment. + * @tparam address Address to be checked for alignment. * @tparam alignment Alignment constraint. */ - template + template struct is_aligned : std::integral_constant< bool, - (Address & (alignment - 1)) == 0 + (address & (alignment - 1)) == 0 > { }; @@ -76,19 +77,19 @@ namespace internals { //! Register pack base implementation. /** - * @tparam PackBase Pack base address. - * @tparam PackByteSize Pack size in bytes. + * @tparam base_address Pack base address. + * @tparam pack_byte_size Pack size in bytes. */ template < - Address_t PackBase, - std::uint32_t PackByteSize + Address_t base_address, + std::uint32_t pack_byte_size > struct RegisterPack { //! Base address. - constexpr static const Address_t pack_base = PackBase; + constexpr static const Address_t pack_base = base_address; //! Pack size in bytes. - constexpr static const std::uint32_t size_in_bytes = PackByteSize; + constexpr static const std::uint32_t size_in_bytes = pack_byte_size; }; @@ -106,32 +107,32 @@ namespace internals { */ template < typename RegisterPack, - std::uint32_t BitOffset, - Width_t RegWidth, - typename RegisterType::type ResetValue = 0x0, - bool UseShadow = false + std::uint32_t bit_offset, + RegBitSize reg_size, + typename TypeTraits::type reset_value = 0x0, + bool use_shadow = false > struct PackedRegister : Register< - RegisterPack::pack_base + (BitOffset / 8u), - RegWidth, - ResetValue, - UseShadow + RegisterPack::pack_base + (bit_offset / 8u), + reg_size, + reset_value, + use_shadow > { //! Register type. using base_reg = Register< - RegisterPack::pack_base + (BitOffset / 8u), - RegWidth, - ResetValue, - UseShadow + RegisterPack::pack_base + (bit_offset / 8u), + reg_size, + reset_value, + use_shadow >; //! Memory map type. using mem_map_t = internals::memory_map< RegisterPack::pack_base, RegisterPack::size_in_bytes, - RegWidth + reg_size >; //! Memory modifier. @@ -139,7 +140,8 @@ namespace internals { * @return A reference to the writable register memory. */ static typename base_reg::MMIO_t& rw_mem_device() { - return mem_map_t::array[BitOffset / RegWidth]; + return mem_map_t::array[bit_offset + / TypeTraits::bit_size]; }; //! Memory accessor. @@ -147,22 +149,26 @@ namespace internals { * @return A reference to the read-only register memory. */ static const typename base_reg::MMIO_t& ro_mem_device() { - return mem_map_t::array[BitOffset / RegWidth]; + return mem_map_t::array[bit_offset + / TypeTraits::bit_size]; }; // Safety check to detect if are overflowing the pack. - static_assert((BitOffset / 8u) <= RegisterPack::size_in_bytes, + static_assert((bit_offset / 8u) <= RegisterPack::size_in_bytes, "packed register is overflowing the pack"); // A packed register of width N bits requires: // - the pack address to be N-bits aligned (N/8 aligned), // - the pack address with offset to be N-bits aligned (N/8 aligned). static_assert( - internals::is_aligned - ::value + internals::is_aligned< + RegisterPack::pack_base, + TypeTraits::byte_size + >::value && internals::is_aligned< - RegisterPack::pack_base + (BitOffset / 8), (RegWidth / 8) + RegisterPack::pack_base + (bit_offset / 8), + TypeTraits::byte_size >::value, "register is mis-aligned in the pack" ); diff --git a/register/Traits.h b/register/Traits.h index 7196d03..20870b5 100644 --- a/register/Traits.h +++ b/register/Traits.h @@ -19,20 +19,50 @@ namespace cppreg { - //! Register data type default implementation. - /** - * @tparam Size Register size. - * - * This will fail to compile if the register size is not implemented. - */ - template - struct RegisterType; +// //! Register data type default implementation. +// /** +// * @tparam Size Register size. +// * +// * This will fail to compile if the register size is not implemented. +// */ +// template +// struct RegisterType; +// +// //!@{ Specializations based on register size. +// template <> struct RegisterType<8u> { using type = std::uint8_t; }; +// template <> struct RegisterType<16u> { using type = std::uint16_t; }; +// template <> struct RegisterType<32u> { using type = std::uint32_t; }; +// //!@} - //!@{ Specializations based on register size. - template <> struct RegisterType<8u> { using type = std::uint8_t; }; - template <> struct RegisterType<16u> { using type = std::uint16_t; }; - template <> struct RegisterType<32u> { using type = std::uint32_t; }; - //!@} + + //! Register type traits based on size. + /** + * @tparam S Register size in bits. + */ + template + struct TypeTraits; + + template <> struct TypeTraits { + using type = std::uint8_t; + constexpr static const std::uint8_t bit_size = 8u; + constexpr static const std::uint8_t byte_size = 1u; + constexpr static const std::uint8_t max_field_width = 8u; + constexpr static const std::uint8_t max_field_offset = 8u; + }; + template <> struct TypeTraits { + using type = std::uint16_t; + constexpr static const std::uint8_t bit_size = 16u; + constexpr static const std::uint8_t byte_size = 2u; + constexpr static const std::uint8_t max_field_width = 16u; + constexpr static const std::uint8_t max_field_offset = 16u; + }; + template <> struct TypeTraits { + using type = std::uint32_t; + constexpr static const std::uint8_t bit_size = 32u; + constexpr static const std::uint8_t byte_size = 4u; + constexpr static const std::uint8_t max_field_width = 32u; + constexpr static const std::uint8_t max_field_offset = 32u; + }; } diff --git a/single/cppreg-all.h b/single/cppreg-all.h index eb3e2a7..5deaf4a 100644 --- a/single/cppreg-all.h +++ b/single/cppreg-all.h @@ -15,8 +15,13 @@ #define CPPREG_CPPREG_DEFINES_H namespace cppreg { using Address_t = std::uintptr_t; - using Width_t = std::uint8_t; - using Offset_t = std::uint8_t; + enum class RegBitSize { + b8, + b16, + b32 + }; + using FieldWidth_t = std::uint8_t; + using FieldOffset_t = std::uint8_t; template struct type_mask { constexpr static const T value = std::numeric_limits::max(); @@ -28,7 +33,7 @@ namespace cppreg { #ifndef CPPREG_ACCESSPOLICY_H #define CPPREG_ACCESSPOLICY_H namespace cppreg { - template + template struct RegisterRead { constexpr static const bool is_trivial = (mask == type_mask::value) && (offset == 0u); @@ -47,7 +52,7 @@ namespace cppreg { return static_cast(mmio_device); }; }; - template + template struct RegisterWrite { constexpr static const bool is_trivial = (mask == type_mask::value) && (offset == 0u); @@ -70,7 +75,9 @@ namespace cppreg { mmio_device = value; }; }; - template + template < + typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value + > struct RegisterWriteConstant { constexpr static const bool is_trivial = (mask == type_mask::value) && (offset == 0u); @@ -92,18 +99,20 @@ namespace cppreg { }; }; struct read_only { - template + template inline static T read(const MMIO_t& mmio_device) noexcept { return RegisterRead::read(mmio_device); }; }; struct read_write : read_only { - template + template inline static void write(MMIO_t& mmio_device, const T value) noexcept { RegisterWrite::write(mmio_device, value); }; - template + template < + typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value + > inline static void write(MMIO_t& mmio_device) noexcept { RegisterWriteConstant ::write(mmio_device); @@ -127,14 +136,16 @@ namespace cppreg { }; }; struct write_only { - template + template inline static void write(MMIO_t& mmio_device, const T value) noexcept { RegisterWrite::value, 0u>::write( mmio_device, ((value << offset) & mask) ); }; - template + template < + typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value + > inline static void write(MMIO_t& mmio_device) noexcept { RegisterWriteConstant< MMIO_t, T, type_mask::value, 0u, ((value << offset) & mask) @@ -149,11 +160,29 @@ namespace cppreg { #ifndef CPPREG_TRAITS_H #define CPPREG_TRAITS_H namespace cppreg { - template - struct RegisterType; - template <> struct RegisterType<8u> { using type = std::uint8_t; }; - template <> struct RegisterType<16u> { using type = std::uint16_t; }; - template <> struct RegisterType<32u> { using type = std::uint32_t; }; + template + struct TypeTraits; + template <> struct TypeTraits { + using type = std::uint8_t; + constexpr static const std::uint8_t bit_size = 8u; + constexpr static const std::uint8_t byte_size = 1u; + constexpr static const std::uint8_t max_field_width = 8u; + constexpr static const std::uint8_t max_field_offset = 8u; + }; + template <> struct TypeTraits { + using type = std::uint16_t; + constexpr static const std::uint8_t bit_size = 16u; + constexpr static const std::uint8_t byte_size = 2u; + constexpr static const std::uint8_t max_field_width = 16u; + constexpr static const std::uint8_t max_field_offset = 16u; + }; + template <> struct TypeTraits { + using type = std::uint32_t; + constexpr static const std::uint8_t bit_size = 32u; + constexpr static const std::uint8_t byte_size = 4u; + constexpr static const std::uint8_t max_field_width = 32u; + constexpr static const std::uint8_t max_field_offset = 32u; + }; } #endif @@ -163,9 +192,9 @@ namespace cppreg { namespace cppreg { namespace internals { template < - Width_t W, - typename RegisterType::type value, - typename RegisterType::type limit + typename T, + T value, + T limit > struct check_overflow : std::integral_constant {}; } @@ -177,17 +206,17 @@ namespace internals { #define CPPREG_MASK_H namespace cppreg { template - constexpr Mask_t make_mask(const Width_t width) noexcept { + constexpr Mask_t make_mask(const FieldWidth_t width) noexcept { return width == 0 ? 0u : static_cast( - (make_mask(Width_t(width - 1)) << 1) | 1 + (make_mask(FieldWidth_t(width - 1)) << 1) | 1 ); }; template - constexpr Mask_t make_shifted_mask(const Width_t width, - const Offset_t offset) noexcept { + constexpr Mask_t make_shifted_mask(const FieldWidth_t width, + const FieldOffset_t offset) noexcept { return static_cast(make_mask(width) << offset); }; } @@ -215,7 +244,7 @@ namespace cppreg { template < typename Register, typename Register::type mask, - Offset_t offset, + FieldOffset_t offset, typename Register::type value > class MergeWrite_tmpl { public: @@ -259,7 +288,7 @@ namespace cppreg { inline typename std::enable_if< (internals::check_overflow< - Register::size, new_value, (F::mask >> F::offset) + typename Register::type, new_value, (F::mask >> F::offset) >::value), T >::type&& @@ -330,18 +359,19 @@ namespace cppreg { #define CPPREG_REGISTER_H namespace cppreg { template < - Address_t RegAddress, - Width_t RegWidth, - typename RegisterType::type ResetValue = 0x0, - bool UseShadow = false + Address_t reg_address, + RegBitSize reg_size, + typename TypeTraits::type reset_value = 0x0, + bool use_shadow = false > struct Register { - using type = typename RegisterType::type; + using type = typename TypeTraits::type; using MMIO_t = volatile type; - constexpr static const Address_t base_address = RegAddress; - constexpr static const Width_t size = RegWidth; - constexpr static const type reset = ResetValue; - using shadow = Shadow; + using shadow = Shadow; + constexpr static const Address_t base_address = reg_address; + constexpr static const std::uint8_t size = + TypeTraits::bit_size; + constexpr static const type reset = reset_value; static MMIO_t& rw_mem_device() { return *(reinterpret_cast(base_address)); }; @@ -368,15 +398,15 @@ namespace cppreg { inline static typename std::enable_if< internals::check_overflow< - size, value, (F::mask >> F::offset) + type, value, (F::mask >> F::offset) >::value, T >::type&& merge_write() noexcept { return std::move(T::make()); }; - static_assert(RegWidth != 0u, - "defining a Register type of width 0u is not allowed"); + static_assert(size != 0u, + "defining a Register type of zero size is not allowed"); }; } #endif @@ -385,67 +415,84 @@ namespace cppreg { #ifndef CPPREG_REGISTERPACK_H #define CPPREG_REGISTERPACK_H namespace cppreg { - template +namespace internals { + template struct memory_map { using mem_array_t = std::array< - volatile typename RegisterType::type, - N / sizeof(typename RegisterType::type) + volatile typename TypeTraits::type, + n / sizeof(typename TypeTraits::type) >; static mem_array_t& array; }; - template - typename memory_map::mem_array_t& - memory_map::array = *( - reinterpret_cast::mem_array_t*>( - Address + template + typename memory_map::mem_array_t& + memory_map::array = *( + reinterpret_cast + ::mem_array_t*>( + address ) ); + template + struct is_aligned : std::integral_constant< + bool, + (address & (alignment - 1)) == 0 + > { + }; +} template < - Address_t PackBase, - std::uint32_t PackByteSize + Address_t base_address, + std::uint32_t pack_byte_size > struct RegisterPack { - constexpr static const Address_t pack_base = PackBase; - constexpr static const std::uint32_t size_in_bytes = PackByteSize; + constexpr static const Address_t pack_base = base_address; + constexpr static const std::uint32_t size_in_bytes = pack_byte_size; }; template < typename RegisterPack, - std::uint32_t BitOffset, - Width_t RegWidth, - typename RegisterType::type ResetValue = 0x0, - bool UseShadow = false + std::uint32_t bit_offset, + RegBitSize reg_size, + typename TypeTraits::type reset_value = 0x0, + bool use_shadow = false > struct PackedRegister : Register< - RegisterPack::pack_base + (BitOffset / 8u), - RegWidth, - ResetValue, - UseShadow + RegisterPack::pack_base + (bit_offset / 8u), + reg_size, + reset_value, + use_shadow > { using base_reg = Register< - RegisterPack::pack_base + (BitOffset / 8u), - RegWidth, - ResetValue, - UseShadow + RegisterPack::pack_base + (bit_offset / 8u), + reg_size, + reset_value, + use_shadow >; - using mem_map_t = memory_map< + using mem_map_t = internals::memory_map< RegisterPack::pack_base, RegisterPack::size_in_bytes, - RegWidth - >; + reg_size + >; static typename base_reg::MMIO_t& rw_mem_device() { - return mem_map_t::array[BitOffset / RegWidth]; + return mem_map_t::array[bit_offset + / TypeTraits::bit_size]; }; static const typename base_reg::MMIO_t& ro_mem_device() { - return mem_map_t::array[BitOffset / RegWidth]; + return mem_map_t::array[bit_offset + / TypeTraits::bit_size]; }; - static_assert((BitOffset / 8u) <= RegisterPack::size_in_bytes, + static_assert((bit_offset / 8u) <= RegisterPack::size_in_bytes, "packed register is overflowing the pack"); - static_assert(( - (BitOffset % RegWidth) == 0 - && - (RegisterPack::pack_base % (RegWidth / 8u) == 0) - ), - "register mis-alignment with respect to pack base"); + static_assert( + internals::is_aligned< + RegisterPack::pack_base, + TypeTraits::byte_size + >::value + && + internals::is_aligned< + RegisterPack::pack_base + (bit_offset / 8), + TypeTraits::byte_size + >::value, + "register is mis-aligned in the pack" + ); }; template struct PackIndexing { @@ -493,8 +540,8 @@ namespace cppreg { namespace cppreg { template < typename BaseRegister, - Width_t FieldWidth, - Offset_t FieldOffset, + FieldWidth_t field_width, + FieldOffset_t field_offset, typename AccessPolicy > struct Field { @@ -502,15 +549,15 @@ namespace cppreg { using type = typename parent_register::type; using MMIO_t = typename parent_register::MMIO_t; using policy = AccessPolicy; - constexpr static const Width_t width = FieldWidth; - constexpr static const Offset_t offset = FieldOffset; + constexpr static const FieldWidth_t width = field_width; + constexpr static const FieldOffset_t offset = field_offset; constexpr static const type mask = make_shifted_mask(width, offset); constexpr static const bool has_shadow = parent_register::shadow::value; template struct check_overflow : internals::check_overflow< - parent_register::size, + type, value, (mask >> offset) > {}; @@ -585,7 +632,7 @@ namespace cppreg { "field width is larger than parent register size"); static_assert(parent_register::size >= width + offset, "offset + width is larger than parent register size"); - static_assert(FieldWidth != 0u, + static_assert(width != 0u, "defining a Field type of width 0u is not allowed"); }; }