blob: 2b5bc0f0fb110b210580485fb4a1fed0d4f7a52d [file] [log] [blame]
John Koleszar0ea50ce2010-05-18 11:58:33 -04001/*
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
John Koleszar0ea50ce2010-05-18 11:58:33 -04003 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -07004 * 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.
John Koleszar0ea50ce2010-05-18 11:58:33 -040010 */
11
James Zerne1cbb132018-08-22 14:10:36 -070012#ifndef AOM_AOM_PORTS_MEM_OPS_H_
13#define AOM_AOM_PORTS_MEM_OPS_H_
John Koleszar0ea50ce2010-05-18 11:58:33 -040014
James Zernf42d52e2011-02-16 17:54:49 -080015/* \file
16 * \brief Provides portable memory access primitives
John Koleszar0ea50ce2010-05-18 11:58:33 -040017 *
James Zernf42d52e2011-02-16 17:54:49 -080018 * This function provides portable primitives for getting and setting of
John Koleszar0ea50ce2010-05-18 11:58:33 -040019 * 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
clang-format05ce8502016-08-10 18:23:43 -070050#undef mem_ops_wrap_symbol
John Koleszar0ea50ce2010-05-18 11:58:33 -040051#define mem_ops_wrap_symbol(fn) mem_ops_wrap_symbol2(fn, MEM_VALUE_T)
clang-format05ce8502016-08-10 18:23:43 -070052#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
John Koleszar0ea50ce2010-05-18 11:58:33 -040056
57/*
58 * Include aligned access routines
59 */
60#define INCLUDED_BY_MEM_OPS_H
61#include "mem_ops_aligned.h"
clang-format05ce8502016-08-10 18:23:43 -070062#undef INCLUDED_BY_MEM_OPS_H
John Koleszar0ea50ce2010-05-18 11:58:33 -040063
clang-format05ce8502016-08-10 18:23:43 -070064#undef mem_get_be16
John Koleszar0ea50ce2010-05-18 11:58:33 -040065#define mem_get_be16 mem_ops_wrap_symbol(mem_get_be16)
John Koleszarc6b90392012-07-13 15:21:29 -070066static unsigned MEM_VALUE_T mem_get_be16(const void *vmem) {
clang-format05ce8502016-08-10 18:23:43 -070067 unsigned MEM_VALUE_T val;
68 const MAU_T *mem = (const MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -040069
John Koleszarc6b90392012-07-13 15:21:29 -070070 val = mem[0] << 8;
71 val |= mem[1];
72 return val;
John Koleszar0ea50ce2010-05-18 11:58:33 -040073}
74
clang-format05ce8502016-08-10 18:23:43 -070075#undef mem_get_be24
John Koleszar0ea50ce2010-05-18 11:58:33 -040076#define mem_get_be24 mem_ops_wrap_symbol(mem_get_be24)
John Koleszarc6b90392012-07-13 15:21:29 -070077static unsigned MEM_VALUE_T mem_get_be24(const void *vmem) {
clang-format05ce8502016-08-10 18:23:43 -070078 unsigned MEM_VALUE_T val;
79 const MAU_T *mem = (const MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -040080
John Koleszarc6b90392012-07-13 15:21:29 -070081 val = mem[0] << 16;
82 val |= mem[1] << 8;
83 val |= mem[2];
84 return val;
John Koleszar0ea50ce2010-05-18 11:58:33 -040085}
86
clang-format05ce8502016-08-10 18:23:43 -070087#undef mem_get_be32
John Koleszar0ea50ce2010-05-18 11:58:33 -040088#define mem_get_be32 mem_ops_wrap_symbol(mem_get_be32)
John Koleszarc6b90392012-07-13 15:21:29 -070089static unsigned MEM_VALUE_T mem_get_be32(const void *vmem) {
clang-format05ce8502016-08-10 18:23:43 -070090 unsigned MEM_VALUE_T val;
91 const MAU_T *mem = (const MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -040092
Tom Fineganf1de6222016-05-27 09:16:35 -070093 val = ((unsigned MEM_VALUE_T)mem[0]) << 24;
John Koleszarc6b90392012-07-13 15:21:29 -070094 val |= mem[1] << 16;
95 val |= mem[2] << 8;
96 val |= mem[3];
97 return val;
John Koleszar0ea50ce2010-05-18 11:58:33 -040098}
99
clang-format05ce8502016-08-10 18:23:43 -0700100#undef mem_get_le16
John Koleszar0ea50ce2010-05-18 11:58:33 -0400101#define mem_get_le16 mem_ops_wrap_symbol(mem_get_le16)
John Koleszarc6b90392012-07-13 15:21:29 -0700102static unsigned MEM_VALUE_T mem_get_le16(const void *vmem) {
clang-format05ce8502016-08-10 18:23:43 -0700103 unsigned MEM_VALUE_T val;
104 const MAU_T *mem = (const MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400105
John Koleszarc6b90392012-07-13 15:21:29 -0700106 val = mem[1] << 8;
107 val |= mem[0];
108 return val;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400109}
110
clang-format05ce8502016-08-10 18:23:43 -0700111#undef mem_get_le24
John Koleszar0ea50ce2010-05-18 11:58:33 -0400112#define mem_get_le24 mem_ops_wrap_symbol(mem_get_le24)
John Koleszarc6b90392012-07-13 15:21:29 -0700113static unsigned MEM_VALUE_T mem_get_le24(const void *vmem) {
clang-format05ce8502016-08-10 18:23:43 -0700114 unsigned MEM_VALUE_T val;
115 const MAU_T *mem = (const MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400116
John Koleszarc6b90392012-07-13 15:21:29 -0700117 val = mem[2] << 16;
118 val |= mem[1] << 8;
119 val |= mem[0];
120 return val;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400121}
122
clang-format05ce8502016-08-10 18:23:43 -0700123#undef mem_get_le32
John Koleszar0ea50ce2010-05-18 11:58:33 -0400124#define mem_get_le32 mem_ops_wrap_symbol(mem_get_le32)
John Koleszarc6b90392012-07-13 15:21:29 -0700125static unsigned MEM_VALUE_T mem_get_le32(const void *vmem) {
clang-format05ce8502016-08-10 18:23:43 -0700126 unsigned MEM_VALUE_T val;
127 const MAU_T *mem = (const MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400128
Tom Fineganf1de6222016-05-27 09:16:35 -0700129 val = ((unsigned MEM_VALUE_T)mem[3]) << 24;
John Koleszarc6b90392012-07-13 15:21:29 -0700130 val |= mem[2] << 16;
131 val |= mem[1] << 8;
132 val |= mem[0];
133 return val;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400134}
135
clang-format05ce8502016-08-10 18:23:43 -0700136#define mem_get_s_generic(end, sz) \
Yaowu Xuf883b422016-08-30 14:01:10 -0700137 static AOM_INLINE signed MEM_VALUE_T mem_get_s##end##sz(const void *vmem) { \
clang-format05ce8502016-08-10 18:23:43 -0700138 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); \
John Koleszarc6b90392012-07-13 15:21:29 -0700141 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400142
clang-format05ce8502016-08-10 18:23:43 -0700143/* clang-format off */
John Koleszar0ea50ce2010-05-18 11:58:33 -0400144#undef mem_get_sbe16
145#define mem_get_sbe16 mem_ops_wrap_symbol(mem_get_sbe16)
John Koleszar807acf12012-11-02 15:39:14 -0700146mem_get_s_generic(be, 16)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400147
148#undef mem_get_sbe24
149#define mem_get_sbe24 mem_ops_wrap_symbol(mem_get_sbe24)
John Koleszar807acf12012-11-02 15:39:14 -0700150mem_get_s_generic(be, 24)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400151
152#undef mem_get_sbe32
153#define mem_get_sbe32 mem_ops_wrap_symbol(mem_get_sbe32)
John Koleszar807acf12012-11-02 15:39:14 -0700154mem_get_s_generic(be, 32)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400155
156#undef mem_get_sle16
157#define mem_get_sle16 mem_ops_wrap_symbol(mem_get_sle16)
John Koleszar807acf12012-11-02 15:39:14 -0700158mem_get_s_generic(le, 16)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400159
160#undef mem_get_sle24
161#define mem_get_sle24 mem_ops_wrap_symbol(mem_get_sle24)
John Koleszar807acf12012-11-02 15:39:14 -0700162mem_get_s_generic(le, 24)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400163
164#undef mem_get_sle32
165#define mem_get_sle32 mem_ops_wrap_symbol(mem_get_sle32)
John Koleszar807acf12012-11-02 15:39:14 -0700166mem_get_s_generic(le, 32)
John Koleszar0ea50ce2010-05-18 11:58:33 -0400167
168#undef mem_put_be16
169#define mem_put_be16 mem_ops_wrap_symbol(mem_put_be16)
Yaowu Xuf883b422016-08-30 14:01:10 -0700170static AOM_INLINE void mem_put_be16(void *vmem, MEM_VALUE_T val) {
John Koleszarc6b90392012-07-13 15:21:29 -0700171 MAU_T *mem = (MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400172
James Zern44a9edf2016-03-30 17:02:10 -0700173 mem[0] = (MAU_T)((val >> 8) & 0xff);
174 mem[1] = (MAU_T)((val >> 0) & 0xff);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400175}
176
177#undef mem_put_be24
178#define mem_put_be24 mem_ops_wrap_symbol(mem_put_be24)
Yaowu Xuf883b422016-08-30 14:01:10 -0700179static AOM_INLINE void mem_put_be24(void *vmem, MEM_VALUE_T val) {
John Koleszarc6b90392012-07-13 15:21:29 -0700180 MAU_T *mem = (MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400181
James Zern44a9edf2016-03-30 17:02:10 -0700182 mem[0] = (MAU_T)((val >> 16) & 0xff);
183 mem[1] = (MAU_T)((val >> 8) & 0xff);
184 mem[2] = (MAU_T)((val >> 0) & 0xff);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400185}
186
187#undef mem_put_be32
188#define mem_put_be32 mem_ops_wrap_symbol(mem_put_be32)
Yaowu Xuf883b422016-08-30 14:01:10 -0700189static AOM_INLINE void mem_put_be32(void *vmem, MEM_VALUE_T val) {
John Koleszarc6b90392012-07-13 15:21:29 -0700190 MAU_T *mem = (MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400191
James Zern44a9edf2016-03-30 17:02:10 -0700192 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);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400196}
197
198#undef mem_put_le16
199#define mem_put_le16 mem_ops_wrap_symbol(mem_put_le16)
Yaowu Xuf883b422016-08-30 14:01:10 -0700200static AOM_INLINE void mem_put_le16(void *vmem, MEM_VALUE_T val) {
John Koleszarc6b90392012-07-13 15:21:29 -0700201 MAU_T *mem = (MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400202
James Zern44a9edf2016-03-30 17:02:10 -0700203 mem[0] = (MAU_T)((val >> 0) & 0xff);
204 mem[1] = (MAU_T)((val >> 8) & 0xff);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400205}
206
207#undef mem_put_le24
208#define mem_put_le24 mem_ops_wrap_symbol(mem_put_le24)
Yaowu Xuf883b422016-08-30 14:01:10 -0700209static AOM_INLINE void mem_put_le24(void *vmem, MEM_VALUE_T val) {
John Koleszarc6b90392012-07-13 15:21:29 -0700210 MAU_T *mem = (MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400211
James Zern44a9edf2016-03-30 17:02:10 -0700212 mem[0] = (MAU_T)((val >> 0) & 0xff);
213 mem[1] = (MAU_T)((val >> 8) & 0xff);
214 mem[2] = (MAU_T)((val >> 16) & 0xff);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400215}
216
217#undef mem_put_le32
218#define mem_put_le32 mem_ops_wrap_symbol(mem_put_le32)
Yaowu Xuf883b422016-08-30 14:01:10 -0700219static AOM_INLINE void mem_put_le32(void *vmem, MEM_VALUE_T val) {
John Koleszarc6b90392012-07-13 15:21:29 -0700220 MAU_T *mem = (MAU_T *)vmem;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400221
James Zern44a9edf2016-03-30 17:02:10 -0700222 mem[0] = (MAU_T)((val >> 0) & 0xff);
223 mem[1] = (MAU_T)((val >> 8) & 0xff);
224 mem[2] = (MAU_T)((val >> 16) & 0xff);
225 mem[3] = (MAU_T)((val >> 24) & 0xff);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400226}
clang-format05ce8502016-08-10 18:23:43 -0700227/* clang-format on */
James Zerne1cbb132018-08-22 14:10:36 -0700228#endif // AOM_AOM_PORTS_MEM_OPS_H_