summaryrefslogtreecommitdiffstats
path: root/third_party/aom/aom_ports/mem_ops_aligned.h
blob: 37c36753188080a7391c849bdf247f6f4497b949 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#ifndef AOM_AOM_PORTS_MEM_OPS_ALIGNED_H_
#define AOM_AOM_PORTS_MEM_OPS_ALIGNED_H_

#include "aom/aom_integer.h"

/* \file
 * \brief Provides portable memory access primitives for operating on aligned
 *        data
 *
 * This file is split from mem_ops.h for easier maintenance. See mem_ops.h
 * for a more detailed description of these primitives.
 */
#ifndef INCLUDED_BY_MEM_OPS_H
#error Include mem_ops.h, not mem_ops_aligned.h directly.
#endif

/* Architectures that provide instructions for doing this byte swapping
 * could redefine these macros.
 */
#define swap_endian_16(val, raw)                                     \
  do {                                                               \
    val = (uint16_t)(((raw >> 8) & 0x00ff) | ((raw << 8) & 0xff00)); \
  } while (0)
#define swap_endian_32(val, raw)                                   \
  do {                                                             \
    val = ((raw >> 24) & 0x000000ff) | ((raw >> 8) & 0x0000ff00) | \
          ((raw << 8) & 0x00ff0000) | ((raw << 24) & 0xff000000);  \
  } while (0)
#define swap_endian_16_se(val, raw) \
  do {                              \
    swap_endian_16(val, raw);       \
    val = ((val << 16) >> 16);      \
  } while (0)
#define swap_endian_32_se(val, raw) swap_endian_32(val, raw)

#define mem_get_ne_aligned_generic(end, sz)                           \
  static AOM_INLINE unsigned MEM_VALUE_T mem_get_##end##sz##_aligned( \
      const void *vmem) {                                             \
    const uint##sz##_t *mem = (const uint##sz##_t *)vmem;             \
    return *mem;                                                      \
  }

#define mem_get_sne_aligned_generic(end, sz)                         \
  static AOM_INLINE signed MEM_VALUE_T mem_get_s##end##sz##_aligned( \
      const void *vmem) {                                            \
    const int##sz##_t *mem = (const int##sz##_t *)vmem;              \
    return *mem;                                                     \
  }

#define mem_get_se_aligned_generic(end, sz)                           \
  static AOM_INLINE unsigned MEM_VALUE_T mem_get_##end##sz##_aligned( \
      const void *vmem) {                                             \
    const uint##sz##_t *mem = (const uint##sz##_t *)vmem;             \
    unsigned MEM_VALUE_T val, raw = *mem;                             \
    swap_endian_##sz(val, raw);                                       \
    return val;                                                       \
  }

#define mem_get_sse_aligned_generic(end, sz)                         \
  static AOM_INLINE signed MEM_VALUE_T mem_get_s##end##sz##_aligned( \
      const void *vmem) {                                            \
    const int##sz##_t *mem = (const int##sz##_t *)vmem;              \
    unsigned MEM_VALUE_T val, raw = *mem;                            \
    swap_endian_##sz##_se(val, raw);                                 \
    return val;                                                      \
  }

