From 7a0cfb484ccbf6c8dbcea8af7393e18c0757b66d Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Thu, 9 Jun 2022 21:55:12 +0530 Subject: [PATCH] Add NPOT `AlignUp` utility All our normal alignment functions are designed to only handle power of 2 (`POT`) multiples as we only align or check alignment to `POT` multiples but there are cases where this is not possible and we deal with `NPOT` multiples which is why this function is required. --- app/src/main/cpp/skyline/common/utils.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/src/main/cpp/skyline/common/utils.h b/app/src/main/cpp/skyline/common/utils.h index e57fd2b9..e9dd44f7 100644 --- a/app/src/main/cpp/skyline/common/utils.h +++ b/app/src/main/cpp/skyline/common/utils.h @@ -70,7 +70,7 @@ namespace skyline::util { /** * @return The value aligned up to the next multiple - * @note The multiple needs to be a power of 2 + * @note The multiple **must** be a power of 2 */ template requires IsPointerOrUnsignedIntegral @@ -79,9 +79,20 @@ namespace skyline::util { return ValuePointer((PointerValue(value) + multiple) & ~(multiple)); } + /** + * @return The value aligned up to the next multiple, the multiple is not restricted to being a power of two (NPOT) + * @note This will round away from zero for negative numbers + * @note This is costlier to compute than the power of 2 version, it should be preferred over this when possible + */ + template + requires std::is_integral_v || std::is_pointer_v + constexpr TypeVal AlignUpNpot(TypeVal value, ssize_t multiple) { + return ValuePointer(((PointerValue(value) + multiple - 1) / multiple) * multiple); + } + /** * @return The value aligned down to the previous multiple - * @note The multiple needs to be a power of 2 + * @note The multiple **must** be a power of 2 */ template requires IsPointerOrUnsignedIntegral