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