Added load/store aligned/unaligned. (#366)

This commit is contained in:
Branimir Karadžić
2026-01-26 18:00:52 -08:00
committed by GitHub
parent 0e7d969a8a
commit 3ed36d14b0
3 changed files with 130 additions and 57 deletions

View File

@@ -174,6 +174,38 @@ namespace bx
template<typename Ty>
const Ty* addressOf(const void* _ptr, ptrdiff_t _offsetInBytes = 0);
/// Loads a value of type Ty from an naturally aligned memory location.
///
/// @param[in] _ptr Pointer to the memory location.
/// @returns The loaded value of type Ty.
///
template<typename Ty>
inline Ty loadAligned(const void* _ptr);
/// Loads a value of type Ty from a potentially unaligned memory location.
///
/// @param[in] _ptr Pointer to the memory location.
/// @returns The loaded value of type Ty.
///
template<typename Ty>
inline Ty loadUnaligned(const void* _ptr);
/// Stores a value of type Ty to an naturally aligned memory location.
///
/// @param[out] _ptr Pointer to the destination memory.
/// @param[in] _value The value to store.
///
template<typename Ty>
inline void storeAligned(void* _outPtr, const Ty& _value);
/// Stores a value of type Ty to a potentially unaligned memory location.
///
/// @param[out] _ptr Pointer to the destination memory.
/// @param[in] _value The value to store.
///
template<typename Ty>
inline void storeUnaligned(void* _outPtr, const Ty& _value);
/// Swap two values.
template<typename Ty>
void swap(Ty& _a, Ty& _b);

View File

@@ -59,6 +59,81 @@ namespace bx
return (const Ty*)( (const uint8_t*)_ptr + _offsetInBytes);
}
template<typename Ty>
inline Ty loadAligned(const void* _ptr)
{
static_assert(isTriviallyCopyable<Ty>(), "Ty must be trivially copyable type.");
return *(const Ty*)_ptr;
}
template<typename Ty>
inline Ty loadUnaligned(const void* _ptr)
{
static_assert(isTriviallyCopyable<Ty>(), "Ty must be trivially copyable type.");
#if BX_COMPILER_GCC || BX_COMPILER_CLANG
typedef Ty BX_ATTRIBUTE(aligned(1) ) UnalignedTy;
return *(UnalignedTy*)_ptr;
#else
Ty value;
memCopy(&value, _ptr, sizeof(Ty) );
return value;
#endif // BX_COMPILER_*
}
template<>
inline uint32_t loadUnaligned(const void* _ptr)
{
const uint8_t* data = (const uint8_t*)_ptr;
return 0
| uint32_t(data[3])<<24
| uint32_t(data[2])<<16
| uint32_t(data[1])<<8
| uint32_t(data[0])
;
}
template<>
inline uint64_t loadUnaligned(const void* _ptr)
{
const uint8_t* data = (const uint8_t*)_ptr;
return 0
| uint64_t(data[7])<<56
| uint64_t(data[6])<<48
| uint64_t(data[5])<<40
| uint64_t(data[4])<<32
| uint64_t(data[3])<<24
| uint64_t(data[2])<<16
| uint64_t(data[1])<<8
| uint64_t(data[0])
;
}
template<typename Ty>
inline void storeAligned(void* _ptr, const Ty& _value)
{
static_assert(isTriviallyCopyable<Ty>(), "Ty must be trivially copyable type.");
*(Ty*)_ptr = _value;
}
template<typename Ty>
inline void storeUnaligned(void* _ptr, const Ty& _value)
{
static_assert(isTriviallyCopyable<Ty>(), "Ty must be trivially copyable type.");
#if BX_COMPILER_GCC || BX_COMPILER_CLANG
typedef Ty BX_ATTRIBUTE(aligned(1) ) UnalignedTy;
*(UnalignedTy*)_ptr = _value;
#else
memCopy(_ptr, &_value, sizeof(Ty) );
#endif // BX_COMPILER_*
}
template<typename Ty>
inline void swap(Ty& _a, Ty& _b)
{