John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 1 | /* |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 3 | * |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 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. |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 10 | */ |
| 11 | |
James Zern | e1cbb13 | 2018-08-22 14:10:36 -0700 | [diff] [blame] | 12 | #ifndef AOM_AOM_PORTS_MEM_OPS_H_ |
| 13 | #define AOM_AOM_PORTS_MEM_OPS_H_ |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 14 | |
James Zern | f42d52e | 2011-02-16 17:54:49 -0800 | [diff] [blame] | 15 | /* \file |
| 16 | * \brief Provides portable memory access primitives |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 17 | * |
James Zern | f42d52e | 2011-02-16 17:54:49 -0800 | [diff] [blame] | 18 | * This function provides portable primitives for getting and setting of |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 | |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 50 | #undef mem_ops_wrap_symbol |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 51 | #define mem_ops_wrap_symbol(fn) mem_ops_wrap_symbol2(fn, MEM_VALUE_T) |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 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 |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 56 | |
| 57 | /* |
| 58 | * Include aligned access routines |
| 59 | */ |
| 60 | #define INCLUDED_BY_MEM_OPS_H |
| 61 | #include "mem_ops_aligned.h" |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 62 | #undef INCLUDED_BY_MEM_OPS_H |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 63 | |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 64 | #undef mem_get_be16 |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 65 | #define mem_get_be16 mem_ops_wrap_symbol(mem_get_be16) |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 66 | static unsigned MEM_VALUE_T mem_get_be16(const void *vmem) { |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 67 | unsigned MEM_VALUE_T val; |
| 68 | const MAU_T *mem = (const MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 69 | |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 70 | val = mem[0] << 8; |
| 71 | val |= mem[1]; |
| 72 | return val; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 73 | } |
| 74 | |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 75 | #undef mem_get_be24 |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 76 | #define mem_get_be24 mem_ops_wrap_symbol(mem_get_be24) |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 77 | static unsigned MEM_VALUE_T mem_get_be24(const void *vmem) { |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 78 | unsigned MEM_VALUE_T val; |
| 79 | const MAU_T *mem = (const MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 80 | |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 81 | val = mem[0] << 16; |
| 82 | val |= mem[1] << 8; |
| 83 | val |= mem[2]; |
| 84 | return val; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 85 | } |
| 86 | |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 87 | #undef mem_get_be32 |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 88 | #define mem_get_be32 mem_ops_wrap_symbol(mem_get_be32) |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 89 | static unsigned MEM_VALUE_T mem_get_be32(const void *vmem) { |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 90 | unsigned MEM_VALUE_T val; |
| 91 | const MAU_T *mem = (const MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 92 | |
Tom Finegan | f1de622 | 2016-05-27 09:16:35 -0700 | [diff] [blame] | 93 | val = ((unsigned MEM_VALUE_T)mem[0]) << 24; |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 94 | val |= mem[1] << 16; |
| 95 | val |= mem[2] << 8; |
| 96 | val |= mem[3]; |
| 97 | return val; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 98 | } |
| 99 | |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 100 | #undef mem_get_le16 |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 101 | #define mem_get_le16 mem_ops_wrap_symbol(mem_get_le16) |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 102 | static unsigned MEM_VALUE_T mem_get_le16(const void *vmem) { |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 103 | unsigned MEM_VALUE_T val; |
| 104 | const MAU_T *mem = (const MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 105 | |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 106 | val = mem[1] << 8; |
| 107 | val |= mem[0]; |
| 108 | return val; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 109 | } |
| 110 | |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 111 | #undef mem_get_le24 |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 112 | #define mem_get_le24 mem_ops_wrap_symbol(mem_get_le24) |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 113 | static unsigned MEM_VALUE_T mem_get_le24(const void *vmem) { |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 114 | unsigned MEM_VALUE_T val; |
| 115 | const MAU_T *mem = (const MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 116 | |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 117 | val = mem[2] << 16; |
| 118 | val |= mem[1] << 8; |
| 119 | val |= mem[0]; |
| 120 | return val; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 121 | } |
| 122 | |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 123 | #undef mem_get_le32 |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 124 | #define mem_get_le32 mem_ops_wrap_symbol(mem_get_le32) |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 125 | static unsigned MEM_VALUE_T mem_get_le32(const void *vmem) { |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 126 | unsigned MEM_VALUE_T val; |
| 127 | const MAU_T *mem = (const MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 128 | |
Tom Finegan | f1de622 | 2016-05-27 09:16:35 -0700 | [diff] [blame] | 129 | val = ((unsigned MEM_VALUE_T)mem[3]) << 24; |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 130 | val |= mem[2] << 16; |
| 131 | val |= mem[1] << 8; |
| 132 | val |= mem[0]; |
| 133 | return val; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 134 | } |
| 135 | |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 136 | #define mem_get_s_generic(end, sz) \ |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 137 | static AOM_INLINE signed MEM_VALUE_T mem_get_s##end##sz(const void *vmem) { \ |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 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); \ |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 141 | } |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 142 | |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 143 | /* clang-format off */ |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 144 | #undef mem_get_sbe16 |
| 145 | #define mem_get_sbe16 mem_ops_wrap_symbol(mem_get_sbe16) |
John Koleszar | 807acf1 | 2012-11-02 15:39:14 -0700 | [diff] [blame] | 146 | mem_get_s_generic(be, 16) |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 147 | |
| 148 | #undef mem_get_sbe24 |
| 149 | #define mem_get_sbe24 mem_ops_wrap_symbol(mem_get_sbe24) |
John Koleszar | 807acf1 | 2012-11-02 15:39:14 -0700 | [diff] [blame] | 150 | mem_get_s_generic(be, 24) |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 151 | |
| 152 | #undef mem_get_sbe32 |
| 153 | #define mem_get_sbe32 mem_ops_wrap_symbol(mem_get_sbe32) |
John Koleszar | 807acf1 | 2012-11-02 15:39:14 -0700 | [diff] [blame] | 154 | mem_get_s_generic(be, 32) |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 155 | |
| 156 | #undef mem_get_sle16 |
| 157 | #define mem_get_sle16 mem_ops_wrap_symbol(mem_get_sle16) |
John Koleszar | 807acf1 | 2012-11-02 15:39:14 -0700 | [diff] [blame] | 158 | mem_get_s_generic(le, 16) |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 159 | |
| 160 | #undef mem_get_sle24 |
| 161 | #define mem_get_sle24 mem_ops_wrap_symbol(mem_get_sle24) |
John Koleszar | 807acf1 | 2012-11-02 15:39:14 -0700 | [diff] [blame] | 162 | mem_get_s_generic(le, 24) |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 163 | |
| 164 | #undef mem_get_sle32 |
| 165 | #define mem_get_sle32 mem_ops_wrap_symbol(mem_get_sle32) |
John Koleszar | 807acf1 | 2012-11-02 15:39:14 -0700 | [diff] [blame] | 166 | mem_get_s_generic(le, 32) |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 167 | |
| 168 | #undef mem_put_be16 |
| 169 | #define mem_put_be16 mem_ops_wrap_symbol(mem_put_be16) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 170 | static AOM_INLINE void mem_put_be16(void *vmem, MEM_VALUE_T val) { |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 171 | MAU_T *mem = (MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 172 | |
James Zern | 44a9edf | 2016-03-30 17:02:10 -0700 | [diff] [blame] | 173 | mem[0] = (MAU_T)((val >> 8) & 0xff); |
| 174 | mem[1] = (MAU_T)((val >> 0) & 0xff); |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 175 | } |
| 176 | |
| 177 | #undef mem_put_be24 |
| 178 | #define mem_put_be24 mem_ops_wrap_symbol(mem_put_be24) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 179 | static AOM_INLINE void mem_put_be24(void *vmem, MEM_VALUE_T val) { |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 180 | MAU_T *mem = (MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 181 | |
James Zern | 44a9edf | 2016-03-30 17:02:10 -0700 | [diff] [blame] | 182 | mem[0] = (MAU_T)((val >> 16) & 0xff); |
| 183 | mem[1] = (MAU_T)((val >> 8) & 0xff); |
| 184 | mem[2] = (MAU_T)((val >> 0) & 0xff); |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 185 | } |
| 186 | |
| 187 | #undef mem_put_be32 |
| 188 | #define mem_put_be32 mem_ops_wrap_symbol(mem_put_be32) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 189 | static AOM_INLINE void mem_put_be32(void *vmem, MEM_VALUE_T val) { |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 190 | MAU_T *mem = (MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 191 | |
James Zern | 44a9edf | 2016-03-30 17:02:10 -0700 | [diff] [blame] | 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); |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 196 | } |
| 197 | |
| 198 | #undef mem_put_le16 |
| 199 | #define mem_put_le16 mem_ops_wrap_symbol(mem_put_le16) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 200 | static AOM_INLINE void mem_put_le16(void *vmem, MEM_VALUE_T val) { |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 201 | MAU_T *mem = (MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 202 | |
James Zern | 44a9edf | 2016-03-30 17:02:10 -0700 | [diff] [blame] | 203 | mem[0] = (MAU_T)((val >> 0) & 0xff); |
| 204 | mem[1] = (MAU_T)((val >> 8) & 0xff); |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 205 | } |
| 206 | |
| 207 | #undef mem_put_le24 |
| 208 | #define mem_put_le24 mem_ops_wrap_symbol(mem_put_le24) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 209 | static AOM_INLINE void mem_put_le24(void *vmem, MEM_VALUE_T val) { |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 210 | MAU_T *mem = (MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 211 | |
James Zern | 44a9edf | 2016-03-30 17:02:10 -0700 | [diff] [blame] | 212 | mem[0] = (MAU_T)((val >> 0) & 0xff); |
| 213 | mem[1] = (MAU_T)((val >> 8) & 0xff); |
| 214 | mem[2] = (MAU_T)((val >> 16) & 0xff); |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 215 | } |
| 216 | |
| 217 | #undef mem_put_le32 |
| 218 | #define mem_put_le32 mem_ops_wrap_symbol(mem_put_le32) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 219 | static AOM_INLINE void mem_put_le32(void *vmem, MEM_VALUE_T val) { |
John Koleszar | c6b9039 | 2012-07-13 15:21:29 -0700 | [diff] [blame] | 220 | MAU_T *mem = (MAU_T *)vmem; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 221 | |
James Zern | 44a9edf | 2016-03-30 17:02:10 -0700 | [diff] [blame] | 222 | 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 Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 226 | } |
clang-format | 05ce850 | 2016-08-10 18:23:43 -0700 | [diff] [blame] | 227 | /* clang-format on */ |
James Zern | e1cbb13 | 2018-08-22 14:10:36 -0700 | [diff] [blame] | 228 | #endif // AOM_AOM_PORTS_MEM_OPS_H_ |