Line data Source code
1 : /*
2 : * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 : *
4 : * This source code is subject to the terms of the BSD 2 Clause License and
5 : * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 : * was not distributed with this source code in the LICENSE file, you can
7 : * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 : * Media Patent License 1.0 was not distributed with this source code in the
9 : * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 : */
11 :
12 : #ifndef AOM_PORTS_MEM_OPS_H_
13 : #define AOM_PORTS_MEM_OPS_H_
14 :
15 : /* \file
16 : * \brief Provides portable memory access primitives
17 : *
18 : * This function provides portable primitives for getting and setting of
19 : * signed and unsigned integers in 16, 24, and 32 bit sizes. The operations
20 : * can be performed on unaligned data regardless of hardware support for
21 : * unaligned accesses.
22 : *
23 : * The type used to pass the integral values may be changed by defining
24 : * MEM_VALUE_T with the appropriate type. The type given must be an integral
25 : * numeric type.
26 : *
27 : * The actual functions instantiated have the MEM_VALUE_T type name pasted
28 : * on to the symbol name. This allows the developer to instantiate these
29 : * operations for multiple types within the same translation unit. This is
30 : * of somewhat questionable utility, but the capability exists nonetheless.
31 : * Users not making use of this functionality should call the functions
32 : * without the type name appended, and the preprocessor will take care of
33 : * it.
34 : *
35 : * NOTE: This code is not supported on platforms where char > 1 octet ATM.
36 : */
37 :
38 : #ifndef MAU_T
39 : /* Minimum Access Unit for this target */
40 : #define MAU_T unsigned char
41 : #endif
42 :
43 : #ifndef MEM_VALUE_T
44 : #define MEM_VALUE_T int
45 : #endif
46 :
47 : #undef MEM_VALUE_T_SZ_BITS
48 : #define MEM_VALUE_T_SZ_BITS (sizeof(MEM_VALUE_T) << 3)
49 :
50 : #undef mem_ops_wrap_symbol
51 : #define mem_ops_wrap_symbol(fn) mem_ops_wrap_symbol2(fn, MEM_VALUE_T)
52 : #undef mem_ops_wrap_symbol2
53 : #define mem_ops_wrap_symbol2(fn, typ) mem_ops_wrap_symbol3(fn, typ)
54 : #undef mem_ops_wrap_symbol3
55 : #define mem_ops_wrap_symbol3(fn, typ) fn##_as_##typ
56 :
57 : /*
58 : * Include aligned access routines
59 : */
60 : #define INCLUDED_BY_MEM_OPS_H
61 : #include "mem_ops_aligned.h"
62 : #undef INCLUDED_BY_MEM_OPS_H
63 :
64 : #undef mem_get_be16
65 : #define mem_get_be16 mem_ops_wrap_symbol(mem_get_be16)
66 0 : static unsigned MEM_VALUE_T mem_get_be16(const void *vmem) {
67 : unsigned MEM_VALUE_T val;
68 0 : const MAU_T *mem = (const MAU_T *)vmem;
69 :
70 0 : val = mem[0] << 8;
71 0 : val |= mem[1];
72 0 : return val;
73 : }
74 :
75 : #undef mem_get_be24
76 : #define mem_get_be24 mem_ops_wrap_symbol(mem_get_be24)
77 0 : static unsigned MEM_VALUE_T mem_get_be24(const void *vmem) {
78 : unsigned MEM_VALUE_T val;
79 0 : const MAU_T *mem = (const MAU_T *)vmem;
80 :
81 0 : val = mem[0] << 16;
82 0 : val |= mem[1] << 8;
83 0 : val |= mem[2];
84 0 : return val;
85 : }
86 :
87 : #undef mem_get_be32
88 : #define mem_get_be32 mem_ops_wrap_symbol(mem_get_be32)
89 0 : static unsigned MEM_VALUE_T mem_get_be32(const void *vmem) {
90 : unsigned MEM_VALUE_T val;
91 0 : const MAU_T *mem = (const MAU_T *)vmem;
92 :
93 0 : val = ((unsigned MEM_VALUE_T)mem[0]) << 24;
94 0 : val |= mem[1] << 16;
95 0 : val |= mem[2] << 8;
96 0 : val |= mem[3];
97 0 : return val;
98 : }
99 :
100 : #undef mem_get_le16
101 : #define mem_get_le16 mem_ops_wrap_symbol(mem_get_le16)
102 0 : static unsigned MEM_VALUE_T mem_get_le16(const void *vmem) {
103 : unsigned MEM_VALUE_T val;
104 0 : const MAU_T *mem = (const MAU_T *)vmem;
105 :
106 0 : val = mem[1] << 8;
107 0 : val |= mem[0];
108 0 : return val;
109 : }
110 :
111 : #undef mem_get_le24
112 : #define mem_get_le24 mem_ops_wrap_symbol(mem_get_le24)
113 0 : static unsigned MEM_VALUE_T mem_get_le24(const void *vmem) {
114 : unsigned MEM_VALUE_T val;
115 0 : const MAU_T *mem = (const MAU_T *)vmem;
116 :
117 0 : val = mem[2] << 16;
118 0 : val |= mem[1] << 8;
119 0 : val |= mem[0];
120 0 : return val;
121 : }
122 :
123 : #undef mem_get_le32
124 : #define mem_get_le32 mem_ops_wrap_symbol(mem_get_le32)
125 0 : static unsigned MEM_VALUE_T mem_get_le32(const void *vmem) {
126 : unsigned MEM_VALUE_T val;
127 0 : const MAU_T *mem = (const MAU_T *)vmem;
128 :
129 0 : val = ((unsigned MEM_VALUE_T)mem[3]) << 24;
130 0 : val |= mem[2] << 16;
131 0 : val |= mem[1] << 8;
132 0 : val |= mem[0];
133 0 : return val;
134 : }
135 :
136 : #define mem_get_s_generic(end, sz) \
137 : static AOM_INLINE signed MEM_VALUE_T mem_get_s##end##sz(const void *vmem) { \
138 : const MAU_T *mem = (const MAU_T *)vmem; \
139 : signed MEM_VALUE_T val = mem_get_##end##sz(mem); \
140 : return (val << (MEM_VALUE_T_SZ_BITS - sz)) >> (MEM_VALUE_T_SZ_BITS - sz); \
141 : }
142 :
143 : /* clang-format off */
144 : #undef mem_get_sbe16
145 : #define mem_get_sbe16 mem_ops_wrap_symbol(mem_get_sbe16)
146 : mem_get_s_generic(be, 16)
147 :
148 : #undef mem_get_sbe24
149 : #define mem_get_sbe24 mem_ops_wrap_symbol(mem_get_sbe24)
150 : mem_get_s_generic(be, 24)
151 :
152 : #undef mem_get_sbe32
153 : #define mem_get_sbe32 mem_ops_wrap_symbol(mem_get_sbe32)
154 : mem_get_s_generic(be, 32)
155 :
156 : #undef mem_get_sle16
157 : #define mem_get_sle16 mem_ops_wrap_symbol(mem_get_sle16)
158 : mem_get_s_generic(le, 16)
159 :
160 : #undef mem_get_sle24
161 : #define mem_get_sle24 mem_ops_wrap_symbol(mem_get_sle24)
162 : mem_get_s_generic(le, 24)
163 :
164 : #undef mem_get_sle32
165 : #define mem_get_sle32 mem_ops_wrap_symbol(mem_get_sle32)
166 : mem_get_s_generic(le, 32)
167 :
168 : #undef mem_put_be16
169 : #define mem_put_be16 mem_ops_wrap_symbol(mem_put_be16)
170 : static AOM_INLINE void mem_put_be16(void *vmem, MEM_VALUE_T val) {
171 : MAU_T *mem = (MAU_T *)vmem;
172 :
173 : mem[0] = (MAU_T)((val >> 8) & 0xff);
174 : mem[1] = (MAU_T)((val >> 0) & 0xff);
175 : }
176 :
177 : #undef mem_put_be24
178 : #define mem_put_be24 mem_ops_wrap_symbol(mem_put_be24)
179 : static AOM_INLINE void mem_put_be24(void *vmem, MEM_VALUE_T val) {
180 : MAU_T *mem = (MAU_T *)vmem;
181 :
182 : mem[0] = (MAU_T)((val >> 16) & 0xff);
183 : mem[1] = (MAU_T)((val >> 8) & 0xff);
184 : mem[2] = (MAU_T)((val >> 0) & 0xff);
185 : }
186 :
187 : #undef mem_put_be32
188 : #define mem_put_be32 mem_ops_wrap_symbol(mem_put_be32)
189 : static AOM_INLINE void mem_put_be32(void *vmem, MEM_VALUE_T val) {
190 : MAU_T *mem = (MAU_T *)vmem;
191 :
192 : mem[0] = (MAU_T)((val >> 24) & 0xff);
193 : mem[1] = (MAU_T)((val >> 16) & 0xff);
194 : mem[2] = (MAU_T)((val >> 8) & 0xff);
195 : mem[3] = (MAU_T)((val >> 0) & 0xff);
196 : }
197 :
198 : #undef mem_put_le16
199 : #define mem_put_le16 mem_ops_wrap_symbol(mem_put_le16)
200 0 : static AOM_INLINE void mem_put_le16(void *vmem, MEM_VALUE_T val) {
201 0 : MAU_T *mem = (MAU_T *)vmem;
202 :
203 0 : mem[0] = (MAU_T)((val >> 0) & 0xff);
204 0 : mem[1] = (MAU_T)((val >> 8) & 0xff);
205 0 : }
206 :
207 : #undef mem_put_le24
208 : #define mem_put_le24 mem_ops_wrap_symbol(mem_put_le24)
209 0 : static AOM_INLINE void mem_put_le24(void *vmem, MEM_VALUE_T val) {
210 0 : MAU_T *mem = (MAU_T *)vmem;
211 :
212 0 : mem[0] = (MAU_T)((val >> 0) & 0xff);
213 0 : mem[1] = (MAU_T)((val >> 8) & 0xff);
214 0 : mem[2] = (MAU_T)((val >> 16) & 0xff);
215 0 : }
216 :
217 : #undef mem_put_le32
218 : #define mem_put_le32 mem_ops_wrap_symbol(mem_put_le32)
219 0 : static AOM_INLINE void mem_put_le32(void *vmem, MEM_VALUE_T val) {
220 0 : MAU_T *mem = (MAU_T *)vmem;
221 :
222 0 : mem[0] = (MAU_T)((val >> 0) & 0xff);
223 0 : mem[1] = (MAU_T)((val >> 8) & 0xff);
224 0 : mem[2] = (MAU_T)((val >> 16) & 0xff);
225 0 : mem[3] = (MAU_T)((val >> 24) & 0xff);
226 0 : }
227 : /* clang-format on */
228 :
229 : #endif // AOM_PORTS_MEM_OPS_H_
|