#define mem_put_ne_aligned_generic(end, sz)                             \
  static AOM_INLINE void mem_put_##end##sz##_aligned(void *vmem,        \
                                                     MEM_VALUE_T val) { \
    uint##sz##_t *mem = (uint##sz##_t *)vmem;                           \
    *mem = (uint##sz##_t)val;                                           \
  }

#define mem_put_se_aligned_generic(end, sz)                             \
  static AOM_INLINE void mem_put_##end##sz##_aligned(void *vmem,        \
                                                     MEM_VALUE_T val) { \
    uint##sz##_t *mem = (uint##sz##_t *)vmem, raw;                      \
    swap_endian_##sz(raw, val);                                         \
    *mem = (uint##sz##_t)raw;                                           \
  }

#include "config/aom_config.h"

#if CONFIG_BIG_ENDIAN
#define mem_get_be_aligned_generic(sz) mem_get_ne_aligned_generic(be, sz)
#define mem_get_sbe_aligned_generic(sz) mem_get_sne_aligned_generic(be, sz)
#define mem_get_le_aligned_generic(sz) mem_get_se_aligned_generic(le, sz)
#define mem_get_sle_aligned_generic(sz) mem_get_sse_aligned_generic(le, sz)
#define mem_put_be_aligned_generic(sz) mem_put_ne_aligned_generic(be, sz)
#define mem_put_le_aligned_generic(sz) mem_put_se_aligned_generic(le, sz)
#else
#define mem_get_be_aligned_generic(sz) mem_get_se_aligned_generic(be, sz)
#define mem_get_sbe_aligned_generic(sz) mem_get_sse_aligned_generic(be, sz)
#define mem_get_le_aligned_generic(sz) mem_get_ne_aligned_generic(le, sz)
#define mem_get_sle_aligned_generic(sz) mem_get_sne_aligned_generic(le, sz)
#define mem_put_be_aligned_generic(sz) mem_put_se_aligned_generic(be, sz)
#define mem_put_le_aligned_generic(sz) mem_put_ne_aligned_generic(le, sz)
#endif

/* clang-format off */
#undef  mem_get_be16_aligned
#define mem_get_be16_aligned mem_ops_wrap_symbol(mem_get_be16_aligned)
mem_get_be_aligned_generic(16)

#undef  mem_get_be32_aligned
#define mem_get_be32_aligned mem_ops_wrap_symbol(mem_get_be32_aligned)
mem_get_be_aligned_generic(32)

#undef  mem_get_le16_aligned
#define mem_get_le16_aligned mem_ops_wrap_symbol(mem_get_le16_aligned)
mem_get_le_aligned_generic(16)

#undef  mem_get_le32_aligned
#define mem_get_le32_aligned mem_ops_wrap_symbol(mem_get_le32_aligned)
mem_get_le_aligned_generic(32)

#undef  mem_get_sbe16_aligned
#define mem_get_sbe16_aligned mem_ops_wrap_symbol(mem_get_sbe16_aligned)
mem_get_sbe_aligned_generic(16)

#undef  mem_get_sbe32_aligned
#define mem_get_sbe32_aligned mem_ops_wrap_symbol(mem_get_sbe32_aligned)
mem_get_sbe_aligned_generic(32)

#undef  mem_get_sle16_aligned
#define mem_get_sle16_aligned mem_ops_wrap_symbol(mem_get_sle16_aligned)
mem_get_sle_aligned_generic(16)

#undef  mem_get_sle32_aligned
#define mem_get_sle32_aligned mem_ops_wrap_symbol(mem_get_sle32_aligned)
mem_get_sle_aligned_generic(32)

#undef  mem_put_be16_aligned
#define mem_put_be16_aligned mem_ops_wrap_symbol(mem_put_be16_aligned)
mem_put_be_aligned_generic(16)

#undef  mem_put_be32_aligned
#define mem_put_be32_aligned mem_ops_wrap_symbol(mem_put_be32_aligned)
mem_put_be_aligned_generic(32)

#undef  mem_put_le16_aligned
#define mem_put_le16_aligned mem_ops_wrap_symbol(mem_put_le16_aligned)
mem_put_le_aligned_generic(16)

#undef  mem_put_le32_aligned
#define mem_put_le32_aligned mem_ops_wrap_symbol(mem_put_le32_aligned)
mem_put_le_aligned_generic(32)

#undef mem_get_ne_aligned_generic
#undef mem_get_se_aligned_generic
#undef mem_get_sne_aligned_generic
#undef mem_get_sse_aligned_generic
#undef mem_put_ne_aligned_generic
#undef mem_put_se_aligned_generic
#undef swap_endian_16
#undef swap_endian_32
#undef swap_endian_16_se
#undef swap_endian_32_se
/* clang-format on */

#endif  // AOM_AOM_PORTS_MEM_OPS_ALIGNED_H_