blob: dcdd586a9fd91555d3fb75e48ea2b4a2b5c8aa41 [file] [log] [blame]
Nick Terrelle0c1b49f2020-09-11 16:37:08 -07001/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
2/*
3 * Copyright (c) Yann Collet, Facebook, Inc.
4 * All rights reserved.
5 *
6 * This source code is licensed under both the BSD-style license (found in the
7 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
8 * in the COPYING file in the root directory of this source tree).
9 * You may select, at your option, one of the above-listed licenses.
10 */
11
12#ifndef MEM_H_MODULE
13#define MEM_H_MODULE
14
15/*-****************************************
16* Dependencies
17******************************************/
18#include <asm/unaligned.h> /* get_unaligned, put_unaligned* */
19#include <linux/compiler.h> /* inline */
20#include <linux/swab.h> /* swab32, swab64 */
21#include <linux/types.h> /* size_t, ptrdiff_t */
22#include "debug.h" /* DEBUG_STATIC_ASSERT */
23
24/*-****************************************
25* Compiler specifics
26******************************************/
27#define MEM_STATIC static inline
28
29/*-**************************************************************
30* Basic Types
31*****************************************************************/
32typedef uint8_t BYTE;
33typedef uint16_t U16;
34typedef int16_t S16;
35typedef uint32_t U32;
36typedef int32_t S32;
37typedef uint64_t U64;
38typedef int64_t S64;
39
40/*-**************************************************************
41* Memory I/O API
42*****************************************************************/
43/*=== Static platform detection ===*/
44MEM_STATIC unsigned MEM_32bits(void);
45MEM_STATIC unsigned MEM_64bits(void);
46MEM_STATIC unsigned MEM_isLittleEndian(void);
47
48/*=== Native unaligned read/write ===*/
49MEM_STATIC U16 MEM_read16(const void* memPtr);
50MEM_STATIC U32 MEM_read32(const void* memPtr);
51MEM_STATIC U64 MEM_read64(const void* memPtr);
52MEM_STATIC size_t MEM_readST(const void* memPtr);
53
54MEM_STATIC void MEM_write16(void* memPtr, U16 value);
55MEM_STATIC void MEM_write32(void* memPtr, U32 value);
56MEM_STATIC void MEM_write64(void* memPtr, U64 value);
57
58/*=== Little endian unaligned read/write ===*/
59MEM_STATIC U16 MEM_readLE16(const void* memPtr);
60MEM_STATIC U32 MEM_readLE24(const void* memPtr);
61MEM_STATIC U32 MEM_readLE32(const void* memPtr);
62MEM_STATIC U64 MEM_readLE64(const void* memPtr);
63MEM_STATIC size_t MEM_readLEST(const void* memPtr);
64
65MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val);
66MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val);
67MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32);
68MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64);
69MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val);
70
71/*=== Big endian unaligned read/write ===*/
72MEM_STATIC U32 MEM_readBE32(const void* memPtr);
73MEM_STATIC U64 MEM_readBE64(const void* memPtr);
74MEM_STATIC size_t MEM_readBEST(const void* memPtr);
75
76MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32);
77MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64);
78MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val);
79
80/*=== Byteswap ===*/
81MEM_STATIC U32 MEM_swap32(U32 in);
82MEM_STATIC U64 MEM_swap64(U64 in);
83MEM_STATIC size_t MEM_swapST(size_t in);
84
85/*-**************************************************************
86* Memory I/O Implementation
87*****************************************************************/
88MEM_STATIC unsigned MEM_32bits(void)
89{
90 return sizeof(size_t) == 4;
91}
92
93MEM_STATIC unsigned MEM_64bits(void)
94{
95 return sizeof(size_t) == 8;
96}
97
98#if defined(__LITTLE_ENDIAN)
99#define MEM_LITTLE_ENDIAN 1
100#else
101#define MEM_LITTLE_ENDIAN 0
102#endif
103
104MEM_STATIC unsigned MEM_isLittleEndian(void)
105{
106 return MEM_LITTLE_ENDIAN;
107}
108
109MEM_STATIC U16 MEM_read16(const void *memPtr)
110{
111 return get_unaligned((const U16 *)memPtr);
112}
113
114MEM_STATIC U32 MEM_read32(const void *memPtr)
115{
116 return get_unaligned((const U32 *)memPtr);
117}
118
119MEM_STATIC U64 MEM_read64(const void *memPtr)
120{
121 return get_unaligned((const U64 *)memPtr);
122}
123
124MEM_STATIC size_t MEM_readST(const void *memPtr)
125{
126 return get_unaligned((const size_t *)memPtr);
127}
128
129MEM_STATIC void MEM_write16(void *memPtr, U16 value)
130{
131 put_unaligned(value, (U16 *)memPtr);
132}
133
134MEM_STATIC void MEM_write32(void *memPtr, U32 value)
135{
136 put_unaligned(value, (U32 *)memPtr);
137}
138
139MEM_STATIC void MEM_write64(void *memPtr, U64 value)
140{
141 put_unaligned(value, (U64 *)memPtr);
142}
143
144/*=== Little endian r/w ===*/
145
146MEM_STATIC U16 MEM_readLE16(const void *memPtr)
147{
148 return get_unaligned_le16(memPtr);
149}
150
151MEM_STATIC void MEM_writeLE16(void *memPtr, U16 val)
152{
153 put_unaligned_le16(val, memPtr);
154}
155
156MEM_STATIC U32 MEM_readLE24(const void *memPtr)
157{
158 return MEM_readLE16(memPtr) + (((const BYTE *)memPtr)[2] << 16);
159}
160
161MEM_STATIC void MEM_writeLE24(void *memPtr, U32 val)
162{
163 MEM_writeLE16(memPtr, (U16)val);
164 ((BYTE *)memPtr)[2] = (BYTE)(val >> 16);
165}
166
167MEM_STATIC U32 MEM_readLE32(const void *memPtr)
168{
169 return get_unaligned_le32(memPtr);
170}
171
172MEM_STATIC void MEM_writeLE32(void *memPtr, U32 val32)
173{
174 put_unaligned_le32(val32, memPtr);
175}
176
177MEM_STATIC U64 MEM_readLE64(const void *memPtr)
178{
179 return get_unaligned_le64(memPtr);
180}
181
182MEM_STATIC void MEM_writeLE64(void *memPtr, U64 val64)
183{
184 put_unaligned_le64(val64, memPtr);
185}
186
187MEM_STATIC size_t MEM_readLEST(const void *memPtr)
188{
189 if (MEM_32bits())
190 return (size_t)MEM_readLE32(memPtr);
191 else
192 return (size_t)MEM_readLE64(memPtr);
193}
194
195MEM_STATIC void MEM_writeLEST(void *memPtr, size_t val)
196{
197 if (MEM_32bits())
198 MEM_writeLE32(memPtr, (U32)val);
199 else
200 MEM_writeLE64(memPtr, (U64)val);
201}
202
203/*=== Big endian r/w ===*/
204
205MEM_STATIC U32 MEM_readBE32(const void *memPtr)
206{
207 return get_unaligned_be32(memPtr);
208}
209
210MEM_STATIC void MEM_writeBE32(void *memPtr, U32 val32)
211{
212 put_unaligned_be32(val32, memPtr);
213}
214
215MEM_STATIC U64 MEM_readBE64(const void *memPtr)
216{
217 return get_unaligned_be64(memPtr);
218}
219
220MEM_STATIC void MEM_writeBE64(void *memPtr, U64 val64)
221{
222 put_unaligned_be64(val64, memPtr);
223}
224
225MEM_STATIC size_t MEM_readBEST(const void *memPtr)
226{
227 if (MEM_32bits())
228 return (size_t)MEM_readBE32(memPtr);
229 else
230 return (size_t)MEM_readBE64(memPtr);
231}
232
233MEM_STATIC void MEM_writeBEST(void *memPtr, size_t val)
234{
235 if (MEM_32bits())
236 MEM_writeBE32(memPtr, (U32)val);
237 else
238 MEM_writeBE64(memPtr, (U64)val);
239}
240
241MEM_STATIC U32 MEM_swap32(U32 in)
242{
243 return swab32(in);
244}
245
246MEM_STATIC U64 MEM_swap64(U64 in)
247{
248 return swab64(in);
249}
250
251MEM_STATIC size_t MEM_swapST(size_t in)
252{
253 if (MEM_32bits())
254 return (size_t)MEM_swap32((U32)in);
255 else
256 return (size_t)MEM_swap64((U64)in);
257}
258
259#endif /* MEM_H_MODULE */