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_AOM_PORTS_MEM_OPS_ALIGNED_H_ 13 #define AOM_AOM_PORTS_MEM_OPS_ALIGNED_H_ 14 15 #include "aom/aom_integer.h" 16 17 /* \file 18 * \brief Provides portable memory access primitives for operating on aligned 19 * data 20 * 21 * This file is split from mem_ops.h for easier maintenance. See mem_ops.h 22 * for a more detailed description of these primitives. 23 */ 24 #ifndef INCLUDED_BY_MEM_OPS_H 25 #error Include mem_ops.h, not mem_ops_aligned.h directly. 26 #endif 27 28 /* Architectures that provide instructions for doing this byte swapping 29 * could redefine these macros. 30 */ 31 #define swap_endian_16(val, raw) \ 32 do { \ 33 val = (uint16_t)(((raw >> 8) & 0x00ff) | ((raw << 8) & 0xff00)); \ 34 } while (0) 35 #define swap_endian_32(val, raw) \ 36 do { \ 37 val = ((raw >> 24) & 0x000000ff) | ((raw >> 8) & 0x0000ff00) | \ 38 ((raw << 8) & 0x00ff0000) | ((raw << 24) & 0xff000000); \ 39 } while (0) 40 #define swap_endian_16_se(val, raw) \ 41 do { \ 42 swap_endian_16(val, raw); \ 43 val = ((val << 16) >> 16); \ 44 } while (0) 45 #define swap_endian_32_se(val, raw) swap_endian_32(val, raw) 46 47 #define mem_get_ne_aligned_generic(end, sz) \ 48 static AOM_INLINE unsigned MEM_VALUE_T mem_get_##end##sz##_aligned( \ 49 const void *vmem) { \ 50 const uint##sz##_t *mem = (const uint##sz##_t *)vmem; \ 51 return *mem; \ 52 } 53 54 #define mem_get_sne_aligned_generic(end, sz) \ 55 static AOM_INLINE signed MEM_VALUE_T mem_get_s##end##sz##_aligned( \ 56 const void *vmem) { \ 57 const int##sz##_t *mem = (const int##sz##_t *)vmem; \ 58 return *mem; \ 59 } 60 61 #define mem_get_se_aligned_generic(end, sz) \ 62 static AOM_INLINE unsigned MEM_VALUE_T mem_get_##end##sz##_aligned( \ 63 const void *vmem) { \ 64 const uint##sz##_t *mem = (const uint##sz##_t *)vmem; \ 65 unsigned MEM_VALUE_T val, raw = *mem; \ 66 swap_endian_##sz(val, raw); \ 67 return val; \ 68 } 69 70 #define mem_get_sse_aligned_generic(end, sz) \ 71 static AOM_INLINE signed MEM_VALUE_T mem_get_s##end##sz##_aligned( \ 72 const void *vmem) { \ 73 const int##sz##_t *mem = (const int##sz##_t *)vmem; \ 74 unsigned MEM_VALUE_T val, raw = *mem; \ 75 swap_endian_##sz##_se(val, raw); \ 76 return val; \ 77 } 78 79 #define mem_put_ne_aligned_generic(end, sz) \ 80 static AOM_INLINE void mem_put_##end##sz##_aligned(void *vmem, \ 81 MEM_VALUE_T val) { \ 82 uint##sz##_t *mem = (uint##sz##_t *)vmem; \ 83 *mem = (uint##sz##_t)val; \ 84 } 85 86 #define mem_put_se_aligned_generic(end, sz) \ 87 static AOM_INLINE void mem_put_##end##sz##_aligned(void *vmem, \ 88 MEM_VALUE_T val) { \ 89 uint##sz##_t *mem = (uint##sz##_t *)vmem, raw; \ 90 swap_endian_##sz(raw, val); \ 91 *mem = (uint##sz##_t)raw; \ 92 } 93 94 #include "config/aom_config.h" 95 96 #if CONFIG_BIG_ENDIAN 97 #define mem_get_be_aligned_generic(sz) mem_get_ne_aligned_generic(be, sz) 98 #define mem_get_sbe_aligned_generic(sz) mem_get_sne_aligned_generic(be, sz) 99 #define mem_get_le_aligned_generic(sz) mem_get_se_aligned_generic(le, sz) 100 #define mem_get_sle_aligned_generic(sz) mem_get_sse_aligned_generic(le, sz) 101 #define mem_put_be_aligned_generic(sz) mem_put_ne_aligned_generic(be, sz) 102 #define mem_put_le_aligned_generic(sz) mem_put_se_aligned_generic(le, sz) 103 #else 104 #define mem_get_be_aligned_generic(sz) mem_get_se_aligned_generic(be, sz) 105 #define mem_get_sbe_aligned_generic(sz) mem_get_sse_aligned_generic(be, sz) 106 #define mem_get_le_aligned_generic(sz) mem_get_ne_aligned_generic(le, sz) 107 #define mem_get_sle_aligned_generic(sz) mem_get_sne_aligned_generic(le, sz) 108 #define mem_put_be_aligned_generic(sz) mem_put_se_aligned_generic(be, sz) 109 #define mem_put_le_aligned_generic(sz) mem_put_ne_aligned_generic(le, sz) 110 #endif 111 112 /* clang-format off */ 113 #undef mem_get_be16_aligned 114 #define mem_get_be16_aligned mem_ops_wrap_symbol(mem_get_be16_aligned) 115 mem_get_be_aligned_generic(16) 116 117 #undef mem_get_be32_aligned 118 #define mem_get_be32_aligned mem_ops_wrap_symbol(mem_get_be32_aligned) 119 mem_get_be_aligned_generic(32) 120 121 #undef mem_get_le16_aligned 122 #define mem_get_le16_aligned mem_ops_wrap_symbol(mem_get_le16_aligned) 123 mem_get_le_aligned_generic(16) 124 125 #undef mem_get_le32_aligned 126 #define mem_get_le32_aligned mem_ops_wrap_symbol(mem_get_le32_aligned) 127 mem_get_le_aligned_generic(32) 128 129 #undef mem_get_sbe16_aligned 130 #define mem_get_sbe16_aligned mem_ops_wrap_symbol(mem_get_sbe16_aligned) 131 mem_get_sbe_aligned_generic(16) 132 133 #undef mem_get_sbe32_aligned 134 #define mem_get_sbe32_aligned mem_ops_wrap_symbol(mem_get_sbe32_aligned) 135 mem_get_sbe_aligned_generic(32) 136 137 #undef mem_get_sle16_aligned 138 #define mem_get_sle16_aligned mem_ops_wrap_symbol(mem_get_sle16_aligned) 139 mem_get_sle_aligned_generic(16) 140 141 #undef mem_get_sle32_aligned 142 #define mem_get_sle32_aligned mem_ops_wrap_symbol(mem_get_sle32_aligned) 143 mem_get_sle_aligned_generic(32) 144 145 #undef mem_put_be16_aligned 146 #define mem_put_be16_aligned mem_ops_wrap_symbol(mem_put_be16_aligned) 147 mem_put_be_aligned_generic(16) 148 149 #undef mem_put_be32_aligned 150 #define mem_put_be32_aligned mem_ops_wrap_symbol(mem_put_be32_aligned) 151 mem_put_be_aligned_generic(32) 152 153 #undef mem_put_le16_aligned 154 #define mem_put_le16_aligned mem_ops_wrap_symbol(mem_put_le16_aligned) 155 mem_put_le_aligned_generic(16) 156 157 #undef mem_put_le32_aligned 158 #define mem_put_le32_aligned mem_ops_wrap_symbol(mem_put_le32_aligned) 159 mem_put_le_aligned_generic(32) 160 161 #undef mem_get_ne_aligned_generic 162 #undef mem_get_se_aligned_generic 163 #undef mem_get_sne_aligned_generic 164 #undef mem_get_sse_aligned_generic 165 #undef mem_put_ne_aligned_generic 166 #undef mem_put_se_aligned_generic 167 #undef swap_endian_16 168 #undef swap_endian_32 169 #undef swap_endian_16_se 170 #undef swap_endian_32_se 171 /* clang-format on */ 172 173 #endif // AOM_AOM_PORTS_MEM_OPS_ALIGNED_H_ 174