OXYGENHUB
◆ main openmsx / src / utils / aligned.hh
1.5 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#ifndef ALIGNED_HH
2
#define ALIGNED_HH
3
4
#include "inline.hh"
5
6
#include <cstdint>
7
#include <cstring>
8
9
// Only need to (more strictly) align when SSE is actually enabled.
10
#ifdef __SSE2__
11
inline constexpr size_t SSE_ALIGNMENT = 16;
12
#else
13
inline constexpr size_t SSE_ALIGNMENT = 0; // alignas(0) has no effect
14
#endif
15
16
// 'alignas(0)' has no effect according to the C++ standard, however gcc
17
// produces a warning for it. This for example triggers when using
18
//     alignas(SSE_ALIGNMENT)
19
// and the target has no SSE instructions (thus SSE_ALIGNMENT == 0).
20
// The following macro works around that.
21
#ifdef __SSE2__
22
#define ALIGNAS_SSE alignas(SSE_ALIGNMENT)
23
#else
24
#define ALIGNAS_SSE /*nothing*/
25
#endif
26
27
// Unaligned loads and stores.
28
template<typename T> [[nodiscard]] static ALWAYS_INLINE T unalignedLoad(const void* p)
29
{
30
	T t;
31
	memcpy(&t, p, sizeof(t));
32
	return t;
33
}
34
static ALWAYS_INLINE void unalignedStore(void* p, auto t)
35
{
36
	memcpy(p, &t, sizeof(t));
37
}
38
39
[[nodiscard]] ALWAYS_INLINE uint16_t unalignedLoad16(const void* p) {
40
	return unalignedLoad<uint16_t>(p);
41
}
42
[[nodiscard]] ALWAYS_INLINE uint32_t unalignedLoad32(const void* p) {
43
	return unalignedLoad<uint32_t>(p);
44
}
45
[[nodiscard]] ALWAYS_INLINE uint64_t unalignedLoad64(const void* p) {
46
	return unalignedLoad<uint64_t>(p);
47
}
48
ALWAYS_INLINE void unalignedStore16(void* p, uint16_t v) {
49
	unalignedStore(p, v);
50
}
51
ALWAYS_INLINE void unalignedStore32(void* p, uint32_t v) {
52
	unalignedStore(p, v);
53
}
54
ALWAYS_INLINE void unalignedStore64(void* p, uint64_t v) {
55
	unalignedStore(p, v);
56
}
57
58
#endif // ALIGNED_HH