register framework: read bitfields to fitting uint

* Replaces bool access types with uint8_t access types
* Ensures, that the framework always uses the smalles possible uint type
  for the return value wherever a bitfield is read and returned to the user.

Ref #4924
This commit is contained in:
Martin Stein 2023-06-07 19:14:04 +02:00 committed by Norman Feske
parent 79e262921e
commit c907e44a02
3 changed files with 15 additions and 19 deletions

View File

@ -33,8 +33,7 @@ namespace Genode { namespace Trait {
template <unsigned _WIDTH>
struct Raise_to_uint_width
{
enum { WIDTH = _WIDTH < 2 ? 1 :
_WIDTH < 9 ? 8 :
enum { WIDTH = _WIDTH < 9 ? 8 :
_WIDTH < 17 ? 16 :
_WIDTH < 33 ? 32 :
_WIDTH < 65 ? 64 : 0, };
@ -45,10 +44,10 @@ namespace Genode { namespace Trait {
*/
template <unsigned long _WIDTH> struct Uint_width;
template <> struct Uint_width<1>
template <> struct Uint_width<8>
{
typedef bool Type;
enum { WIDTH_LOG2 = 0 };
typedef uint8_t Type;
enum { WIDTH_LOG2 = 3 };
/**
* Access widths wich are dividers to the compound type width
@ -56,12 +55,6 @@ namespace Genode { namespace Trait {
template <unsigned long _DIVISOR_WIDTH> struct Divisor;
};
template <> struct Uint_width<8> : Uint_width<1>
{
typedef uint8_t Type;
enum { WIDTH_LOG2 = 3 };
};
template <> struct Uint_width<16> : Uint_width<8>
{
typedef uint16_t Type;
@ -80,7 +73,7 @@ namespace Genode { namespace Trait {
enum { WIDTH_LOG2 = 6 };
};
template <> struct Uint_width<1>::Divisor<1> { enum { WIDTH_LOG2 = 0 }; };
template <> struct Uint_width<8>::Divisor<1> { enum { WIDTH_LOG2 = 0 }; };
template <> struct Uint_width<8>::Divisor<2> { enum { WIDTH_LOG2 = 1 }; };
template <> struct Uint_width<8>::Divisor<4> { enum { WIDTH_LOG2 = 2 }; };
template <> struct Uint_width<8>::Divisor<8> { enum { WIDTH_LOG2 = 3 }; };
@ -93,7 +86,6 @@ namespace Genode { namespace Trait {
*/
template <typename _TYPE> struct Uint_type;
template <> struct Uint_type<bool> : Uint_width<1> { };
template <> struct Uint_type<uint8_t> : Uint_width<8> { };
template <> struct Uint_type<uint16_t> : Uint_width<16> { };
template <> struct Uint_type<uint32_t> : Uint_width<32> { };
@ -141,6 +133,10 @@ struct Genode::Register
static constexpr size_t WIDTH = _WIDTH;
static constexpr size_t BITFIELD_WIDTH = WIDTH;
typedef typename
Trait::Uint_width<Trait::Raise_to_uint_width<WIDTH>::WIDTH>::Type
bitfield_t;
/**
* Get an unshifted mask of this field
*/
@ -190,8 +186,8 @@ struct Genode::Register
/**
* Get value of this bitfield from 'reg'
*/
static inline access_t get(access_t const reg)
{ return (reg >> SHIFT) & mask(); }
static inline bitfield_t get(access_t const reg)
{ return (bitfield_t)((reg >> SHIFT) & mask()); }
/**
* Get register value 'reg' with this bitfield set to zero

View File

@ -418,7 +418,7 @@ class Genode::Register_set : Noncopyable
* Read the bitfield 'T' of a register
*/
template <typename T>
inline typename T::Bitfield_base::Compound_reg::access_t
inline typename T::Bitfield_base::bitfield_t
read() const
{
typedef typename T::Bitfield_base Bitfield;
@ -553,7 +553,7 @@ class Genode::Register_set : Noncopyable
* \param index index of the targeted item
*/
template <typename T>
inline typename T::Array_bitfield_base::Compound_array::access_t
inline typename T::Array_bitfield_base::bitfield_t
read(unsigned long const index) const
{
typedef typename T::Array_bitfield_base Bitfield;

View File

@ -71,8 +71,8 @@ struct Test_mmio : public Mmio
struct Bits_4 : Bitfield<60,4> { };
struct Bits_5 : Bitfield<0,64> { };
struct Bits_6 : Bitfield<16,64> { };
struct Bits_7 : Bitfield<12,90> { };
struct Bits_8 : Bitfield<0,72> { };
struct Bits_7 : Bitfield<12,64> { };
struct Bits_8 : Bitfield<0,64> { };
};
struct Bitset_64_0 : Bitset_2<Reg_64::Bits_0, Reg_64::Bits_1> { };
struct Bitset_64_1 : Bitset_3<Reg_64::Bits_4, Reg_64::Bits_3, Reg_64::Bits_2> { };