diff --git a/include/bx/allocator.h b/include/bx/allocator.h index 9a6010d..27e3f69 100644 --- a/include/bx/allocator.h +++ b/include/bx/allocator.h @@ -7,6 +7,7 @@ #define BX_ALLOCATOR_H_HEADER_GUARD #include "bx.h" +#include "uint32_t.h" #if BX_CONFIG_ALLOCATOR_DEBUG # define BX_ALLOC(_allocator, _size) bx::alloc(_allocator, _size, 0, __FILE__, __LINE__) diff --git a/include/bx/inline/allocator.inl b/include/bx/inline/allocator.inl index d0391f9..1810f0d 100644 --- a/include/bx/inline/allocator.inl +++ b/include/bx/inline/allocator.inl @@ -22,20 +22,12 @@ namespace bx { } - inline bool isAligned(const void* _ptr, size_t _align) - { - union { const void* ptr; uintptr_t addr; } un; - un.ptr = _ptr; - return 0 == (un.addr & (_align-1) ); - } - inline void* alignPtr(void* _ptr, size_t _extra, size_t _align) { union { void* ptr; uintptr_t addr; } un; un.ptr = _ptr; uintptr_t unaligned = un.addr + _extra; // space for header - uintptr_t mask = _align-1; - uintptr_t aligned = BX_ALIGN_MASK(unaligned, mask); + uintptr_t aligned = bx::alignUp(unaligned, _align); un.addr = aligned; return un.ptr; } diff --git a/include/bx/inline/readerwriter.inl b/include/bx/inline/readerwriter.inl index 36afeeb..604553f 100644 --- a/include/bx/inline/readerwriter.inl +++ b/include/bx/inline/readerwriter.inl @@ -239,7 +239,7 @@ namespace bx if (0 < morecore) { - morecore = BX_ALIGN_MASK(morecore, 0xfff); + morecore = alignUp(morecore, 0x1000); m_data = (uint8_t*)m_memBlock->more(morecore); m_size = m_memBlock->getSize(); } diff --git a/include/bx/inline/uint32_t.inl b/include/bx/inline/uint32_t.inl index 7bfcec7..e7227d1 100644 --- a/include/bx/inline/uint32_t.inl +++ b/include/bx/inline/uint32_t.inl @@ -687,6 +687,72 @@ namespace bx return result; } + template + inline bool isAligned(Ty _a, int32_t _align) + { + const Ty mask = _align - 1; + return 0 == (_a & mask); + } + + template + inline bool isAligned(const Ty* _ptr, int32_t _align) + { + union { const void* ptr; uintptr_t addr; } un = { _ptr }; + return isAligned(un.addr, _align); + } + + template + inline bool isAligned(Ty* _ptr, int32_t _align) + { + return isAligned( (const void*)_ptr, _align); + } + + template + inline Ty alignDown(Ty _a, int32_t _align) + { + const Ty mask = _align - 1; + return Ty(_a & ~mask); + } + + template + inline Ty* alignDown(Ty* _ptr, int32_t _align) + { + union { Ty* ptr; uintptr_t addr; } un = { _ptr }; + un.addr = alignDown(un.addr, _align); + return un.ptr; + } + + template + inline const Ty* alignDown(const Ty* _ptr, int32_t _align) + { + union { const Ty* ptr; uintptr_t addr; } un = { _ptr }; + un.addr = alignDown(un.addr, _align); + return un.ptr; + } + + template + inline Ty alignUp(Ty _a, int32_t _align) + { + const Ty mask = _align - 1; + return Ty( (_a + mask) & ~mask); + } + + template + inline Ty* alignUp(Ty* _ptr, int32_t _align) + { + union { Ty* ptr; uintptr_t addr; } un = { _ptr }; + un.addr = alignUp(un.addr, _align); + return un.ptr; + } + + template + inline const Ty* alignUp(const Ty* _ptr, int32_t _align) + { + union { const Ty* ptr; uintptr_t addr; } un = { _ptr }; + un.addr = alignUp(un.addr, _align); + return un.ptr; + } + inline BX_CONST_FUNC uint16_t halfFromFloat(float _a) { union { uint32_t ui; float flt; } ftou; diff --git a/include/bx/macros.h b/include/bx/macros.h index f4a003b..5b8ca91 100644 --- a/include/bx/macros.h +++ b/include/bx/macros.h @@ -42,12 +42,6 @@ /// #define BX_FILE_LINE_LITERAL "" __FILE__ "(" BX_STRINGIZE(__LINE__) "): " -/// -#define BX_ALIGN_MASK(_value, _mask) ( ( (_value)+(_mask) ) & ( (~0)&(~(_mask) ) ) ) -#define BX_ALIGN_16(_value) BX_ALIGN_MASK(_value, 0xf) -#define BX_ALIGN_256(_value) BX_ALIGN_MASK(_value, 0xff) -#define BX_ALIGN_4096(_value) BX_ALIGN_MASK(_value, 0xfff) - /// #define BX_ALIGNOF(_type) __alignof(_type) diff --git a/include/bx/uint32_t.h b/include/bx/uint32_t.h index 7e813a5..3922625 100644 --- a/include/bx/uint32_t.h +++ b/include/bx/uint32_t.h @@ -251,6 +251,42 @@ namespace bx template BX_CONSTEXPR_FUNC uint32_t strideAlign(uint32_t _offset, uint32_t _stride); + /// + template + bool isAligned(Ty _a, int32_t _align); + + /// + template + bool isAligned(void* _ptr, int32_t _align); + + /// + template + bool isAligned(const void* _ptr, int32_t _align); + + /// + template + Ty alignDown(Ty _a, int32_t _align); + + /// + template + Ty* alignDown(Ty* _ptr, int32_t _align); + + /// + template + const Ty* alignDown(const Ty* _ptr, int32_t _align); + + /// + template + Ty alignUp(Ty _a, int32_t _align); + + /// + template + Ty* alignUp(Ty* _ptr, int32_t _align); + + /// + template + const Ty* alignUp(const Ty* _ptr, int32_t _align); + /// Convert float to half-float. /// BX_CONST_FUNC uint16_t halfFromFloat(float _a); diff --git a/tests/macros_test.cpp b/tests/macros_test.cpp index 98e8cf2..324e571 100644 --- a/tests/macros_test.cpp +++ b/tests/macros_test.cpp @@ -24,20 +24,6 @@ BX_STATIC_ASSERT(4 == BX_VA_ARGS_COUNT(1, 2, 3, 4) ); BX_STATIC_ASSERT(5 == BX_VA_ARGS_COUNT(1, 2, 3, 4, 5) ); BX_STATIC_ASSERT(6 == BX_VA_ARGS_COUNT(1, 2, 3, 4, 5, 6) ); -BX_STATIC_ASSERT( 0 == BX_ALIGN_16( 0) ); -BX_STATIC_ASSERT( 16 == BX_ALIGN_16( 1) ); -BX_STATIC_ASSERT( 16 == BX_ALIGN_16( 15) ); -BX_STATIC_ASSERT( 16 == BX_ALIGN_16( 16) ); -BX_STATIC_ASSERT(256 == BX_ALIGN_16(255) ); - -BX_STATIC_ASSERT( 0 == BX_ALIGN_256( 0) ); -BX_STATIC_ASSERT(256 == BX_ALIGN_256( 1) ); -BX_STATIC_ASSERT(256 == BX_ALIGN_256( 15) ); -BX_STATIC_ASSERT(256 == BX_ALIGN_256(255) ); -BX_STATIC_ASSERT(256 == BX_ALIGN_256(256) ); -BX_STATIC_ASSERT(256 == BX_ALIGN_256(256) ); -BX_STATIC_ASSERT(512 == BX_ALIGN_256(511) ); - BX_NO_INLINE void unusedFunction() { CHECK(false); diff --git a/tests/uint32_test.cpp b/tests/uint32_test.cpp index e697e3c..3772442 100644 --- a/tests/uint32_test.cpp +++ b/tests/uint32_test.cpp @@ -117,3 +117,35 @@ TEST_CASE("uint64_roX", "") REQUIRE(bx::uint64_rol(0x8000000000000000, 1) == 1); REQUIRE(bx::uint64_ror(1, 1) == 0x8000000000000000); } + +TEST_CASE("align", "") +{ + REQUIRE( bx::isAligned(0, 8) ); + REQUIRE(!bx::isAligned(7, 8) ); + REQUIRE( bx::isAligned(64, 8) ); + REQUIRE(!bx::isAligned(63, 8) ); + + REQUIRE( 0 == bx::alignUp( 0, 16) ); + REQUIRE( 16 == bx::alignUp( 1, 16) ); + REQUIRE( 16 == bx::alignUp( 15, 16) ); + REQUIRE( 16 == bx::alignUp( 16, 16) ); + REQUIRE(256 == bx::alignUp(255, 16) ); + REQUIRE( 0 == bx::alignUp(-1, 16) ); + REQUIRE(-16 == bx::alignUp(-31, 16) ); + + REQUIRE( 0 == bx::alignUp( 0, 256) ); + REQUIRE(256 == bx::alignUp( 1, 256) ); + REQUIRE(256 == bx::alignUp( 15, 256) ); + REQUIRE(256 == bx::alignUp(255, 256) ); + REQUIRE(256 == bx::alignUp(256, 256) ); + REQUIRE(256 == bx::alignUp(256, 256) ); + REQUIRE(512 == bx::alignUp(511, 256) ); + + REQUIRE( 0 == bx::alignDown( 0, 16) ); + REQUIRE( 0 == bx::alignDown( 1, 16) ); + REQUIRE( 0 == bx::alignDown( 15, 16) ); + REQUIRE( 16 == bx::alignDown( 16, 16) ); + REQUIRE(240 == bx::alignDown(255, 16) ); + REQUIRE(-16 == bx::alignDown(-1, 16) ); + REQUIRE(-32 == bx::alignDown(-31, 16) ); +}