diff --git a/include/bx/uint32_t.h b/include/bx/uint32_t.h index 9e77295..16ce229 100644 --- a/include/bx/uint32_t.h +++ b/include/bx/uint32_t.h @@ -679,6 +679,64 @@ namespace bx #endif // BX_COMPILER_ } + /// Greatest common divisor. + inline uint32_t uint32_gcd(uint32_t _a, uint32_t _b) + { + do + { + uint32_t tmp = _a % _b; + _a = _b; + _b = tmp; + } + while (_b); + + return _a; + } + + /// Least common multiple. + inline uint32_t uint32_lcm(uint32_t _a, uint32_t _b) + { + return _a * (_b / uint32_gcd(_a, _b) ); + } + + /// Align to arbitrary stride. + inline uint32_t strideAlign(uint32_t _offset, uint32_t _stride) + { + const uint32_t mod = uint32_mod(_offset, _stride); + const uint32_t add = uint32_sub(_stride, mod); + const uint32_t mask = uint32_cmpeq(mod, 0); + const uint32_t tmp = uint32_selb(mask, 0, add); + const uint32_t result = uint32_add(_offset, tmp); + + return result; + } + + /// Align to arbitrary stride and 16-bytes. + inline uint32_t strideAlign16(uint32_t _offset, uint32_t _stride) + { + const uint32_t align = uint32_lcm(16, _stride); + const uint32_t mod = uint32_mod(_offset, align); + const uint32_t mask = uint32_cmpeq(mod, 0); + const uint32_t tmp0 = uint32_selb(mask, 0, align); + const uint32_t tmp1 = uint32_add(_offset, tmp0); + const uint32_t result = uint32_sub(tmp1, mod); + + return result; + } + + /// Align to arbitrary stride and 256-bytes. + inline uint32_t strideAlign256(uint32_t _offset, uint32_t _stride) + { + const uint32_t align = uint32_lcm(256, _stride); + const uint32_t mod = uint32_mod(_offset, align); + const uint32_t mask = uint32_cmpeq(mod, 0); + const uint32_t tmp0 = uint32_selb(mask, 0, align); + const uint32_t tmp1 = uint32_add(_offset, tmp0); + const uint32_t result = uint32_sub(tmp1, mod); + + return result; + } + } // namespace bx #endif // BX_UINT32_T_H_HEADER_GUARD diff --git a/tests/uint32_t.cpp b/tests/uint32_t.cpp new file mode 100644 index 0000000..b232ff6 --- /dev/null +++ b/tests/uint32_t.cpp @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include "test.h" +#include + +TEST(StrideAlign) +{ + CHECK(0 == bx::strideAlign(0, 12) ); + for (uint32_t ii = 0; ii < 12; ++ii) + { + CHECK(12 == bx::strideAlign(ii+1, 12) ); + } + + CHECK(0 == bx::strideAlign16(0, 12) ); + for (uint32_t ii = 0; ii < 12; ++ii) + { + CHECK(48 == bx::strideAlign16(ii+1, 12) ); + } +}