xref: /isa-l/include/unaligned.h (revision ae034d6f087d23d20f56950be306f81456f49921)
1 /**********************************************************************
2   Copyright(c) 2011-2019 Intel Corporation All rights reserved.
3 
4   Redistribution and use in source and binary forms, with or without
5   modification, are permitted provided that the following conditions
6   are met:
7     * Redistributions of source code must retain the above copyright
8       notice, 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
11       the documentation and/or other materials provided with the
12       distribution.
13     * Neither the name of Intel Corporation nor the names of its
14       contributors may be used to endorse or promote products derived
15       from this software without specific prior written permission.
16 
17   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
29 
30 #ifndef UNALIGNED_H
31 #define UNALIGNED_H
32 
33 #include "stdint.h"
34 #include "stdlib.h"
35 #include "string.h"
36 
37 #if defined(__FreeBSD__) || defined(__NetBSD__)
38 #include <sys/types.h>
39 #include <sys/endian.h>
40 #define isal_bswap16(x) bswap16(x)
41 #define isal_bswap32(x) bswap32(x)
42 #define isal_bswap64(x) bswap64(x)
43 #elif defined(__APPLE__)
44 #include <libkern/OSByteOrder.h>
45 #define isal_bswap16(x) OSSwapInt16(x)
46 #define isal_bswap32(x) OSSwapInt32(x)
47 #define isal_bswap64(x) OSSwapInt64(x)
48 #elif defined(__GNUC__) && !defined(__MINGW32__)
49 #include <byteswap.h>
50 #define isal_bswap16(x) bswap_16(x)
51 #define isal_bswap32(x) bswap_32(x)
52 #define isal_bswap64(x) bswap_64(x)
53 #elif defined _WIN32
54 #define isal_bswap16(x) _byteswap_ushort(x)
55 #define isal_bswap32(x) _byteswap_ulong(x)
56 #define isal_bswap64(x) _byteswap_uint64(x)
57 #endif
58 
59 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
60 #define to_be16(x)   isal_bswap16(x)
61 #define from_be16(x) isal_bswap16(x)
62 #define to_be32(x)   isal_bswap32(x)
63 #define from_be32(x) isal_bswap32(x)
64 #define to_be64(x)   isal_bswap64(x)
65 #define from_be64(x) isal_bswap64(x)
66 #define to_le16(x)   (x)
67 #define from_le16(x) (x)
68 #define to_le32(x)   (x)
69 #define from_le32(x) (x)
70 #define to_le64(x)   (x)
71 #define from_le64(x) (x)
72 #else
73 #define to_be16(x)   (x)
74 #define from_be16(x) (x)
75 #define to_be32(x)   (x)
76 #define from_be32(x) (x)
77 #define to_be64(x)   (x)
78 #define from_be64(x) (x)
79 #define to_le16(x)   isal_bswap16(x)
80 #define from_le16(x) isal_bswap16(x)
81 #define to_le32(x)   isal_bswap32(x)
82 #define from_le32(x) isal_bswap32(x)
83 #define to_le64(x)   isal_bswap64(x)
84 #define from_le64(x) isal_bswap64(x)
85 #endif
86 
87 static inline uint16_t
88 load_native_u16(uint8_t *buf)
89 {
90         uint16_t ret;
91         memcpy(&ret, buf, sizeof(ret));
92         return ret;
93 }
94 
95 static inline uint16_t
96 load_le_u16(uint8_t *buf)
97 {
98         return from_le16(load_native_u16(buf));
99 }
100 
101 static inline uint16_t
102 load_be_u16(uint8_t *buf)
103 {
104         return from_be16(load_native_u16(buf));
105 }
106 
107 static inline uint32_t
108 load_native_u32(uint8_t *buf)
109 {
110         uint32_t ret;
111         memcpy(&ret, buf, sizeof(ret));
112         return ret;
113 }
114 
115 static inline uint32_t
116 load_le_u32(uint8_t *buf)
117 {
118         return from_le32(load_native_u32(buf));
119 }
120 
121 static inline uint32_t
122 load_be_u32(uint8_t *buf)
123 {
124         return from_be32(load_native_u32(buf));
125 }
126 
127 static inline uint64_t
128 load_native_u64(uint8_t *buf)
129 {
130         uint64_t ret;
131         memcpy(&ret, buf, sizeof(ret));
132         return ret;
133 }
134 
135 static inline uint64_t
136 load_le_u64(uint8_t *buf)
137 {
138         return from_le64(load_native_u64(buf));
139 }
140 
141 static inline uint64_t
142 load_be_u64(uint8_t *buf)
143 {
144         return from_be64(load_native_u64(buf));
145 }
146 
147 static inline uintmax_t
148 load_le_umax(uint8_t *buf)
149 {
150         switch (sizeof(uintmax_t)) {
151         case sizeof(uint32_t):
152                 return from_le32(load_native_u32(buf));
153         case sizeof(uint64_t):
154                 return from_le64(load_native_u64(buf));
155         default:
156                 return 0;
157         }
158 }
159 
160 static inline void
161 store_native_u16(uint8_t *buf, uint16_t val)
162 {
163         memcpy(buf, &val, sizeof(val));
164 }
165 
166 static inline void
167 store_le_u16(uint8_t *buf, uint16_t val)
168 {
169         store_native_u16(buf, to_le16(val));
170 }
171 
172 static inline void
173 store_be_u16(uint8_t *buf, uint16_t val)
174 {
175         store_native_u16(buf, to_be16(val));
176 }
177 
178 static inline void
179 store_native_u16_to_u64(uint64_t *buf, uint16_t val)
180 {
181 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
182         store_native_u16((uint8_t *) buf, val);
183 #else
184         store_native_u16((uint8_t *) buf + 6, val);
185 #endif
186 }
187 
188 static inline void
189 store_native_u32(uint8_t *buf, uint32_t val)
190 {
191         memcpy(buf, &val, sizeof(val));
192 }
193 
194 static inline void
195 store_le_u32(uint8_t *buf, uint32_t val)
196 {
197         store_native_u32(buf, to_le32(val));
198 }
199 
200 static inline void
201 store_be_u32(uint8_t *buf, uint32_t val)
202 {
203         store_native_u32(buf, to_be32(val));
204 }
205 
206 static inline void
207 store_native_u64(uint8_t *buf, uint64_t val)
208 {
209         memcpy(buf, &val, sizeof(val));
210 }
211 
212 static inline void
213 store_le_u64(uint8_t *buf, uint64_t val)
214 {
215         store_native_u64(buf, to_le64(val));
216 }
217 
218 static inline void
219 store_be_u64(uint8_t *buf, uint64_t val)
220 {
221         store_native_u64(buf, to_be64(val));
222 }
223 
224 #endif
225