1/*
2 * Copyright (c) 2015, Intel Corporation
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * * Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Intel Corporation nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** \file
30 * \brief Helper functions for unaligned loads and stores.
31 */
32
33#ifndef UNALIGNED_H
34#define UNALIGNED_H
35
36#include "ue2common.h"
37
38#if !defined(_WIN32)
39#define PACKED__MAY_ALIAS __attribute__((packed, may_alias))
40#else
41#define PACKED__MAY_ALIAS
42#pragma pack(push, 1) // pack everything until told otherwise
43#endif
44
45/// Perform an unaligned 16-bit load
46static really_inline
47u16 unaligned_load_u16(const void *ptr) {
48 struct unaligned { u16 u; } PACKED__MAY_ALIAS;
49 const struct unaligned *uptr = (const struct unaligned *)ptr;
50 return uptr->u;
51}
52
53/// Perform an unaligned 32-bit load
54static really_inline
55u32 unaligned_load_u32(const void *ptr) {
56 struct unaligned { u32 u; } PACKED__MAY_ALIAS;
57 const struct unaligned *uptr = (const struct unaligned *)ptr;
58 return uptr->u;
59}
60
61/// Perform an unaligned 64-bit load
62static really_inline
63u64a unaligned_load_u64a(const void *ptr) {
64 struct unaligned { u64a u; } PACKED__MAY_ALIAS;
65 const struct unaligned *uptr = (const struct unaligned *)ptr;
66 return uptr->u;
67}
68
69/// Perform an unaligned 16-bit store
70static really_inline
71void unaligned_store_u16(void *ptr, u16 val) {
72 struct unaligned { u16 u; } PACKED__MAY_ALIAS;
73 struct unaligned *uptr = (struct unaligned *)ptr;
74 uptr->u = val;
75}
76
77/// Perform an unaligned 32-bit store
78static really_inline
79void unaligned_store_u32(void *ptr, u32 val) {
80 struct unaligned { u32 u; } PACKED__MAY_ALIAS;
81 struct unaligned *uptr = (struct unaligned *)ptr;
82 uptr->u = val;
83}
84
85/// Perform an unaligned 64-bit store
86static really_inline
87void unaligned_store_u64a(void *ptr, u64a val) {
88 struct unaligned { u64a u; } PACKED__MAY_ALIAS;
89 struct unaligned *uptr = (struct unaligned *)ptr;
90 uptr->u = val;
91}
92#if defined(_WIN32)
93#pragma pack(pop)
94#endif // win32
95
96#undef PACKED__MAY_ALIAS
97
98#endif // UNALIGNED_H
99