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