mirror of https://github.com/sendyne/cppreg.git
BUG FIX IN MERGER WRITE IMPLEMENTATION FOR NON CONSTANT VALUES
* For write-only registers the merge write implementation for non-constant values was properly updating the cache value. * Unnecessary `inline` have been removed.
This commit is contained in:
parent
e59bc356c8
commit
2e0d502674
|
@ -58,7 +58,7 @@ namespace cppreg {
|
|||
* @return The content of the register field.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static T read(
|
||||
static T read(
|
||||
const MMIO_t& mmio_device,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
|
@ -71,7 +71,7 @@ namespace cppreg {
|
|||
* @return The content of the register field.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static T read(
|
||||
static T read(
|
||||
const MMIO_t& mmio_device,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
|
@ -111,7 +111,7 @@ namespace cppreg {
|
|||
* @param value Value to be written to the register field.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
T value,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
|
@ -127,7 +127,7 @@ namespace cppreg {
|
|||
* @param value Value to be written to the register field.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
T value,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
|
@ -170,7 +170,7 @@ namespace cppreg {
|
|||
* @param mmio_device Pointer to the register memory device.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
|
@ -184,7 +184,7 @@ namespace cppreg {
|
|||
* @param mmio_device Pointer to the register memory device.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
|
@ -207,7 +207,7 @@ namespace cppreg {
|
|||
* @return The value at the field location.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static T read(const MMIO_t& mmio_device) noexcept {
|
||||
static T read(const MMIO_t& mmio_device) noexcept {
|
||||
return RegisterRead<MMIO_t, T, mask, offset>::read(mmio_device);
|
||||
};
|
||||
|
||||
|
@ -227,7 +227,7 @@ namespace cppreg {
|
|||
* @param value Value to be written at the field location.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static void write(MMIO_t& mmio_device,
|
||||
static void write(MMIO_t& mmio_device,
|
||||
const T value) noexcept {
|
||||
RegisterWrite<MMIO_t, T, mask, offset>::write(mmio_device, value);
|
||||
};
|
||||
|
@ -244,7 +244,7 @@ namespace cppreg {
|
|||
template <
|
||||
typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value
|
||||
>
|
||||
inline static void write(MMIO_t& mmio_device) noexcept {
|
||||
static void write(MMIO_t& mmio_device) noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, offset, value>
|
||||
::write(mmio_device);
|
||||
};
|
||||
|
@ -256,7 +256,7 @@ namespace cppreg {
|
|||
* @param mmio_device Pointer to register mapped memory.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void set(MMIO_t& mmio_device)
|
||||
static void set(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, 0u, mask>
|
||||
::write(mmio_device);
|
||||
|
@ -270,7 +270,7 @@ namespace cppreg {
|
|||
* @param mmio_device Pointer to register mapped memory.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void clear(MMIO_t& mmio_device)
|
||||
static void clear(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, 0u, ~mask>
|
||||
::write(mmio_device);
|
||||
|
@ -284,7 +284,7 @@ namespace cppreg {
|
|||
* @param mmio_device Pointer to register mapped memory.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void toggle(MMIO_t& mmio_device)
|
||||
static void toggle(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
mmio_device = static_cast<T>((mmio_device) ^ mask);
|
||||
};
|
||||
|
@ -305,8 +305,7 @@ namespace cppreg {
|
|||
* @param value Value to be written at the field location.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static void write(MMIO_t& mmio_device,
|
||||
const T value) noexcept {
|
||||
static void write(MMIO_t& mmio_device, const T value) noexcept {
|
||||
|
||||
// For write-only fields we can only write to the whole register.
|
||||
RegisterWrite<MMIO_t, T, type_mask<T>::value, 0u>::write(
|
||||
|
@ -326,7 +325,7 @@ namespace cppreg {
|
|||
template <
|
||||
typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value
|
||||
>
|
||||
inline static void write(MMIO_t& mmio_device) noexcept {
|
||||
static void write(MMIO_t& mmio_device) noexcept {
|
||||
|
||||
// For write-only fields we can only write to the whole register.
|
||||
RegisterWriteConstant<
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace cppreg {
|
|||
/**
|
||||
* @return Field value.
|
||||
*/
|
||||
inline static type read() noexcept {
|
||||
static type read() noexcept {
|
||||
return policy::template read<MMIO_t, type, mask, offset>(
|
||||
parent_register::ro_mem_device()
|
||||
);
|
||||
|
@ -100,7 +100,7 @@ namespace cppreg {
|
|||
* @param value Value to be written to the field.
|
||||
*/
|
||||
template <typename T = type>
|
||||
inline static void
|
||||
static void
|
||||
write(const typename std::enable_if<!has_shadow, T>::type value)
|
||||
noexcept {
|
||||
policy::template write<MMIO_t, type, mask, offset>(
|
||||
|
@ -114,7 +114,7 @@ namespace cppreg {
|
|||
* @param value Value to be written to the field.
|
||||
*/
|
||||
template <typename T = type>
|
||||
inline static void
|
||||
static void
|
||||
write(const typename std::enable_if<has_shadow, T>::type value)
|
||||
noexcept {
|
||||
|
||||
|
@ -140,14 +140,14 @@ namespace cppreg {
|
|||
* field and uses the constant write implementation.
|
||||
*/
|
||||
template <type value, typename T = void>
|
||||
inline static
|
||||
typename std::enable_if<
|
||||
!has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type
|
||||
write() noexcept {
|
||||
static void write(
|
||||
typename std::enable_if<
|
||||
!has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type* = nullptr
|
||||
) noexcept {
|
||||
policy::template write<MMIO_t, type, mask, offset, value>(
|
||||
parent_register::rw_mem_device()
|
||||
);
|
||||
|
@ -161,14 +161,14 @@ namespace cppreg {
|
|||
* field and uses the constant write implementation.
|
||||
*/
|
||||
template <type value, typename T = void>
|
||||
inline static
|
||||
typename std::enable_if<
|
||||
has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type
|
||||
write() noexcept {
|
||||
static void write(
|
||||
typename std::enable_if<
|
||||
has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type* = nullptr
|
||||
) noexcept {
|
||||
|
||||
// For this particular we simply forward to the non-constant
|
||||
// implementation because the shadow value needs to be updated.
|
||||
|
@ -180,7 +180,7 @@ namespace cppreg {
|
|||
/**
|
||||
* This method will set all bits in the field.
|
||||
*/
|
||||
inline static void set() noexcept {
|
||||
static void set() noexcept {
|
||||
policy::template
|
||||
set<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
|
@ -189,7 +189,7 @@ namespace cppreg {
|
|||
/**
|
||||
* This method will clear all bits in the field.
|
||||
*/
|
||||
inline static void clear() noexcept {
|
||||
static void clear() noexcept {
|
||||
policy::template
|
||||
clear<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
|
@ -198,7 +198,7 @@ namespace cppreg {
|
|||
/**
|
||||
* This method will toggle all bits in the field.
|
||||
*/
|
||||
inline static void toggle() noexcept {
|
||||
static void toggle() noexcept {
|
||||
policy::template
|
||||
toggle<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
|
@ -207,7 +207,7 @@ namespace cppreg {
|
|||
/**
|
||||
* @return `true` if all the bits are set to 1, `false` otherwise.
|
||||
*/
|
||||
inline static bool is_set() noexcept {
|
||||
static bool is_set() noexcept {
|
||||
return (Field::read() == (mask >> offset));
|
||||
};
|
||||
|
||||
|
@ -215,7 +215,7 @@ namespace cppreg {
|
|||
/**
|
||||
* @return `true` if all the bits are set to 0, `false` otherwise.
|
||||
*/
|
||||
inline static bool is_clear() noexcept {
|
||||
static bool is_clear() noexcept {
|
||||
return (Field::read() == 0u);
|
||||
};
|
||||
|
||||
|
|
|
@ -68,13 +68,13 @@ namespace cppreg {
|
|||
constexpr static const base_type _combined_mask = mask;
|
||||
|
||||
// Default constructor.
|
||||
MergeWrite_tmpl() {};
|
||||
MergeWrite_tmpl() = default;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//! Instantiation method.
|
||||
inline static MergeWrite_tmpl make() noexcept { return {}; };
|
||||
static MergeWrite_tmpl make() noexcept { return {}; };
|
||||
|
||||
//!@{ Non-copyable and non-moveable.
|
||||
MergeWrite_tmpl(const MergeWrite_tmpl&) = delete;
|
||||
|
@ -88,7 +88,7 @@ namespace cppreg {
|
|||
/**
|
||||
* This is where the write happens.
|
||||
*/
|
||||
inline void done() const && noexcept {
|
||||
void done() const && noexcept {
|
||||
|
||||
// Get memory pointer.
|
||||
typename Register::MMIO_t& mmio_device =
|
||||
|
@ -124,7 +124,6 @@ namespace cppreg {
|
|||
F::mask)
|
||||
>
|
||||
>
|
||||
inline
|
||||
typename std::enable_if<
|
||||
(internals::check_overflow<
|
||||
typename Register::type, new_value, (F::mask >> F::offset)
|
||||
|
@ -196,7 +195,7 @@ namespace cppreg {
|
|||
/**
|
||||
* This is where the write happens.
|
||||
*/
|
||||
inline void done() const && noexcept {
|
||||
void done() const && noexcept {
|
||||
|
||||
// Get memory pointer.
|
||||
typename Register::MMIO_t& mmio_device =
|
||||
|
@ -221,8 +220,8 @@ namespace cppreg {
|
|||
* @return A reference to the current merge write data.
|
||||
*/
|
||||
template <typename F>
|
||||
inline MergeWrite<Register, _combined_mask | F::mask> with
|
||||
(const base_type value) && noexcept {
|
||||
MergeWrite<Register, _combined_mask | F::mask>
|
||||
with(const base_type value) && noexcept {
|
||||
|
||||
// Check that the field belongs to the register.
|
||||
static_assert(std::is_same<
|
||||
|
@ -232,12 +231,8 @@ namespace cppreg {
|
|||
"field is not from the same register in merge_write");
|
||||
|
||||
// Update accumulated value.
|
||||
F::policy::template write<
|
||||
base_type,
|
||||
base_type,
|
||||
F::mask,
|
||||
F::offset
|
||||
>(_accumulated_value, value);
|
||||
_accumulated_value = (_accumulated_value & ~F::mask)
|
||||
| ((value << F::offset) & F::mask);
|
||||
|
||||
return
|
||||
std::move(
|
||||
|
@ -256,7 +251,8 @@ namespace cppreg {
|
|||
|
||||
// Private default constructor.
|
||||
constexpr MergeWrite() : _accumulated_value(0u) {};
|
||||
constexpr MergeWrite(const base_type v) : _accumulated_value(v) {};
|
||||
constexpr explicit MergeWrite(const base_type v) :
|
||||
_accumulated_value(v) {};
|
||||
|
||||
// Accumulated value.
|
||||
base_type _accumulated_value;
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace cppreg {
|
|||
* @return A merge write data structure to chain further writes.
|
||||
*/
|
||||
template <typename F>
|
||||
inline static MergeWrite<typename F::parent_register, F::mask>
|
||||
static MergeWrite<typename F::parent_register, F::mask>
|
||||
merge_write(const typename F::type value) noexcept {
|
||||
return
|
||||
MergeWrite<typename F::parent_register, F::mask>
|
||||
|
@ -107,7 +107,7 @@ namespace cppreg {
|
|||
value
|
||||
>
|
||||
>
|
||||
inline static
|
||||
static
|
||||
typename std::enable_if<
|
||||
internals::check_overflow<
|
||||
type, value, (F::mask >> F::offset)
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace cppreg {
|
|||
/**
|
||||
* @return A reference to the writable register memory.
|
||||
*/
|
||||
inline static typename base_reg::MMIO_t& rw_mem_device() noexcept {
|
||||
static typename base_reg::MMIO_t& rw_mem_device() noexcept {
|
||||
return mem_map_t::array[bit_offset
|
||||
/ TypeTraits<reg_size>::bit_size];
|
||||
};
|
||||
|
@ -92,7 +92,7 @@ namespace cppreg {
|
|||
/**
|
||||
* @return A reference to the read-only register memory.
|
||||
*/
|
||||
inline static const typename base_reg::MMIO_t& ro_mem_device() noexcept {
|
||||
static const typename base_reg::MMIO_t& ro_mem_device() noexcept {
|
||||
return mem_map_t::array[bit_offset
|
||||
/ TypeTraits<reg_size>::bit_size];
|
||||
};
|
||||
|
@ -166,7 +166,7 @@ namespace cppreg {
|
|||
* This will call Op for the range [start, end).
|
||||
*/
|
||||
template <typename Func>
|
||||
inline static void apply() noexcept {
|
||||
static void apply() noexcept {
|
||||
Func().template operator()<start>();
|
||||
if (start < end)
|
||||
for_loop<start + 1ul, end>::template apply<Func>();
|
||||
|
@ -184,7 +184,7 @@ namespace cppreg {
|
|||
* use lambda [](auto index) { index.value will be the loop index};
|
||||
*/
|
||||
template <typename Op>
|
||||
inline static void apply(Op&& f) noexcept {
|
||||
static void apply(Op&& f) noexcept {
|
||||
if (start < end) {
|
||||
f(std::integral_constant<std::size_t, start>{});
|
||||
for_loop<start + 1ul, end>::apply(std::forward<Op>(f));
|
||||
|
@ -196,10 +196,10 @@ namespace cppreg {
|
|||
template <std::size_t end>
|
||||
struct for_loop<end, end> {
|
||||
template <typename Func>
|
||||
inline static void apply() noexcept {};
|
||||
static void apply() noexcept {};
|
||||
#if __cplusplus >= 201402L
|
||||
template <typename Op>
|
||||
inline static void apply(Op&& f) noexcept {};
|
||||
static void apply(Op&& f) noexcept {};
|
||||
#endif // __cplusplus 201402L
|
||||
};
|
||||
|
||||
|
|
|
@ -109,14 +109,14 @@ namespace cppreg {
|
|||
constexpr static const bool is_trivial =
|
||||
(mask == type_mask<T>::value) && (offset == 0u);
|
||||
template <typename U = void>
|
||||
inline static T read(
|
||||
static T read(
|
||||
const MMIO_t& mmio_device,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
return static_cast<T>((mmio_device & mask) >> offset);
|
||||
};
|
||||
template <typename U = void>
|
||||
inline static T read(
|
||||
static T read(
|
||||
const MMIO_t& mmio_device,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
|
@ -128,7 +128,7 @@ namespace cppreg {
|
|||
constexpr static const bool is_trivial =
|
||||
(mask == type_mask<T>::value) && (offset == 0u);
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
T value,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
|
@ -138,7 +138,7 @@ namespace cppreg {
|
|||
);
|
||||
};
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
T value,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
|
@ -153,7 +153,7 @@ namespace cppreg {
|
|||
constexpr static const bool is_trivial =
|
||||
(mask == type_mask<T>::value) && (offset == 0u);
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
|
@ -162,7 +162,7 @@ namespace cppreg {
|
|||
);
|
||||
};
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
|
@ -171,45 +171,44 @@ namespace cppreg {
|
|||
};
|
||||
struct read_only {
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static T read(const MMIO_t& mmio_device) noexcept {
|
||||
static T read(const MMIO_t& mmio_device) noexcept {
|
||||
return RegisterRead<MMIO_t, T, mask, offset>::read(mmio_device);
|
||||
};
|
||||
};
|
||||
struct read_write : read_only {
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static void write(MMIO_t& mmio_device,
|
||||
static void write(MMIO_t& mmio_device,
|
||||
const T value) noexcept {
|
||||
RegisterWrite<MMIO_t, T, mask, offset>::write(mmio_device, value);
|
||||
};
|
||||
template <
|
||||
typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value
|
||||
>
|
||||
inline static void write(MMIO_t& mmio_device) noexcept {
|
||||
static void write(MMIO_t& mmio_device) noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, offset, value>
|
||||
::write(mmio_device);
|
||||
};
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void set(MMIO_t& mmio_device)
|
||||
static void set(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, 0u, mask>
|
||||
::write(mmio_device);
|
||||
};
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void clear(MMIO_t& mmio_device)
|
||||
static void clear(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, 0u, ~mask>
|
||||
::write(mmio_device);
|
||||
};
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void toggle(MMIO_t& mmio_device)
|
||||
static void toggle(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
mmio_device = static_cast<T>((mmio_device) ^ mask);
|
||||
};
|
||||
};
|
||||
struct write_only {
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static void write(MMIO_t& mmio_device,
|
||||
const T value) noexcept {
|
||||
static void write(MMIO_t& mmio_device, const T value) noexcept {
|
||||
RegisterWrite<MMIO_t, T, type_mask<T>::value, 0u>::write(
|
||||
mmio_device, ((value << offset) & mask)
|
||||
);
|
||||
|
@ -217,7 +216,7 @@ namespace cppreg {
|
|||
template <
|
||||
typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value
|
||||
>
|
||||
inline static void write(MMIO_t& mmio_device) noexcept {
|
||||
static void write(MMIO_t& mmio_device) noexcept {
|
||||
RegisterWriteConstant<
|
||||
MMIO_t, T, type_mask<T>::value, 0u, ((value << offset) & mask)
|
||||
>
|
||||
|
@ -281,15 +280,15 @@ namespace cppreg {
|
|||
constexpr static const base_type _accumulated_value =
|
||||
((value << offset) & mask);
|
||||
constexpr static const base_type _combined_mask = mask;
|
||||
MergeWrite_tmpl() {};
|
||||
MergeWrite_tmpl() = default;
|
||||
public:
|
||||
inline static MergeWrite_tmpl make() noexcept { return {}; };
|
||||
static MergeWrite_tmpl make() noexcept { return {}; };
|
||||
MergeWrite_tmpl(const MergeWrite_tmpl&) = delete;
|
||||
MergeWrite_tmpl& operator=(const MergeWrite_tmpl&) = delete;
|
||||
MergeWrite_tmpl& operator=(MergeWrite_tmpl&&) = delete;
|
||||
MergeWrite_tmpl operator=(MergeWrite_tmpl) = delete;
|
||||
MergeWrite_tmpl(MergeWrite_tmpl&&) = delete;
|
||||
inline void done() const && noexcept {
|
||||
void done() const && noexcept {
|
||||
typename Register::MMIO_t& mmio_device =
|
||||
Register::rw_mem_device();
|
||||
RegisterWriteConstant<
|
||||
|
@ -311,7 +310,6 @@ namespace cppreg {
|
|||
F::mask)
|
||||
>
|
||||
>
|
||||
inline
|
||||
typename std::enable_if<
|
||||
(internals::check_overflow<
|
||||
typename Register::type, new_value, (F::mask >> F::offset)
|
||||
|
@ -345,7 +343,7 @@ namespace cppreg {
|
|||
MergeWrite(const MergeWrite&) = delete;
|
||||
MergeWrite& operator=(const MergeWrite&) = delete;
|
||||
MergeWrite& operator=(MergeWrite&&) = delete;
|
||||
inline void done() const && noexcept {
|
||||
void done() const && noexcept {
|
||||
typename Register::MMIO_t& mmio_device =
|
||||
Register::rw_mem_device();
|
||||
RegisterWrite<
|
||||
|
@ -356,19 +354,15 @@ namespace cppreg {
|
|||
>::write(mmio_device, _accumulated_value);
|
||||
};
|
||||
template <typename F>
|
||||
inline MergeWrite<Register, _combined_mask | F::mask> with
|
||||
(const base_type value) && noexcept {
|
||||
MergeWrite<Register, _combined_mask | F::mask>
|
||||
with(const base_type value) && noexcept {
|
||||
static_assert(std::is_same<
|
||||
typename F::parent_register,
|
||||
Register
|
||||
>::value,
|
||||
"field is not from the same register in merge_write");
|
||||
F::policy::template write<
|
||||
base_type,
|
||||
base_type,
|
||||
F::mask,
|
||||
F::offset
|
||||
>(_accumulated_value, value);
|
||||
_accumulated_value = (_accumulated_value & ~F::mask)
|
||||
| ((value << F::offset) & F::mask);
|
||||
return
|
||||
std::move(
|
||||
MergeWrite<Register, (_combined_mask | F::mask)>
|
||||
|
@ -379,7 +373,8 @@ namespace cppreg {
|
|||
static_assert(!Register::shadow::value,
|
||||
"merge write is not available for shadow value register");
|
||||
constexpr MergeWrite() : _accumulated_value(0u) {};
|
||||
constexpr MergeWrite(const base_type v) : _accumulated_value(v) {};
|
||||
constexpr explicit MergeWrite(const base_type v) :
|
||||
_accumulated_value(v) {};
|
||||
base_type _accumulated_value;
|
||||
};
|
||||
}
|
||||
|
@ -410,7 +405,7 @@ namespace cppreg {
|
|||
return *(reinterpret_cast<const MMIO_t* const>(base_address));
|
||||
};
|
||||
template <typename F>
|
||||
inline static MergeWrite<typename F::parent_register, F::mask>
|
||||
static MergeWrite<typename F::parent_register, F::mask>
|
||||
merge_write(const typename F::type value) noexcept {
|
||||
return
|
||||
MergeWrite<typename F::parent_register, F::mask>
|
||||
|
@ -426,7 +421,7 @@ namespace cppreg {
|
|||
value
|
||||
>
|
||||
>
|
||||
inline static
|
||||
static
|
||||
typename std::enable_if<
|
||||
internals::check_overflow<
|
||||
type, value, (F::mask >> F::offset)
|
||||
|
@ -482,11 +477,11 @@ namespace cppreg {
|
|||
RegisterPack::size_in_bytes,
|
||||
reg_size
|
||||
>;
|
||||
inline static typename base_reg::MMIO_t& rw_mem_device() noexcept {
|
||||
static typename base_reg::MMIO_t& rw_mem_device() noexcept {
|
||||
return mem_map_t::array[bit_offset
|
||||
/ TypeTraits<reg_size>::bit_size];
|
||||
};
|
||||
inline static const typename base_reg::MMIO_t& ro_mem_device() noexcept {
|
||||
static const typename base_reg::MMIO_t& ro_mem_device() noexcept {
|
||||
return mem_map_t::array[bit_offset
|
||||
/ TypeTraits<reg_size>::bit_size];
|
||||
};
|
||||
|
@ -521,14 +516,14 @@ namespace cppreg {
|
|||
template <std::size_t start, std::size_t end>
|
||||
struct for_loop {
|
||||
template <typename Func>
|
||||
inline static void apply() noexcept {
|
||||
static void apply() noexcept {
|
||||
Func().template operator()<start>();
|
||||
if (start < end)
|
||||
for_loop<start + 1ul, end>::template apply<Func>();
|
||||
};
|
||||
#if __cplusplus >= 201402L
|
||||
template <typename Op>
|
||||
inline static void apply(Op&& f) noexcept {
|
||||
static void apply(Op&& f) noexcept {
|
||||
if (start < end) {
|
||||
f(std::integral_constant<std::size_t, start>{});
|
||||
for_loop<start + 1ul, end>::apply(std::forward<Op>(f));
|
||||
|
@ -539,10 +534,10 @@ namespace cppreg {
|
|||
template <std::size_t end>
|
||||
struct for_loop<end, end> {
|
||||
template <typename Func>
|
||||
inline static void apply() noexcept {};
|
||||
static void apply() noexcept {};
|
||||
#if __cplusplus >= 201402L
|
||||
template <typename Op>
|
||||
inline static void apply(Op&& f) noexcept {};
|
||||
static void apply(Op&& f) noexcept {};
|
||||
#endif
|
||||
};
|
||||
template <typename IndexedPack>
|
||||
|
@ -577,13 +572,13 @@ namespace cppreg {
|
|||
value,
|
||||
(mask >> offset)
|
||||
> {};
|
||||
inline static type read() noexcept {
|
||||
static type read() noexcept {
|
||||
return policy::template read<MMIO_t, type, mask, offset>(
|
||||
parent_register::ro_mem_device()
|
||||
);
|
||||
};
|
||||
template <typename T = type>
|
||||
inline static void
|
||||
static void
|
||||
write(const typename std::enable_if<!has_shadow, T>::type value)
|
||||
noexcept {
|
||||
policy::template write<MMIO_t, type, mask, offset>(
|
||||
|
@ -592,7 +587,7 @@ namespace cppreg {
|
|||
);
|
||||
};
|
||||
template <typename T = type>
|
||||
inline static void
|
||||
static void
|
||||
write(const typename std::enable_if<has_shadow, T>::type value)
|
||||
noexcept {
|
||||
RegisterWrite<type, type, mask, offset>
|
||||
|
@ -603,45 +598,45 @@ namespace cppreg {
|
|||
);
|
||||
};
|
||||
template <type value, typename T = void>
|
||||
inline static
|
||||
typename std::enable_if<
|
||||
!has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type
|
||||
write() noexcept {
|
||||
static void write(
|
||||
typename std::enable_if<
|
||||
!has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type* = nullptr
|
||||
) noexcept {
|
||||
policy::template write<MMIO_t, type, mask, offset, value>(
|
||||
parent_register::rw_mem_device()
|
||||
);
|
||||
};
|
||||
template <type value, typename T = void>
|
||||
inline static
|
||||
typename std::enable_if<
|
||||
has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type
|
||||
write() noexcept {
|
||||
static void write(
|
||||
typename std::enable_if<
|
||||
has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type* = nullptr
|
||||
) noexcept {
|
||||
write(value);
|
||||
};
|
||||
inline static void set() noexcept {
|
||||
static void set() noexcept {
|
||||
policy::template
|
||||
set<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
inline static void clear() noexcept {
|
||||
static void clear() noexcept {
|
||||
policy::template
|
||||
clear<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
inline static void toggle() noexcept {
|
||||
static void toggle() noexcept {
|
||||
policy::template
|
||||
toggle<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
inline static bool is_set() noexcept {
|
||||
static bool is_set() noexcept {
|
||||
return (Field::read() == (mask >> offset));
|
||||
};
|
||||
inline static bool is_clear() noexcept {
|
||||
static bool is_clear() noexcept {
|
||||
return (Field::read() == 0u);
|
||||
};
|
||||
static_assert(parent_register::size >= width,
|
||||
|
|
Loading…
Reference in New Issue