mirror of
https://github.com/sendyne/cppreg.git
synced 2025-05-09 23:24:05 +00:00
FIX INLINING OF WRITE CALLS WITH Os ENABLED
The inlining issue was due to a bad template design in the access policies implementations: the MMIO_t type from the field was used (which is a volatile type) for all arguments in the write implementation. The new implementation relies on two template types (one for the register memory device and another one for the value to be written). This fixes inlining and was checked on godbolt.
This commit is contained in:
parent
d7404ab946
commit
5cf8a851d8
@ -25,14 +25,15 @@ namespace cppreg {
|
|||||||
|
|
||||||
//! Read access implementation.
|
//! Read access implementation.
|
||||||
/**
|
/**
|
||||||
|
* @tparam MMIO_t Register memory device type.
|
||||||
* @tparam T Field data type.
|
* @tparam T Field data type.
|
||||||
* @param mmio_device Pointer to register mapped memory.
|
* @param mmio_device Pointer to register mapped memory.
|
||||||
* @param mask Field mask.
|
* @param mask Field mask.
|
||||||
* @param offset Field offset.
|
* @param offset Field offset.
|
||||||
* @return The value at the field location.
|
* @return The value at the field location.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static T read(const T* const mmio_device,
|
inline static T read(const MMIO_t* const mmio_device,
|
||||||
const T mask,
|
const T mask,
|
||||||
const Offset_t offset) noexcept {
|
const Offset_t offset) noexcept {
|
||||||
return static_cast<T>((*mmio_device & mask) >> offset);
|
return static_cast<T>((*mmio_device & mask) >> offset);
|
||||||
@ -46,14 +47,15 @@ namespace cppreg {
|
|||||||
|
|
||||||
//! Write access implementation.
|
//! Write access implementation.
|
||||||
/**
|
/**
|
||||||
|
* @tparam MMIO_t Register memory device type.
|
||||||
* @tparam T Field data type.
|
* @tparam T Field data type.
|
||||||
* @param mmio_device Pointer to register mapped memory.
|
* @param mmio_device Pointer to register mapped memory.
|
||||||
* @param mask Field mask.
|
* @param mask Field mask.
|
||||||
* @param offset Field offset.
|
* @param offset Field offset.
|
||||||
* @param value Value to be written at the field location.
|
* @param value Value to be written at the field location.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static void write(T* const mmio_device,
|
inline static void write(MMIO_t* const mmio_device,
|
||||||
const T mask,
|
const T mask,
|
||||||
const Offset_t offset,
|
const Offset_t offset,
|
||||||
const T value) noexcept {
|
const T value) noexcept {
|
||||||
@ -67,31 +69,36 @@ namespace cppreg {
|
|||||||
* @param mmio_device Pointer to register mapped memory.
|
* @param mmio_device Pointer to register mapped memory.
|
||||||
* @param mask Field mask.
|
* @param mask Field mask.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static void set(T* const mmio_device, const T mask) noexcept {
|
inline static void set(MMIO_t* const mmio_device, const T mask)
|
||||||
|
noexcept {
|
||||||
*mmio_device = static_cast<T>((*mmio_device) | mask);
|
*mmio_device = static_cast<T>((*mmio_device) | mask);
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Clear field implementation.
|
//! Clear field implementation.
|
||||||
/**
|
/**
|
||||||
|
* @tparam MMIO_t Register memory device type.
|
||||||
* @tparam T Field data type.
|
* @tparam T Field data type.
|
||||||
* @param mmio_device Pointer to register mapped memory.
|
* @param mmio_device Pointer to register mapped memory.
|
||||||
* @param mask Field mask.
|
* @param mask Field mask.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static void clear(T* const mmio_device, const T mask) noexcept {
|
inline static void clear(MMIO_t* const mmio_device, const T mask)
|
||||||
|
noexcept {
|
||||||
*mmio_device = static_cast<T>((*mmio_device) & ~mask);
|
*mmio_device = static_cast<T>((*mmio_device) & ~mask);
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Toggle field implementation.
|
//! Toggle field implementation.
|
||||||
/**
|
/**
|
||||||
|
* @tparam MMIO_t Register memory device type.
|
||||||
* @tparam T Field data type.
|
* @tparam T Field data type.
|
||||||
* @param mmio_device Pointer to register mapped memory.
|
* @param mmio_device Pointer to register mapped memory.
|
||||||
* @param mask Field mask.
|
* @param mask Field mask.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static void toggle(T* const mmio_device, const T mask) noexcept {
|
inline static void toggle(MMIO_t* const mmio_device, const T mask)
|
||||||
*mmio_device ^= mask;
|
noexcept {
|
||||||
|
*mmio_device = static_cast<T>((*mmio_device) ^ mask);
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -102,14 +109,15 @@ namespace cppreg {
|
|||||||
|
|
||||||
//! Write access implementation.
|
//! Write access implementation.
|
||||||
/**
|
/**
|
||||||
|
* @tparam MMIO_t Register memory device type.
|
||||||
* @tparam T Field data type.
|
* @tparam T Field data type.
|
||||||
* @param mmio_device Pointer to register mapped memory.
|
* @param mmio_device Pointer to register mapped memory.
|
||||||
* @param mask Field mask.
|
* @param mask Field mask.
|
||||||
* @param offset Field offset
|
* @param offset Field offset
|
||||||
* @param value Value to be written at the field location.
|
* @param value Value to be written at the field location.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static void write(T* const mmio_device,
|
inline static void write(MMIO_t* const mmio_device,
|
||||||
const T mask,
|
const T mask,
|
||||||
const Offset_t offset,
|
const Offset_t offset,
|
||||||
const T value) noexcept {
|
const T value) noexcept {
|
||||||
|
@ -90,8 +90,7 @@ namespace cppreg {
|
|||||||
*/
|
*/
|
||||||
inline static type read() noexcept {
|
inline static type read() noexcept {
|
||||||
return
|
return
|
||||||
AccessPolicy
|
AccessPolicy::read(parent_register::ro_mem_pointer(),
|
||||||
::template read<MMIO_t>(parent_register::ro_mem_pointer(),
|
|
||||||
mask,
|
mask,
|
||||||
offset);
|
offset);
|
||||||
};
|
};
|
||||||
@ -113,8 +112,7 @@ namespace cppreg {
|
|||||||
write(const typename std::enable_if<
|
write(const typename std::enable_if<
|
||||||
!parent_register::shadow::use_shadow, T
|
!parent_register::shadow::use_shadow, T
|
||||||
>::type value) noexcept {
|
>::type value) noexcept {
|
||||||
AccessPolicy
|
AccessPolicy::write(parent_register::rw_mem_pointer(),
|
||||||
::template write<MMIO_t>(parent_register::rw_mem_pointer(),
|
|
||||||
mask,
|
mask,
|
||||||
offset,
|
offset,
|
||||||
value);
|
value);
|
||||||
@ -147,8 +145,7 @@ namespace cppreg {
|
|||||||
|
|
||||||
// Write as a block to the register, that is, we do not use the
|
// Write as a block to the register, that is, we do not use the
|
||||||
// mask and offset.
|
// mask and offset.
|
||||||
AccessPolicy
|
AccessPolicy::write(parent_register::rw_mem_pointer(),
|
||||||
::template write<MMIO_t>(parent_register::rw_mem_pointer(),
|
|
||||||
~(0u),
|
~(0u),
|
||||||
0u,
|
0u,
|
||||||
parent_register::shadow::value);
|
parent_register::shadow::value);
|
||||||
@ -205,8 +202,7 @@ namespace cppreg {
|
|||||||
* This method will set all bits in the field.
|
* This method will set all bits in the field.
|
||||||
*/
|
*/
|
||||||
inline static void set() noexcept {
|
inline static void set() noexcept {
|
||||||
AccessPolicy
|
AccessPolicy::set(parent_register::rw_mem_pointer(), mask);
|
||||||
::template set<MMIO_t>(parent_register::rw_mem_pointer(), mask);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Field clear method.
|
//! Field clear method.
|
||||||
@ -214,8 +210,7 @@ namespace cppreg {
|
|||||||
* This method will clear all bits in the field.
|
* This method will clear all bits in the field.
|
||||||
*/
|
*/
|
||||||
inline static void clear() noexcept {
|
inline static void clear() noexcept {
|
||||||
AccessPolicy
|
AccessPolicy::clear(parent_register::rw_mem_pointer(), mask);
|
||||||
::template clear<MMIO_t>(parent_register::rw_mem_pointer(), mask);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Field toggle method.
|
//! Field toggle method.
|
||||||
@ -223,8 +218,7 @@ namespace cppreg {
|
|||||||
* This method will toggle all bits in the field.
|
* This method will toggle all bits in the field.
|
||||||
*/
|
*/
|
||||||
inline static void toggle() noexcept {
|
inline static void toggle() noexcept {
|
||||||
AccessPolicy
|
AccessPolicy::toggle(parent_register::rw_mem_pointer(), mask);
|
||||||
::template toggle<MMIO_t>(parent_register::rw_mem_pointer(), mask);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Is field set bool method.
|
//! Is field set bool method.
|
||||||
|
@ -24,38 +24,41 @@ namespace cppreg {
|
|||||||
#define CPPREG_ACCESSPOLICY_H
|
#define CPPREG_ACCESSPOLICY_H
|
||||||
namespace cppreg {
|
namespace cppreg {
|
||||||
struct read_only {
|
struct read_only {
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static T read(const T* const mmio_device,
|
inline static T read(const MMIO_t* const mmio_device,
|
||||||
const T mask,
|
const T mask,
|
||||||
const Offset_t offset) noexcept {
|
const Offset_t offset) noexcept {
|
||||||
return static_cast<T>((*mmio_device & mask) >> offset);
|
return static_cast<T>((*mmio_device & mask) >> offset);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
struct read_write : read_only {
|
struct read_write : read_only {
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static void write(T* const mmio_device,
|
inline static void write(MMIO_t* const mmio_device,
|
||||||
const T mask,
|
const T mask,
|
||||||
const Offset_t offset,
|
const Offset_t offset,
|
||||||
const T value) noexcept {
|
const T value) noexcept {
|
||||||
*mmio_device = static_cast<T>((*mmio_device & ~mask) |
|
*mmio_device = static_cast<T>((*mmio_device & ~mask) |
|
||||||
((value << offset) & mask));
|
((value << offset) & mask));
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static void set(T* const mmio_device, const T mask) noexcept {
|
inline static void set(MMIO_t* const mmio_device, const T mask)
|
||||||
|
noexcept {
|
||||||
*mmio_device = static_cast<T>((*mmio_device) | mask);
|
*mmio_device = static_cast<T>((*mmio_device) | mask);
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static void clear(T* const mmio_device, const T mask) noexcept {
|
inline static void clear(MMIO_t* const mmio_device, const T mask)
|
||||||
|
noexcept {
|
||||||
*mmio_device = static_cast<T>((*mmio_device) & ~mask);
|
*mmio_device = static_cast<T>((*mmio_device) & ~mask);
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static void toggle(T* const mmio_device, const T mask) noexcept {
|
inline static void toggle(MMIO_t* const mmio_device, const T mask)
|
||||||
*mmio_device ^= mask;
|
noexcept {
|
||||||
|
*mmio_device = static_cast<T>((*mmio_device) ^ mask);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
struct write_only {
|
struct write_only {
|
||||||
template <typename T>
|
template <typename MMIO_t, typename T>
|
||||||
inline static void write(T* const mmio_device,
|
inline static void write(MMIO_t* const mmio_device,
|
||||||
const T mask,
|
const T mask,
|
||||||
const Offset_t offset,
|
const Offset_t offset,
|
||||||
const T value) noexcept {
|
const T value) noexcept {
|
||||||
@ -287,8 +290,7 @@ namespace cppreg {
|
|||||||
};
|
};
|
||||||
inline static type read() noexcept {
|
inline static type read() noexcept {
|
||||||
return
|
return
|
||||||
AccessPolicy
|
AccessPolicy::read(parent_register::ro_mem_pointer(),
|
||||||
::template read<MMIO_t>(parent_register::ro_mem_pointer(),
|
|
||||||
mask,
|
mask,
|
||||||
offset);
|
offset);
|
||||||
};
|
};
|
||||||
@ -297,8 +299,7 @@ namespace cppreg {
|
|||||||
write(const typename std::enable_if<
|
write(const typename std::enable_if<
|
||||||
!parent_register::shadow::use_shadow, T
|
!parent_register::shadow::use_shadow, T
|
||||||
>::type value) noexcept {
|
>::type value) noexcept {
|
||||||
AccessPolicy
|
AccessPolicy::write(parent_register::rw_mem_pointer(),
|
||||||
::template write<MMIO_t>(parent_register::rw_mem_pointer(),
|
|
||||||
mask,
|
mask,
|
||||||
offset,
|
offset,
|
||||||
value);
|
value);
|
||||||
@ -311,8 +312,7 @@ namespace cppreg {
|
|||||||
parent_register::shadow::value =
|
parent_register::shadow::value =
|
||||||
(parent_register::shadow::value & ~mask) |
|
(parent_register::shadow::value & ~mask) |
|
||||||
((value << offset) & mask);
|
((value << offset) & mask);
|
||||||
AccessPolicy
|
AccessPolicy::write(parent_register::rw_mem_pointer(),
|
||||||
::template write<MMIO_t>(parent_register::rw_mem_pointer(),
|
|
||||||
~(0u),
|
~(0u),
|
||||||
0u,
|
0u,
|
||||||
parent_register::shadow::value);
|
parent_register::shadow::value);
|
||||||
@ -340,16 +340,13 @@ namespace cppreg {
|
|||||||
write(value);
|
write(value);
|
||||||
};
|
};
|
||||||
inline static void set() noexcept {
|
inline static void set() noexcept {
|
||||||
AccessPolicy
|
AccessPolicy::set(parent_register::rw_mem_pointer(), mask);
|
||||||
::template set<MMIO_t>(parent_register::rw_mem_pointer(), mask);
|
|
||||||
};
|
};
|
||||||
inline static void clear() noexcept {
|
inline static void clear() noexcept {
|
||||||
AccessPolicy
|
AccessPolicy::clear(parent_register::rw_mem_pointer(), mask);
|
||||||
::template clear<MMIO_t>(parent_register::rw_mem_pointer(), mask);
|
|
||||||
};
|
};
|
||||||
inline static void toggle() noexcept {
|
inline static void toggle() noexcept {
|
||||||
AccessPolicy
|
AccessPolicy::toggle(parent_register::rw_mem_pointer(), mask);
|
||||||
::template toggle<MMIO_t>(parent_register::rw_mem_pointer(), mask);
|
|
||||||
};
|
};
|
||||||
template <typename T = bool>
|
template <typename T = bool>
|
||||||
inline static typename std::enable_if<FieldWidth == 1, T>::type
|
inline static typename std::enable_if<FieldWidth == 1, T>::type
|
||||||
|
Loading…
x
Reference in New Issue
Block a user