2023-08-23 09:04:05 +00:00
|
|
|
/**
|
|
|
|
* @file Alignment.h
|
|
|
|
* @author apio (cloudapio.eu)
|
|
|
|
* @brief Functions to align addresses and sizes to specified boundaries.
|
|
|
|
*
|
|
|
|
* @copyright Copyright (c) 2022-2023, the Luna authors.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2022-11-16 19:02:04 +00:00
|
|
|
#pragma once
|
2022-12-18 15:30:27 +00:00
|
|
|
#include <luna/Types.h>
|
2022-11-16 19:02:04 +00:00
|
|
|
|
2023-08-23 09:04:05 +00:00
|
|
|
/**
|
|
|
|
* @brief Check whether a value is aligned to a specific alignment.
|
|
|
|
*
|
|
|
|
* @tparam alignment The alignment to use. It must be provided as a template parameter to help the compiler with
|
|
|
|
* optimizations. For best results, use a power of two.
|
|
|
|
* @tparam T The type of the value.
|
|
|
|
* @param value The value to check.
|
|
|
|
* @return constexpr bool Whether the value is aligned.
|
|
|
|
*/
|
|
|
|
template <usize alignment, typename T> constexpr inline bool is_aligned(T value)
|
2022-11-16 19:02:04 +00:00
|
|
|
{
|
2022-11-18 17:02:38 +00:00
|
|
|
return (value % alignment == 0);
|
2022-11-16 19:02:04 +00:00
|
|
|
}
|
|
|
|
|
2023-08-23 09:04:05 +00:00
|
|
|
/**
|
|
|
|
* @brief Find the closest aligned value that is smaller than the value provided.
|
|
|
|
*
|
|
|
|
* @tparam alignment The alignment to use. It must be provided as a template parameter to help the compiler with
|
|
|
|
* optimizations. For best results, use a power of two.
|
|
|
|
* @tparam T The type of the value.
|
|
|
|
* @param value The value to use.
|
|
|
|
* @return constexpr T The aligned value.
|
|
|
|
*/
|
2023-03-07 19:37:30 +00:00
|
|
|
template <usize alignment, typename T> constexpr inline T align_down(T value)
|
2022-11-16 19:02:04 +00:00
|
|
|
{
|
2022-12-06 18:27:58 +00:00
|
|
|
return value - value % alignment;
|
2022-11-16 19:02:04 +00:00
|
|
|
}
|
|
|
|
|
2023-08-23 09:04:05 +00:00
|
|
|
/**
|
|
|
|
* @brief Find the closest aligned value that is bigger than the value provided.
|
|
|
|
*
|
|
|
|
* @tparam alignment The alignment to use. It must be provided as a template parameter to help the compiler with
|
|
|
|
* optimizations. For best results, use a power of two.
|
|
|
|
* @tparam T The type of the value.
|
|
|
|
* @param value The value to use.
|
|
|
|
* @return constexpr T The aligned value.
|
|
|
|
*/
|
2023-03-07 19:37:30 +00:00
|
|
|
template <usize alignment, typename T> constexpr inline T align_up(T value)
|
2022-11-16 19:02:04 +00:00
|
|
|
{
|
2022-12-06 18:27:58 +00:00
|
|
|
if (is_aligned<alignment>(value)) return value;
|
|
|
|
return align_down<alignment>(value) + alignment;
|
2022-11-16 19:02:04 +00:00
|
|
|
}
|
|
|
|
|
2023-08-23 09:04:05 +00:00
|
|
|
/**
|
|
|
|
* @brief Offset a pointer by exactly <offset> bytes, no matter the type.
|
|
|
|
*
|
|
|
|
* Generally only useful for pointers to void (or char), because breaking other pointers' alignments is not a good
|
|
|
|
* idea...
|
|
|
|
*
|
|
|
|
* @tparam T The underlying type of the pointer.
|
|
|
|
* @tparam Offset The type of the offset.
|
|
|
|
* @param ptr The pointer to offset.
|
|
|
|
* @param offset The offset to use (depending on the type, this could be negative).
|
|
|
|
* @return constexpr T* The new pointer.
|
|
|
|
*/
|
2023-03-07 19:37:30 +00:00
|
|
|
template <typename T, typename Offset> constexpr inline T* offset_ptr(T* ptr, Offset offset)
|
2022-11-20 14:12:18 +00:00
|
|
|
{
|
2023-01-16 18:52:34 +00:00
|
|
|
return (T*)((u8*)ptr + offset);
|
2023-01-02 12:07:29 +00:00
|
|
|
}
|