Coverage Report

Created: 2026-11-12 08:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aom/aom_dsp/x86/intrapred_avx2.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2017, 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
#include <immintrin.h>
13
14
#include "config/av1_rtcd.h"
15
#include "aom_dsp/x86/intrapred_x86.h"
16
#include "aom_dsp/x86/intrapred_utils.h"
17
#include "aom_dsp/x86/lpf_common_sse2.h"
18
19
325k
static inline __m256i dc_sum_64(const uint8_t *ref) {
20
325k
  const __m256i x0 = _mm256_loadu_si256((const __m256i *)ref);
21
325k
  const __m256i x1 = _mm256_loadu_si256((const __m256i *)(ref + 32));
22
325k
  const __m256i zero = _mm256_setzero_si256();
23
325k
  __m256i y0 = _mm256_sad_epu8(x0, zero);
24
325k
  __m256i y1 = _mm256_sad_epu8(x1, zero);
25
325k
  y0 = _mm256_add_epi64(y0, y1);
26
325k
  __m256i u0 = _mm256_permute2x128_si256(y0, y0, 1);
27
325k
  y0 = _mm256_add_epi64(u0, y0);
28
325k
  u0 = _mm256_unpackhi_epi64(y0, y0);
29
325k
  return _mm256_add_epi16(y0, u0);
30
325k
}
31
32
2.58M
static inline __m256i dc_sum_32(const uint8_t *ref) {
33
2.58M
  const __m256i x = _mm256_loadu_si256((const __m256i *)ref);
34
2.58M
  const __m256i zero = _mm256_setzero_si256();
35
2.58M
  __m256i y = _mm256_sad_epu8(x, zero);
36
2.58M
  __m256i u = _mm256_permute2x128_si256(y, y, 1);
37
2.58M
  y = _mm256_add_epi64(u, y);
38
2.58M
  u = _mm256_unpackhi_epi64(y, y);
39
2.58M
  return _mm256_add_epi16(y, u);
40
2.58M
}
41
42
static inline void row_store_32xh(const __m256i *r, int height, uint8_t *dst,
43
1.65M
                                  ptrdiff_t stride) {
44
52.4M
  for (int i = 0; i < height; ++i) {
45
50.8M
    _mm256_storeu_si256((__m256i *)dst, *r);
46
50.8M
    dst += stride;
47
50.8M
  }
48
1.65M
}
49
50
static inline void row_store_32x2xh(const __m256i *r0, const __m256i *r1,
51
                                    int height, uint8_t *dst,
52
3.56k
                                    ptrdiff_t stride) {
53
160k
  for (int i = 0; i < height; ++i) {
54
156k
    _mm256_storeu_si256((__m256i *)dst, *r0);
55
156k
    _mm256_storeu_si256((__m256i *)(dst + 32), *r1);
56
156k
    dst += stride;
57
156k
  }
58
3.56k
}
59
60
static inline void row_store_64xh(const __m256i *r, int height, uint8_t *dst,
61
230k
                                  ptrdiff_t stride) {
62
12.0M
  for (int i = 0; i < height; ++i) {
63
11.8M
    _mm256_storeu_si256((__m256i *)dst, *r);
64
11.8M
    _mm256_storeu_si256((__m256i *)(dst + 32), *r);
65
11.8M
    dst += stride;
66
11.8M
  }
67
230k
}
68
69
#if CONFIG_AV1_HIGHBITDEPTH
70
static DECLARE_ALIGNED(16, uint8_t, HighbdLoadMaskx[8][16]) = {
71
  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
72
  { 0, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
73
  { 0, 1, 0, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
74
  { 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
75
  { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 4, 5, 6, 7 },
76
  { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 4, 5 },
77
  { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3 },
78
  { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
79
};
80
81
static DECLARE_ALIGNED(16, uint8_t, HighbdEvenOddMaskx4[4][16]) = {
82
  { 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15 },
83
  { 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 4, 5, 8, 9, 12, 13 },
84
  { 0, 1, 0, 1, 4, 5, 8, 9, 12, 13, 0, 1, 6, 7, 10, 11 },
85
  { 0, 1, 0, 1, 0, 1, 6, 7, 10, 11, 14, 15, 0, 1, 8, 9 }
86
};
87
88
static DECLARE_ALIGNED(16, uint8_t, HighbdEvenOddMaskx[8][32]) = {
89
  { 0, 1, 4, 5, 8,  9,  12, 13, 16, 17, 20, 21, 24, 25, 28, 29,
90
    2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 },
91
  { 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27,
92
    0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29 },
93
  { 0, 1, 0, 1, 4, 5, 8,  9,  12, 13, 16, 17, 20, 21, 24, 25,
94
    0, 1, 0, 1, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27 },
95
  { 0, 1, 0, 1, 0, 1, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23,
96
    0, 1, 0, 1, 0, 1, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25 },
97
  { 0, 1, 0, 1, 0, 1, 0, 1, 8,  9,  12, 13, 16, 17, 20, 21,
98
    0, 1, 0, 1, 0, 1, 0, 1, 10, 11, 14, 15, 18, 19, 22, 23 },
99
  { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 10, 11, 14, 15, 18, 19,
100
    0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 12, 13, 16, 17, 20, 21 },
101
  { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 12, 13, 16, 17,
102
    0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 14, 15, 18, 19 },
103
  { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 14, 15,
104
    0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 16, 17 }
105
};
106
107
static DECLARE_ALIGNED(32, uint16_t, HighbdBaseMask[17][16]) = {
108
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
109
  { 0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
110
  { 0xffff, 0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
111
  { 0xffff, 0xffff, 0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
112
  { 0xffff, 0xffff, 0xffff, 0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
113
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
114
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115
    0 },
116
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0, 0, 0, 0, 0, 0, 0,
117
    0, 0 },
118
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0, 0, 0, 0,
119
    0, 0, 0, 0 },
120
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0,
121
    0, 0, 0, 0, 0, 0 },
122
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
123
    0xffff, 0, 0, 0, 0, 0, 0 },
124
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
125
    0xffff, 0xffff, 0, 0, 0, 0, 0 },
126
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
127
    0xffff, 0xffff, 0xffff, 0, 0, 0, 0 },
128
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
129
    0xffff, 0xffff, 0xffff, 0xffff, 0, 0, 0 },
130
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
131
    0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0, 0 },
132
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
133
    0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0 },
134
  { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
135
    0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff }
136
};
137
138
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
139
64.0k
static inline void highbd_transpose16x4_8x8_sse2(__m128i *x, __m128i *d) {
140
64.0k
  __m128i r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15;
141
142
64.0k
  r0 = _mm_unpacklo_epi16(x[0], x[1]);
143
64.0k
  r1 = _mm_unpacklo_epi16(x[2], x[3]);
144
64.0k
  r2 = _mm_unpacklo_epi16(x[4], x[5]);
145
64.0k
  r3 = _mm_unpacklo_epi16(x[6], x[7]);
146
147
64.0k
  r4 = _mm_unpacklo_epi16(x[8], x[9]);
148
64.0k
  r5 = _mm_unpacklo_epi16(x[10], x[11]);
149
64.0k
  r6 = _mm_unpacklo_epi16(x[12], x[13]);
150
64.0k
  r7 = _mm_unpacklo_epi16(x[14], x[15]);
151
152
64.0k
  r8 = _mm_unpacklo_epi32(r0, r1);
153
64.0k
  r9 = _mm_unpackhi_epi32(r0, r1);
154
64.0k
  r10 = _mm_unpacklo_epi32(r2, r3);
155
64.0k
  r11 = _mm_unpackhi_epi32(r2, r3);
156
157
64.0k
  r12 = _mm_unpacklo_epi32(r4, r5);
158
64.0k
  r13 = _mm_unpackhi_epi32(r4, r5);
159
64.0k
  r14 = _mm_unpacklo_epi32(r6, r7);
160
64.0k
  r15 = _mm_unpackhi_epi32(r6, r7);
161
162
64.0k
  r0 = _mm_unpacklo_epi64(r8, r9);
163
64.0k
  r1 = _mm_unpackhi_epi64(r8, r9);
164
64.0k
  r2 = _mm_unpacklo_epi64(r10, r11);
165
64.0k
  r3 = _mm_unpackhi_epi64(r10, r11);
166
167
64.0k
  r4 = _mm_unpacklo_epi64(r12, r13);
168
64.0k
  r5 = _mm_unpackhi_epi64(r12, r13);
169
64.0k
  r6 = _mm_unpacklo_epi64(r14, r15);
170
64.0k
  r7 = _mm_unpackhi_epi64(r14, r15);
171
172
64.0k
  d[0] = _mm_unpacklo_epi64(r0, r2);
173
64.0k
  d[1] = _mm_unpacklo_epi64(r4, r6);
174
64.0k
  d[2] = _mm_unpacklo_epi64(r1, r3);
175
64.0k
  d[3] = _mm_unpacklo_epi64(r5, r7);
176
177
64.0k
  d[4] = _mm_unpackhi_epi64(r0, r2);
178
64.0k
  d[5] = _mm_unpackhi_epi64(r4, r6);
179
64.0k
  d[6] = _mm_unpackhi_epi64(r1, r3);
180
64.0k
  d[7] = _mm_unpackhi_epi64(r5, r7);
181
64.0k
}
182
183
27.3k
static inline void highbd_transpose4x16_avx2(__m256i *x, __m256i *d) {
184
27.3k
  __m256i w0, w1, w2, w3, ww0, ww1;
185
186
27.3k
  w0 = _mm256_unpacklo_epi16(x[0], x[1]);  // 00 10 01 11 02 12 03 13
187
27.3k
  w1 = _mm256_unpacklo_epi16(x[2], x[3]);  // 20 30 21 31 22 32 23 33
188
27.3k
  w2 = _mm256_unpackhi_epi16(x[0], x[1]);  // 40 50 41 51 42 52 43 53
189
27.3k
  w3 = _mm256_unpackhi_epi16(x[2], x[3]);  // 60 70 61 71 62 72 63 73
190
191
27.3k
  ww0 = _mm256_unpacklo_epi32(w0, w1);  // 00 10 20 30 01 11 21 31
192
27.3k
  ww1 = _mm256_unpacklo_epi32(w2, w3);  // 40 50 60 70 41 51 61 71
193
194
27.3k
  d[0] = _mm256_unpacklo_epi64(ww0, ww1);  // 00 10 20 30 40 50 60 70
195
27.3k
  d[1] = _mm256_unpackhi_epi64(ww0, ww1);  // 01 11 21 31 41 51 61 71
196
197
27.3k
  ww0 = _mm256_unpackhi_epi32(w0, w1);  // 02 12 22 32 03 13 23 33
198
27.3k
  ww1 = _mm256_unpackhi_epi32(w2, w3);  // 42 52 62 72 43 53 63 73
199
200
27.3k
  d[2] = _mm256_unpacklo_epi64(ww0, ww1);  // 02 12 22 32 42 52 62 72
201
27.3k
  d[3] = _mm256_unpackhi_epi64(ww0, ww1);  // 03 13 23 33 43 53 63 73
202
27.3k
}
203
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
204
205
187k
static inline void highbd_transpose8x16_16x8_avx2(__m256i *x, __m256i *d) {
206
187k
  __m256i w0, w1, w2, w3, ww0, ww1;
207
208
187k
  w0 = _mm256_unpacklo_epi16(x[0], x[1]);  // 00 10 01 11 02 12 03 13
209
187k
  w1 = _mm256_unpacklo_epi16(x[2], x[3]);  // 20 30 21 31 22 32 23 33
210
187k
  w2 = _mm256_unpacklo_epi16(x[4], x[5]);  // 40 50 41 51 42 52 43 53
211
187k
  w3 = _mm256_unpacklo_epi16(x[6], x[7]);  // 60 70 61 71 62 72 63 73
212
213
187k
  ww0 = _mm256_unpacklo_epi32(w0, w1);  // 00 10 20 30 01 11 21 31
214
187k
  ww1 = _mm256_unpacklo_epi32(w2, w3);  // 40 50 60 70 41 51 61 71
215
216
187k
  d[0] = _mm256_unpacklo_epi64(ww0, ww1);  // 00 10 20 30 40 50 60 70
217
187k
  d[1] = _mm256_unpackhi_epi64(ww0, ww1);  // 01 11 21 31 41 51 61 71
218
219
187k
  ww0 = _mm256_unpackhi_epi32(w0, w1);  // 02 12 22 32 03 13 23 33
220
187k
  ww1 = _mm256_unpackhi_epi32(w2, w3);  // 42 52 62 72 43 53 63 73
221
222
187k
  d[2] = _mm256_unpacklo_epi64(ww0, ww1);  // 02 12 22 32 42 52 62 72
223
187k
  d[3] = _mm256_unpackhi_epi64(ww0, ww1);  // 03 13 23 33 43 53 63 73
224
225
187k
  w0 = _mm256_unpackhi_epi16(x[0], x[1]);  // 04 14 05 15 06 16 07 17
226
187k
  w1 = _mm256_unpackhi_epi16(x[2], x[3]);  // 24 34 25 35 26 36 27 37
227
187k
  w2 = _mm256_unpackhi_epi16(x[4], x[5]);  // 44 54 45 55 46 56 47 57
228
187k
  w3 = _mm256_unpackhi_epi16(x[6], x[7]);  // 64 74 65 75 66 76 67 77
229
230
187k
  ww0 = _mm256_unpacklo_epi32(w0, w1);  // 04 14 24 34 05 15 25 35
231
187k
  ww1 = _mm256_unpacklo_epi32(w2, w3);  // 44 54 64 74 45 55 65 75
232
233
187k
  d[4] = _mm256_unpacklo_epi64(ww0, ww1);  // 04 14 24 34 44 54 64 74
234
187k
  d[5] = _mm256_unpackhi_epi64(ww0, ww1);  // 05 15 25 35 45 55 65 75
235
236
187k
  ww0 = _mm256_unpackhi_epi32(w0, w1);  // 06 16 26 36 07 17 27 37
237
187k
  ww1 = _mm256_unpackhi_epi32(w2, w3);  // 46 56 66 76 47 57 67 77
238
239
187k
  d[6] = _mm256_unpacklo_epi64(ww0, ww1);  // 06 16 26 36 46 56 66 76
240
187k
  d[7] = _mm256_unpackhi_epi64(ww0, ww1);  // 07 17 27 37 47 57 67 77
241
187k
}
242
243
1.17M
static inline void highbd_transpose16x16_avx2(__m256i *x, __m256i *d) {
244
1.17M
  __m256i w0, w1, w2, w3, ww0, ww1;
245
1.17M
  __m256i dd[16];
246
1.17M
  w0 = _mm256_unpacklo_epi16(x[0], x[1]);
247
1.17M
  w1 = _mm256_unpacklo_epi16(x[2], x[3]);
248
1.17M
  w2 = _mm256_unpacklo_epi16(x[4], x[5]);
249
1.17M
  w3 = _mm256_unpacklo_epi16(x[6], x[7]);
250
251
1.17M
  ww0 = _mm256_unpacklo_epi32(w0, w1);  //
252
1.17M
  ww1 = _mm256_unpacklo_epi32(w2, w3);  //
253
254
1.17M
  dd[0] = _mm256_unpacklo_epi64(ww0, ww1);
255
1.17M
  dd[1] = _mm256_unpackhi_epi64(ww0, ww1);
256
257
1.17M
  ww0 = _mm256_unpackhi_epi32(w0, w1);  //
258
1.17M
  ww1 = _mm256_unpackhi_epi32(w2, w3);  //
259
260
1.17M
  dd[2] = _mm256_unpacklo_epi64(ww0, ww1);
261
1.17M
  dd[3] = _mm256_unpackhi_epi64(ww0, ww1);
262
263
1.17M
  w0 = _mm256_unpackhi_epi16(x[0], x[1]);
264
1.17M
  w1 = _mm256_unpackhi_epi16(x[2], x[3]);
265
1.17M
  w2 = _mm256_unpackhi_epi16(x[4], x[5]);
266
1.17M
  w3 = _mm256_unpackhi_epi16(x[6], x[7]);
267
268
1.17M
  ww0 = _mm256_unpacklo_epi32(w0, w1);  //
269
1.17M
  ww1 = _mm256_unpacklo_epi32(w2, w3);  //
270
271
1.17M
  dd[4] = _mm256_unpacklo_epi64(ww0, ww1);
272
1.17M
  dd[5] = _mm256_unpackhi_epi64(ww0, ww1);
273
274
1.17M
  ww0 = _mm256_unpackhi_epi32(w0, w1);  //
275
1.17M
  ww1 = _mm256_unpackhi_epi32(w2, w3);  //
276
277
1.17M
  dd[6] = _mm256_unpacklo_epi64(ww0, ww1);
278
1.17M
  dd[7] = _mm256_unpackhi_epi64(ww0, ww1);
279
280
1.17M
  w0 = _mm256_unpacklo_epi16(x[8], x[9]);
281
1.17M
  w1 = _mm256_unpacklo_epi16(x[10], x[11]);
282
1.17M
  w2 = _mm256_unpacklo_epi16(x[12], x[13]);
283
1.17M
  w3 = _mm256_unpacklo_epi16(x[14], x[15]);
284
285
1.17M
  ww0 = _mm256_unpacklo_epi32(w0, w1);
286
1.17M
  ww1 = _mm256_unpacklo_epi32(w2, w3);
287
288
1.17M
  dd[8] = _mm256_unpacklo_epi64(ww0, ww1);
289
1.17M
  dd[9] = _mm256_unpackhi_epi64(ww0, ww1);
290
291
1.17M
  ww0 = _mm256_unpackhi_epi32(w0, w1);
292
1.17M
  ww1 = _mm256_unpackhi_epi32(w2, w3);
293
294
1.17M
  dd[10] = _mm256_unpacklo_epi64(ww0, ww1);
295
1.17M
  dd[11] = _mm256_unpackhi_epi64(ww0, ww1);
296
297
1.17M
  w0 = _mm256_unpackhi_epi16(x[8], x[9]);
298
1.17M
  w1 = _mm256_unpackhi_epi16(x[10], x[11]);
299
1.17M
  w2 = _mm256_unpackhi_epi16(x[12], x[13]);
300
1.17M
  w3 = _mm256_unpackhi_epi16(x[14], x[15]);
301
302
1.17M
  ww0 = _mm256_unpacklo_epi32(w0, w1);
303
1.17M
  ww1 = _mm256_unpacklo_epi32(w2, w3);
304
305
1.17M
  dd[12] = _mm256_unpacklo_epi64(ww0, ww1);
306
1.17M
  dd[13] = _mm256_unpackhi_epi64(ww0, ww1);
307
308
1.17M
  ww0 = _mm256_unpackhi_epi32(w0, w1);
309
1.17M
  ww1 = _mm256_unpackhi_epi32(w2, w3);
310
311
1.17M
  dd[14] = _mm256_unpacklo_epi64(ww0, ww1);
312
1.17M
  dd[15] = _mm256_unpackhi_epi64(ww0, ww1);
313
314
10.5M
  for (int i = 0; i < 8; i++) {
315
9.38M
    d[i] = _mm256_insertf128_si256(dd[i], _mm256_castsi256_si128(dd[i + 8]), 1);
316
9.38M
    d[i + 8] = _mm256_insertf128_si256(dd[i + 8],
317
9.38M
                                       _mm256_extracti128_si256(dd[i], 1), 0);
318
9.38M
  }
319
1.17M
}
320
#endif  // CONFIG_AV1_HIGHBITDEPTH
321
322
void aom_dc_predictor_32x32_avx2(uint8_t *dst, ptrdiff_t stride,
323
1.12M
                                 const uint8_t *above, const uint8_t *left) {
324
1.12M
  const __m256i sum_above = dc_sum_32(above);
325
1.12M
  __m256i sum_left = dc_sum_32(left);
326
1.12M
  sum_left = _mm256_add_epi16(sum_left, sum_above);
327
1.12M
  const __m256i thirtytwo = _mm256_set1_epi16(32);
328
1.12M
  sum_left = _mm256_add_epi16(sum_left, thirtytwo);
329
1.12M
  sum_left = _mm256_srai_epi16(sum_left, 6);
330
1.12M
  const __m256i zero = _mm256_setzero_si256();
331
1.12M
  __m256i row = _mm256_shuffle_epi8(sum_left, zero);
332
1.12M
  row_store_32xh(&row, 32, dst, stride);
333
1.12M
}
334
335
void aom_dc_top_predictor_32x32_avx2(uint8_t *dst, ptrdiff_t stride,
336
                                     const uint8_t *above,
337
104k
                                     const uint8_t *left) {
338
104k
  __m256i sum = dc_sum_32(above);
339
104k
  (void)left;
340
341
104k
  const __m256i sixteen = _mm256_set1_epi16(16);
342
104k
  sum = _mm256_add_epi16(sum, sixteen);
343
104k
  sum = _mm256_srai_epi16(sum, 5);
344
104k
  const __m256i zero = _mm256_setzero_si256();
345
104k
  __m256i row = _mm256_shuffle_epi8(sum, zero);
346
104k
  row_store_32xh(&row, 32, dst, stride);
347
104k
}
348
349
void aom_dc_left_predictor_32x32_avx2(uint8_t *dst, ptrdiff_t stride,
350
                                      const uint8_t *above,
351
203k
                                      const uint8_t *left) {
352
203k
  __m256i sum = dc_sum_32(left);
353
203k
  (void)above;
354
355
203k
  const __m256i sixteen = _mm256_set1_epi16(16);
356
203k
  sum = _mm256_add_epi16(sum, sixteen);
357
203k
  sum = _mm256_srai_epi16(sum, 5);
358
203k
  const __m256i zero = _mm256_setzero_si256();
359
203k
  __m256i row = _mm256_shuffle_epi8(sum, zero);
360
203k
  row_store_32xh(&row, 32, dst, stride);
361
203k
}
362
363
void aom_dc_128_predictor_32x32_avx2(uint8_t *dst, ptrdiff_t stride,
364
                                     const uint8_t *above,
365
36.2k
                                     const uint8_t *left) {
366
36.2k
  (void)above;
367
36.2k
  (void)left;
368
36.2k
  const __m256i row = _mm256_set1_epi8((int8_t)0x80);
369
36.2k
  row_store_32xh(&row, 32, dst, stride);
370
36.2k
}
371
372
void aom_v_predictor_32x32_avx2(uint8_t *dst, ptrdiff_t stride,
373
27.7k
                                const uint8_t *above, const uint8_t *left) {
374
27.7k
  const __m256i row = _mm256_loadu_si256((const __m256i *)above);
375
27.7k
  (void)left;
376
27.7k
  row_store_32xh(&row, 32, dst, stride);
377
27.7k
}
378
379
// There are 32 rows togeter. This function does line:
380
// 0,1,2,3, and 16,17,18,19. The next call would do
381
// 4,5,6,7, and 20,21,22,23. So 4 times of calling
382
// would finish 32 rows.
383
static inline void h_predictor_32x8line(const __m256i *row, uint8_t *dst,
384
524k
                                        ptrdiff_t stride) {
385
524k
  __m256i t[4];
386
524k
  __m256i m = _mm256_setzero_si256();
387
524k
  const __m256i inc = _mm256_set1_epi8(4);
388
524k
  int i;
389
390
2.62M
  for (i = 0; i < 4; i++) {
391
2.09M
    t[i] = _mm256_shuffle_epi8(*row, m);
392
2.09M
    __m256i r0 = _mm256_permute2x128_si256(t[i], t[i], 0);
393
2.09M
    __m256i r1 = _mm256_permute2x128_si256(t[i], t[i], 0x11);
394
2.09M
    _mm256_storeu_si256((__m256i *)dst, r0);
395
2.09M
    _mm256_storeu_si256((__m256i *)(dst + (stride << 4)), r1);
396
2.09M
    dst += stride;
397
2.09M
    m = _mm256_add_epi8(m, inc);
398
2.09M
  }
399
524k
}
400
401
void aom_h_predictor_32x32_avx2(uint8_t *dst, ptrdiff_t stride,
402
131k
                                const uint8_t *above, const uint8_t *left) {
403
131k
  (void)above;
404
131k
  const __m256i left_col = _mm256_loadu_si256((__m256i const *)left);
405
406
131k
  __m256i u = _mm256_unpacklo_epi8(left_col, left_col);
407
408
131k
  __m256i v = _mm256_unpacklo_epi8(u, u);
409
131k
  h_predictor_32x8line(&v, dst, stride);
410
131k
  dst += stride << 2;
411
412
131k
  v = _mm256_unpackhi_epi8(u, u);
413
131k
  h_predictor_32x8line(&v, dst, stride);
414
131k
  dst += stride << 2;
415
416
131k
  u = _mm256_unpackhi_epi8(left_col, left_col);
417
418
131k
  v = _mm256_unpacklo_epi8(u, u);
419
131k
  h_predictor_32x8line(&v, dst, stride);
420
131k
  dst += stride << 2;
421
422
131k
  v = _mm256_unpackhi_epi8(u, u);
423
131k
  h_predictor_32x8line(&v, dst, stride);
424
131k
}
425
426
// -----------------------------------------------------------------------------
427
// Rectangle
428
void aom_dc_predictor_32x16_avx2(uint8_t *dst, ptrdiff_t stride,
429
115k
                                 const uint8_t *above, const uint8_t *left) {
430
115k
  const __m128i top_sum = dc_sum_32_sse2(above);
431
115k
  __m128i left_sum = dc_sum_16_sse2(left);
432
115k
  left_sum = _mm_add_epi16(top_sum, left_sum);
433
115k
  uint16_t sum = (uint16_t)_mm_cvtsi128_si32(left_sum);
434
115k
  sum += 24;
435
115k
  sum /= 48;
436
115k
  const __m256i row = _mm256_set1_epi8((int8_t)sum);
437
115k
  row_store_32xh(&row, 16, dst, stride);
438
115k
}
439
440
void aom_dc_predictor_32x64_avx2(uint8_t *dst, ptrdiff_t stride,
441
7.72k
                                 const uint8_t *above, const uint8_t *left) {
442
7.72k
  const __m256i sum_above = dc_sum_32(above);
443
7.72k
  __m256i sum_left = dc_sum_64(left);
444
7.72k
  sum_left = _mm256_add_epi16(sum_left, sum_above);
445
7.72k
  uint16_t sum = (uint16_t)_mm_cvtsi128_si32(_mm256_castsi256_si128(sum_left));
446
7.72k
  sum += 48;
447
7.72k
  sum /= 96;
448
7.72k
  const __m256i row = _mm256_set1_epi8((int8_t)sum);
449
7.72k
  row_store_32xh(&row, 64, dst, stride);
450
7.72k
}
451
452
void aom_dc_predictor_64x64_avx2(uint8_t *dst, ptrdiff_t stride,
453
104k
                                 const uint8_t *above, const uint8_t *left) {
454
104k
  const __m256i sum_above = dc_sum_64(above);
455
104k
  __m256i sum_left = dc_sum_64(left);
456
104k
  sum_left = _mm256_add_epi16(sum_left, sum_above);
457
104k
  uint16_t sum = (uint16_t)_mm_cvtsi128_si32(_mm256_castsi256_si128(sum_left));
458
104k
  sum += 64;
459
104k
  sum /= 128;
460
104k
  const __m256i row = _mm256_set1_epi8((int8_t)sum);
461
104k
  row_store_64xh(&row, 64, dst, stride);
462
104k
}
463
464
void aom_dc_predictor_64x32_avx2(uint8_t *dst, ptrdiff_t stride,
465
12.4k
                                 const uint8_t *above, const uint8_t *left) {
466
12.4k
  const __m256i sum_above = dc_sum_64(above);
467
12.4k
  __m256i sum_left = dc_sum_32(left);
468
12.4k
  sum_left = _mm256_add_epi16(sum_left, sum_above);
469
12.4k
  uint16_t sum = (uint16_t)_mm_cvtsi128_si32(_mm256_castsi256_si128(sum_left));
470
12.4k
  sum += 48;
471
12.4k
  sum /= 96;
472
12.4k
  const __m256i row = _mm256_set1_epi8((int8_t)sum);
473
12.4k
  row_store_64xh(&row, 32, dst, stride);
474
12.4k
}
475
476
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
477
void aom_dc_predictor_64x16_avx2(uint8_t *dst, ptrdiff_t stride,
478
45.5k
                                 const uint8_t *above, const uint8_t *left) {
479
45.5k
  const __m256i sum_above = dc_sum_64(above);
480
45.5k
  __m256i sum_left = _mm256_castsi128_si256(dc_sum_16_sse2(left));
481
45.5k
  sum_left = _mm256_add_epi16(sum_left, sum_above);
482
45.5k
  uint16_t sum = (uint16_t)_mm_cvtsi128_si32(_mm256_castsi256_si128(sum_left));
483
45.5k
  sum += 40;
484
45.5k
  sum /= 80;
485
45.5k
  const __m256i row = _mm256_set1_epi8((int8_t)sum);
486
45.5k
  row_store_64xh(&row, 16, dst, stride);
487
45.5k
}
488
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
489
490
void aom_dc_top_predictor_32x16_avx2(uint8_t *dst, ptrdiff_t stride,
491
                                     const uint8_t *above,
492
10.8k
                                     const uint8_t *left) {
493
10.8k
  __m256i sum = dc_sum_32(above);
494
10.8k
  (void)left;
495
496
10.8k
  const __m256i sixteen = _mm256_set1_epi16(16);
497
10.8k
  sum = _mm256_add_epi16(sum, sixteen);
498
10.8k
  sum = _mm256_srai_epi16(sum, 5);
499
10.8k
  const __m256i zero = _mm256_setzero_si256();
500
10.8k
  __m256i row = _mm256_shuffle_epi8(sum, zero);
501
10.8k
  row_store_32xh(&row, 16, dst, stride);
502
10.8k
}
503
504
void aom_dc_top_predictor_32x64_avx2(uint8_t *dst, ptrdiff_t stride,
505
                                     const uint8_t *above,
506
1.04k
                                     const uint8_t *left) {
507
1.04k
  __m256i sum = dc_sum_32(above);
508
1.04k
  (void)left;
509
510
1.04k
  const __m256i sixteen = _mm256_set1_epi16(16);
511
1.04k
  sum = _mm256_add_epi16(sum, sixteen);
512
1.04k
  sum = _mm256_srai_epi16(sum, 5);
513
1.04k
  const __m256i zero = _mm256_setzero_si256();
514
1.04k
  __m256i row = _mm256_shuffle_epi8(sum, zero);
515
1.04k
  row_store_32xh(&row, 64, dst, stride);
516
1.04k
}
517
518
void aom_dc_top_predictor_64x64_avx2(uint8_t *dst, ptrdiff_t stride,
519
                                     const uint8_t *above,
520
19.2k
                                     const uint8_t *left) {
521
19.2k
  __m256i sum = dc_sum_64(above);
522
19.2k
  (void)left;
523
524
19.2k
  const __m256i thirtytwo = _mm256_set1_epi16(32);
525
19.2k
  sum = _mm256_add_epi16(sum, thirtytwo);
526
19.2k
  sum = _mm256_srai_epi16(sum, 6);
527
19.2k
  const __m256i zero = _mm256_setzero_si256();
528
19.2k
  __m256i row = _mm256_shuffle_epi8(sum, zero);
529
19.2k
  row_store_64xh(&row, 64, dst, stride);
530
19.2k
}
531
532
void aom_dc_top_predictor_64x32_avx2(uint8_t *dst, ptrdiff_t stride,
533
                                     const uint8_t *above,
534
775
                                     const uint8_t *left) {
535
775
  __m256i sum = dc_sum_64(above);
536
775
  (void)left;
537
538
775
  const __m256i thirtytwo = _mm256_set1_epi16(32);
539
775
  sum = _mm256_add_epi16(sum, thirtytwo);
540
775
  sum = _mm256_srai_epi16(sum, 6);
541
775
  const __m256i zero = _mm256_setzero_si256();
542
775
  __m256i row = _mm256_shuffle_epi8(sum, zero);
543
775
  row_store_64xh(&row, 32, dst, stride);
544
775
}
545
546
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
547
void aom_dc_top_predictor_64x16_avx2(uint8_t *dst, ptrdiff_t stride,
548
                                     const uint8_t *above,
549
2.21k
                                     const uint8_t *left) {
550
2.21k
  __m256i sum = dc_sum_64(above);
551
2.21k
  (void)left;
552
553
2.21k
  const __m256i thirtytwo = _mm256_set1_epi16(32);
554
2.21k
  sum = _mm256_add_epi16(sum, thirtytwo);
555
2.21k
  sum = _mm256_srai_epi16(sum, 6);
556
2.21k
  const __m256i zero = _mm256_setzero_si256();
557
2.21k
  __m256i row = _mm256_shuffle_epi8(sum, zero);
558
2.21k
  row_store_64xh(&row, 16, dst, stride);
559
2.21k
}
560
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
561
562
void aom_dc_left_predictor_32x16_avx2(uint8_t *dst, ptrdiff_t stride,
563
                                      const uint8_t *above,
564
9.04k
                                      const uint8_t *left) {
565
9.04k
  __m128i sum = dc_sum_16_sse2(left);
566
9.04k
  (void)above;
567
568
9.04k
  const __m128i eight = _mm_set1_epi16(8);
569
9.04k
  sum = _mm_add_epi16(sum, eight);
570
9.04k
  sum = _mm_srai_epi16(sum, 4);
571
9.04k
  const __m128i zero = _mm_setzero_si128();
572
9.04k
  const __m128i r = _mm_shuffle_epi8(sum, zero);
573
9.04k
  const __m256i row = _mm256_inserti128_si256(_mm256_castsi128_si256(r), r, 1);
574
9.04k
  row_store_32xh(&row, 16, dst, stride);
575
9.04k
}
576
577
void aom_dc_left_predictor_32x64_avx2(uint8_t *dst, ptrdiff_t stride,
578
                                      const uint8_t *above,
579
1.32k
                                      const uint8_t *left) {
580
1.32k
  __m256i sum = dc_sum_64(left);
581
1.32k
  (void)above;
582
583
1.32k
  const __m256i thirtytwo = _mm256_set1_epi16(32);
584
1.32k
  sum = _mm256_add_epi16(sum, thirtytwo);
585
1.32k
  sum = _mm256_srai_epi16(sum, 6);
586
1.32k
  const __m256i zero = _mm256_setzero_si256();
587
1.32k
  __m256i row = _mm256_shuffle_epi8(sum, zero);
588
1.32k
  row_store_32xh(&row, 64, dst, stride);
589
1.32k
}
590
591
void aom_dc_left_predictor_64x64_avx2(uint8_t *dst, ptrdiff_t stride,
592
                                      const uint8_t *above,
593
27.5k
                                      const uint8_t *left) {
594
27.5k
  __m256i sum = dc_sum_64(left);
595
27.5k
  (void)above;
596
597
27.5k
  const __m256i thirtytwo = _mm256_set1_epi16(32);
598
27.5k
  sum = _mm256_add_epi16(sum, thirtytwo);
599
27.5k
  sum = _mm256_srai_epi16(sum, 6);
600
27.5k
  const __m256i zero = _mm256_setzero_si256();
601
27.5k
  __m256i row = _mm256_shuffle_epi8(sum, zero);
602
27.5k
  row_store_64xh(&row, 64, dst, stride);
603
27.5k
}
604
605
void aom_dc_left_predictor_64x32_avx2(uint8_t *dst, ptrdiff_t stride,
606
                                      const uint8_t *above,
607
1.27k
                                      const uint8_t *left) {
608
1.27k
  __m256i sum = dc_sum_32(left);
609
1.27k
  (void)above;
610
611
1.27k
  const __m256i sixteen = _mm256_set1_epi16(16);
612
1.27k
  sum = _mm256_add_epi16(sum, sixteen);
613
1.27k
  sum = _mm256_srai_epi16(sum, 5);
614
1.27k
  const __m256i zero = _mm256_setzero_si256();
615
1.27k
  __m256i row = _mm256_shuffle_epi8(sum, zero);
616
1.27k
  row_store_64xh(&row, 32, dst, stride);
617
1.27k
}
618
619
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
620
void aom_dc_left_predictor_64x16_avx2(uint8_t *dst, ptrdiff_t stride,
621
                                      const uint8_t *above,
622
628
                                      const uint8_t *left) {
623
628
  __m128i sum = dc_sum_16_sse2(left);
624
628
  (void)above;
625
626
628
  const __m128i eight = _mm_set1_epi16(8);
627
628
  sum = _mm_add_epi16(sum, eight);
628
628
  sum = _mm_srai_epi16(sum, 4);
629
628
  const __m128i zero = _mm_setzero_si128();
630
628
  const __m128i r = _mm_shuffle_epi8(sum, zero);
631
628
  const __m256i row = _mm256_inserti128_si256(_mm256_castsi128_si256(r), r, 1);
632
628
  row_store_64xh(&row, 16, dst, stride);
633
628
}
634
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
635
636
void aom_dc_128_predictor_32x16_avx2(uint8_t *dst, ptrdiff_t stride,
637
                                     const uint8_t *above,
638
6.24k
                                     const uint8_t *left) {
639
6.24k
  (void)above;
640
6.24k
  (void)left;
641
6.24k
  const __m256i row = _mm256_set1_epi8((int8_t)0x80);
642
6.24k
  row_store_32xh(&row, 16, dst, stride);
643
6.24k
}
644
645
void aom_dc_128_predictor_32x64_avx2(uint8_t *dst, ptrdiff_t stride,
646
                                     const uint8_t *above,
647
388
                                     const uint8_t *left) {
648
388
  (void)above;
649
388
  (void)left;
650
388
  const __m256i row = _mm256_set1_epi8((int8_t)0x80);
651
388
  row_store_32xh(&row, 64, dst, stride);
652
388
}
653
654
void aom_dc_128_predictor_64x64_avx2(uint8_t *dst, ptrdiff_t stride,
655
                                     const uint8_t *above,
656
12.7k
                                     const uint8_t *left) {
657
12.7k
  (void)above;
658
12.7k
  (void)left;
659
12.7k
  const __m256i row = _mm256_set1_epi8((int8_t)0x80);
660
12.7k
  row_store_64xh(&row, 64, dst, stride);
661
12.7k
}
662
663
void aom_dc_128_predictor_64x32_avx2(uint8_t *dst, ptrdiff_t stride,
664
                                     const uint8_t *above,
665
2.46k
                                     const uint8_t *left) {
666
2.46k
  (void)above;
667
2.46k
  (void)left;
668
2.46k
  const __m256i row = _mm256_set1_epi8((int8_t)0x80);
669
2.46k
  row_store_64xh(&row, 32, dst, stride);
670
2.46k
}
671
672
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
673
void aom_dc_128_predictor_64x16_avx2(uint8_t *dst, ptrdiff_t stride,
674
                                     const uint8_t *above,
675
1.64k
                                     const uint8_t *left) {
676
1.64k
  (void)above;
677
1.64k
  (void)left;
678
1.64k
  const __m256i row = _mm256_set1_epi8((int8_t)0x80);
679
1.64k
  row_store_64xh(&row, 16, dst, stride);
680
1.64k
}
681
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
682
683
void aom_v_predictor_32x16_avx2(uint8_t *dst, ptrdiff_t stride,
684
8.57k
                                const uint8_t *above, const uint8_t *left) {
685
8.57k
  const __m256i row = _mm256_loadu_si256((const __m256i *)above);
686
8.57k
  (void)left;
687
8.57k
  row_store_32xh(&row, 16, dst, stride);
688
8.57k
}
689
690
void aom_v_predictor_32x64_avx2(uint8_t *dst, ptrdiff_t stride,
691
534
                                const uint8_t *above, const uint8_t *left) {
692
534
  const __m256i row = _mm256_loadu_si256((const __m256i *)above);
693
534
  (void)left;
694
534
  row_store_32xh(&row, 64, dst, stride);
695
534
}
696
697
void aom_v_predictor_64x64_avx2(uint8_t *dst, ptrdiff_t stride,
698
1.93k
                                const uint8_t *above, const uint8_t *left) {
699
1.93k
  const __m256i row0 = _mm256_loadu_si256((const __m256i *)above);
700
1.93k
  const __m256i row1 = _mm256_loadu_si256((const __m256i *)(above + 32));
701
1.93k
  (void)left;
702
1.93k
  row_store_32x2xh(&row0, &row1, 64, dst, stride);
703
1.93k
}
704
705
void aom_v_predictor_64x32_avx2(uint8_t *dst, ptrdiff_t stride,
706
436
                                const uint8_t *above, const uint8_t *left) {
707
436
  const __m256i row0 = _mm256_loadu_si256((const __m256i *)above);
708
436
  const __m256i row1 = _mm256_loadu_si256((const __m256i *)(above + 32));
709
436
  (void)left;
710
436
  row_store_32x2xh(&row0, &row1, 32, dst, stride);
711
436
}
712
713
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
714
void aom_v_predictor_64x16_avx2(uint8_t *dst, ptrdiff_t stride,
715
1.19k
                                const uint8_t *above, const uint8_t *left) {
716
1.19k
  const __m256i row0 = _mm256_loadu_si256((const __m256i *)above);
717
1.19k
  const __m256i row1 = _mm256_loadu_si256((const __m256i *)(above + 32));
718
1.19k
  (void)left;
719
1.19k
  row_store_32x2xh(&row0, &row1, 16, dst, stride);
720
1.19k
}
721
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
722
723
// -----------------------------------------------------------------------------
724
// PAETH_PRED
725
726
// Return 16 16-bit pixels in one row (__m256i)
727
static inline __m256i paeth_pred(const __m256i *left, const __m256i *top,
728
83.7M
                                 const __m256i *topleft) {
729
83.7M
  const __m256i base =
730
83.7M
      _mm256_sub_epi16(_mm256_add_epi16(*top, *left), *topleft);
731
732
83.7M
  __m256i pl = _mm256_abs_epi16(_mm256_sub_epi16(base, *left));
733
83.7M
  __m256i pt = _mm256_abs_epi16(_mm256_sub_epi16(base, *top));
734
83.7M
  __m256i ptl = _mm256_abs_epi16(_mm256_sub_epi16(base, *topleft));
735
736
83.7M
  __m256i mask1 = _mm256_cmpgt_epi16(pl, pt);
737
83.7M
  mask1 = _mm256_or_si256(mask1, _mm256_cmpgt_epi16(pl, ptl));
738
83.7M
  __m256i mask2 = _mm256_cmpgt_epi16(pt, ptl);
739
740
83.7M
  pl = _mm256_andnot_si256(mask1, *left);
741
742
83.7M
  ptl = _mm256_and_si256(mask2, *topleft);
743
83.7M
  pt = _mm256_andnot_si256(mask2, *top);
744
83.7M
  pt = _mm256_or_si256(pt, ptl);
745
83.7M
  pt = _mm256_and_si256(mask1, pt);
746
747
83.7M
  return _mm256_or_si256(pt, pl);
748
83.7M
}
749
750
// Return 16 8-bit pixels in one row (__m128i)
751
static inline __m128i paeth_16x1_pred(const __m256i *left, const __m256i *top,
752
83.0M
                                      const __m256i *topleft) {
753
83.0M
  const __m256i p0 = paeth_pred(left, top, topleft);
754
83.0M
  const __m256i p1 = _mm256_permute4x64_epi64(p0, 0xe);
755
83.0M
  const __m256i p = _mm256_packus_epi16(p0, p1);
756
83.0M
  return _mm256_castsi256_si128(p);
757
83.0M
}
758
759
2.27M
static inline __m256i get_top_vector(const uint8_t *above) {
760
2.27M
  const __m128i x = _mm_load_si128((const __m128i *)above);
761
2.27M
  const __m128i zero = _mm_setzero_si128();
762
2.27M
  const __m128i t0 = _mm_unpacklo_epi8(x, zero);
763
2.27M
  const __m128i t1 = _mm_unpackhi_epi8(x, zero);
764
2.27M
  return _mm256_inserti128_si256(_mm256_castsi128_si256(t0), t1, 1);
765
2.27M
}
766
767
void aom_paeth_predictor_16x8_avx2(uint8_t *dst, ptrdiff_t stride,
768
68.3k
                                   const uint8_t *above, const uint8_t *left) {
769
68.3k
  __m128i x = _mm_loadl_epi64((const __m128i *)left);
770
68.3k
  const __m256i l = _mm256_inserti128_si256(_mm256_castsi128_si256(x), x, 1);
771
68.3k
  const __m256i tl16 = _mm256_set1_epi16((int16_t)above[-1]);
772
68.3k
  __m256i rep = _mm256_set1_epi16((short)0x8000);
773
68.3k
  const __m256i one = _mm256_set1_epi16(1);
774
68.3k
  const __m256i top = get_top_vector(above);
775
776
68.3k
  int i;
777
615k
  for (i = 0; i < 8; ++i) {
778
547k
    const __m256i l16 = _mm256_shuffle_epi8(l, rep);
779
547k
    const __m128i row = paeth_16x1_pred(&l16, &top, &tl16);
780
781
547k
    _mm_store_si128((__m128i *)dst, row);
782
547k
    dst += stride;
783
547k
    rep = _mm256_add_epi16(rep, one);
784
547k
  }
785
68.3k
}
786
787
4.23M
static inline __m256i get_left_vector(const uint8_t *left) {
788
4.23M
  const __m128i x = _mm_load_si128((const __m128i *)left);
789
4.23M
  return _mm256_inserti128_si256(_mm256_castsi128_si256(x), x, 1);
790
4.23M
}
791
792
void aom_paeth_predictor_16x16_avx2(uint8_t *dst, ptrdiff_t stride,
793
80.6k
                                    const uint8_t *above, const uint8_t *left) {
794
80.6k
  const __m256i l = get_left_vector(left);
795
80.6k
  const __m256i tl16 = _mm256_set1_epi16((int16_t)above[-1]);
796
80.6k
  __m256i rep = _mm256_set1_epi16((short)0x8000);
797
80.6k
  const __m256i one = _mm256_set1_epi16(1);
798
80.6k
  const __m256i top = get_top_vector(above);
799
800
80.6k
  int i;
801
1.37M
  for (i = 0; i < 16; ++i) {
802
1.29M
    const __m256i l16 = _mm256_shuffle_epi8(l, rep);
803
1.29M
    const __m128i row = paeth_16x1_pred(&l16, &top, &tl16);
804
805
1.29M
    _mm_store_si128((__m128i *)dst, row);
806
1.29M
    dst += stride;
807
1.29M
    rep = _mm256_add_epi16(rep, one);
808
1.29M
  }
809
80.6k
}
810
811
void aom_paeth_predictor_16x32_avx2(uint8_t *dst, ptrdiff_t stride,
812
1.17M
                                    const uint8_t *above, const uint8_t *left) {
813
1.17M
  __m256i l = get_left_vector(left);
814
1.17M
  const __m256i tl16 = _mm256_set1_epi16((int16_t)above[-1]);
815
1.17M
  __m256i rep = _mm256_set1_epi16((short)0x8000);
816
1.17M
  const __m256i one = _mm256_set1_epi16(1);
817
1.17M
  const __m256i top = get_top_vector(above);
818
819
1.17M
  int i;
820
19.9M
  for (i = 0; i < 16; ++i) {
821
18.7M
    const __m256i l16 = _mm256_shuffle_epi8(l, rep);
822
18.7M
    const __m128i row = paeth_16x1_pred(&l16, &top, &tl16);
823
824
18.7M
    _mm_store_si128((__m128i *)dst, row);
825
18.7M
    dst += stride;
826
18.7M
    rep = _mm256_add_epi16(rep, one);
827
18.7M
  }
828
829
1.17M
  l = get_left_vector(left + 16);
830
1.17M
  rep = _mm256_set1_epi16((short)0x8000);
831
19.9M
  for (i = 0; i < 16; ++i) {
832
18.7M
    const __m256i l16 = _mm256_shuffle_epi8(l, rep);
833
18.7M
    const __m128i row = paeth_16x1_pred(&l16, &top, &tl16);
834
835
18.7M
    _mm_store_si128((__m128i *)dst, row);
836
18.7M
    dst += stride;
837
18.7M
    rep = _mm256_add_epi16(rep, one);
838
18.7M
  }
839
1.17M
}
840
841
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
842
void aom_paeth_predictor_16x64_avx2(uint8_t *dst, ptrdiff_t stride,
843
295k
                                    const uint8_t *above, const uint8_t *left) {
844
295k
  const __m256i tl16 = _mm256_set1_epi16((int16_t)above[-1]);
845
295k
  const __m256i one = _mm256_set1_epi16(1);
846
295k
  const __m256i top = get_top_vector(above);
847
848
1.47M
  for (int j = 0; j < 4; ++j) {
849
1.18M
    const __m256i l = get_left_vector(left + j * 16);
850
1.18M
    __m256i rep = _mm256_set1_epi16((short)0x8000);
851
20.1M
    for (int i = 0; i < 16; ++i) {
852
18.9M
      const __m256i l16 = _mm256_shuffle_epi8(l, rep);
853
18.9M
      const __m128i row = paeth_16x1_pred(&l16, &top, &tl16);
854
855
18.9M
      _mm_store_si128((__m128i *)dst, row);
856
18.9M
      dst += stride;
857
18.9M
      rep = _mm256_add_epi16(rep, one);
858
18.9M
    }
859
1.18M
  }
860
295k
}
861
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
862
863
// Return 32 8-bit pixels in one row (__m256i)
864
static inline __m256i paeth_32x1_pred(const __m256i *left, const __m256i *top0,
865
                                      const __m256i *top1,
866
352k
                                      const __m256i *topleft) {
867
352k
  __m256i p0 = paeth_pred(left, top0, topleft);
868
352k
  __m256i p1 = _mm256_permute4x64_epi64(p0, 0xe);
869
352k
  const __m256i x0 = _mm256_packus_epi16(p0, p1);
870
871
352k
  p0 = paeth_pred(left, top1, topleft);
872
352k
  p1 = _mm256_permute4x64_epi64(p0, 0xe);
873
352k
  const __m256i x1 = _mm256_packus_epi16(p0, p1);
874
875
352k
  return _mm256_permute2x128_si256(x0, x1, 0x20);
876
352k
}
877
878
void aom_paeth_predictor_32x16_avx2(uint8_t *dst, ptrdiff_t stride,
879
22.0k
                                    const uint8_t *above, const uint8_t *left) {
880
22.0k
  const __m256i l = get_left_vector(left);
881
22.0k
  const __m256i t0 = get_top_vector(above);
882
22.0k
  const __m256i t1 = get_top_vector(above + 16);
883
22.0k
  const __m256i tl = _mm256_set1_epi16((int16_t)above[-1]);
884
22.0k
  __m256i rep = _mm256_set1_epi16((short)0x8000);
885
22.0k
  const __m256i one = _mm256_set1_epi16(1);
886
887
22.0k
  int i;
888
374k
  for (i = 0; i < 16; ++i) {
889
352k
    const __m256i l16 = _mm256_shuffle_epi8(l, rep);
890
891
352k
    const __m256i r = paeth_32x1_pred(&l16, &t0, &t1, &tl);
892
893
352k
    _mm256_storeu_si256((__m256i *)dst, r);
894
895
352k
    dst += stride;
896
352k
    rep = _mm256_add_epi16(rep, one);
897
352k
  }
898
22.0k
}
899
900
void aom_paeth_predictor_32x32_avx2(uint8_t *dst, ptrdiff_t stride,
901
198k
                                    const uint8_t *above, const uint8_t *left) {
902
198k
  __m256i l = get_left_vector(left);
903
198k
  const __m256i t0 = get_top_vector(above);
904
198k
  const __m256i t1 = get_top_vector(above + 16);
905
198k
  const __m256i tl = _mm256_set1_epi16((int16_t)above[-1]);
906
198k
  __m256i rep = _mm256_set1_epi16((short)0x8000);
907
198k
  const __m256i one = _mm256_set1_epi16(1);
908
909
198k
  int i;
910
3.37M
  for (i = 0; i < 16; ++i) {
911
3.17M
    const __m256i l16 = _mm256_shuffle_epi8(l, rep);
912
913
3.17M
    const __m128i r0 = paeth_16x1_pred(&l16, &t0, &tl);
914
3.17M
    const __m128i r1 = paeth_16x1_pred(&l16, &t1, &tl);
915
916
3.17M
    _mm_store_si128((__m128i *)dst, r0);
917
3.17M
    _mm_store_si128((__m128i *)(dst + 16), r1);
918
919
3.17M
    dst += stride;
920
3.17M
    rep = _mm256_add_epi16(rep, one);
921
3.17M
  }
922
923
198k
  l = get_left_vector(left + 16);
924
198k
  rep = _mm256_set1_epi16((short)0x8000);
925
3.37M
  for (i = 0; i < 16; ++i) {
926
3.17M
    const __m256i l16 = _mm256_shuffle_epi8(l, rep);
927
928
3.17M
    const __m128i r0 = paeth_16x1_pred(&l16, &t0, &tl);
929
3.17M
    const __m128i r1 = paeth_16x1_pred(&l16, &t1, &tl);
930
931
3.17M
    _mm_store_si128((__m128i *)dst, r0);
932
3.17M
    _mm_store_si128((__m128i *)(dst + 16), r1);
933
934
3.17M
    dst += stride;
935
3.17M
    rep = _mm256_add_epi16(rep, one);
936
3.17M
  }
937
198k
}
938
939
void aom_paeth_predictor_32x64_avx2(uint8_t *dst, ptrdiff_t stride,
940
9.39k
                                    const uint8_t *above, const uint8_t *left) {
941
9.39k
  const __m256i t0 = get_top_vector(above);
942
9.39k
  const __m256i t1 = get_top_vector(above + 16);
943
9.39k
  const __m256i tl = _mm256_set1_epi16((int16_t)above[-1]);
944
9.39k
  const __m256i one = _mm256_set1_epi16(1);
945
946
9.39k
  int i, j;
947
46.9k
  for (j = 0; j < 4; ++j) {
948
37.5k
    const __m256i l = get_left_vector(left + j * 16);
949
37.5k
    __m256i rep = _mm256_set1_epi16((short)0x8000);
950
638k
    for (i = 0; i < 16; ++i) {
951
601k
      const __m256i l16 = _mm256_shuffle_epi8(l, rep);
952
953
601k
      const __m128i r0 = paeth_16x1_pred(&l16, &t0, &tl);
954
601k
      const __m128i r1 = paeth_16x1_pred(&l16, &t1, &tl);
955
956
601k
      _mm_store_si128((__m128i *)dst, r0);
957
601k
      _mm_store_si128((__m128i *)(dst + 16), r1);
958
959
601k
      dst += stride;
960
601k
      rep = _mm256_add_epi16(rep, one);
961
601k
    }
962
37.5k
  }
963
9.39k
}
964
965
void aom_paeth_predictor_64x32_avx2(uint8_t *dst, ptrdiff_t stride,
966
4.45k
                                    const uint8_t *above, const uint8_t *left) {
967
4.45k
  const __m256i t0 = get_top_vector(above);
968
4.45k
  const __m256i t1 = get_top_vector(above + 16);
969
4.45k
  const __m256i t2 = get_top_vector(above + 32);
970
4.45k
  const __m256i t3 = get_top_vector(above + 48);
971
4.45k
  const __m256i tl = _mm256_set1_epi16((int16_t)above[-1]);
972
4.45k
  const __m256i one = _mm256_set1_epi16(1);
973
974
4.45k
  int i, j;
975
13.3k
  for (j = 0; j < 2; ++j) {
976
8.91k
    const __m256i l = get_left_vector(left + j * 16);
977
8.91k
    __m256i rep = _mm256_set1_epi16((short)0x8000);
978
151k
    for (i = 0; i < 16; ++i) {
979
142k
      const __m256i l16 = _mm256_shuffle_epi8(l, rep);
980
981
142k
      const __m128i r0 = paeth_16x1_pred(&l16, &t0, &tl);
982
142k
      const __m128i r1 = paeth_16x1_pred(&l16, &t1, &tl);
983
142k
      const __m128i r2 = paeth_16x1_pred(&l16, &t2, &tl);
984
142k
      const __m128i r3 = paeth_16x1_pred(&l16, &t3, &tl);
985
986
142k
      _mm_store_si128((__m128i *)dst, r0);
987
142k
      _mm_store_si128((__m128i *)(dst + 16), r1);
988
142k
      _mm_store_si128((__m128i *)(dst + 32), r2);
989
142k
      _mm_store_si128((__m128i *)(dst + 48), r3);
990
991
142k
      dst += stride;
992
142k
      rep = _mm256_add_epi16(rep, one);
993
142k
    }
994
8.91k
  }
995
4.45k
}
996
997
void aom_paeth_predictor_64x64_avx2(uint8_t *dst, ptrdiff_t stride,
998
37.8k
                                    const uint8_t *above, const uint8_t *left) {
999
37.8k
  const __m256i t0 = get_top_vector(above);
1000
37.8k
  const __m256i t1 = get_top_vector(above + 16);
1001
37.8k
  const __m256i t2 = get_top_vector(above + 32);
1002
37.8k
  const __m256i t3 = get_top_vector(above + 48);
1003
37.8k
  const __m256i tl = _mm256_set1_epi16((int16_t)above[-1]);
1004
37.8k
  const __m256i one = _mm256_set1_epi16(1);
1005
1006
37.8k
  int i, j;
1007
189k
  for (j = 0; j < 4; ++j) {
1008
151k
    const __m256i l = get_left_vector(left + j * 16);
1009
151k
    __m256i rep = _mm256_set1_epi16((short)0x8000);
1010
2.57M
    for (i = 0; i < 16; ++i) {
1011
2.42M
      const __m256i l16 = _mm256_shuffle_epi8(l, rep);
1012
1013
2.42M
      const __m128i r0 = paeth_16x1_pred(&l16, &t0, &tl);
1014
2.42M
      const __m128i r1 = paeth_16x1_pred(&l16, &t1, &tl);
1015
2.42M
      const __m128i r2 = paeth_16x1_pred(&l16, &t2, &tl);
1016
2.42M
      const __m128i r3 = paeth_16x1_pred(&l16, &t3, &tl);
1017
1018
2.42M
      _mm_store_si128((__m128i *)dst, r0);
1019
2.42M
      _mm_store_si128((__m128i *)(dst + 16), r1);
1020
2.42M
      _mm_store_si128((__m128i *)(dst + 32), r2);
1021
2.42M
      _mm_store_si128((__m128i *)(dst + 48), r3);
1022
1023
2.42M
      dst += stride;
1024
2.42M
      rep = _mm256_add_epi16(rep, one);
1025
2.42M
    }
1026
151k
  }
1027
37.8k
}
1028
1029
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
1030
void aom_paeth_predictor_64x16_avx2(uint8_t *dst, ptrdiff_t stride,
1031
7.55k
                                    const uint8_t *above, const uint8_t *left) {
1032
7.55k
  const __m256i t0 = get_top_vector(above);
1033
7.55k
  const __m256i t1 = get_top_vector(above + 16);
1034
7.55k
  const __m256i t2 = get_top_vector(above + 32);
1035
7.55k
  const __m256i t3 = get_top_vector(above + 48);
1036
7.55k
  const __m256i tl = _mm256_set1_epi16((int16_t)above[-1]);
1037
7.55k
  const __m256i one = _mm256_set1_epi16(1);
1038
1039
7.55k
  int i;
1040
7.55k
  const __m256i l = get_left_vector(left);
1041
7.55k
  __m256i rep = _mm256_set1_epi16((short)0x8000);
1042
128k
  for (i = 0; i < 16; ++i) {
1043
120k
    const __m256i l16 = _mm256_shuffle_epi8(l, rep);
1044
1045
120k
    const __m128i r0 = paeth_16x1_pred(&l16, &t0, &tl);
1046
120k
    const __m128i r1 = paeth_16x1_pred(&l16, &t1, &tl);
1047
120k
    const __m128i r2 = paeth_16x1_pred(&l16, &t2, &tl);
1048
120k
    const __m128i r3 = paeth_16x1_pred(&l16, &t3, &tl);
1049
1050
120k
    _mm_store_si128((__m128i *)dst, r0);
1051
120k
    _mm_store_si128((__m128i *)(dst + 16), r1);
1052
120k
    _mm_store_si128((__m128i *)(dst + 32), r2);
1053
120k
    _mm_store_si128((__m128i *)(dst + 48), r3);
1054
1055
120k
    dst += stride;
1056
120k
    rep = _mm256_add_epi16(rep, one);
1057
120k
  }
1058
7.55k
}
1059
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
1060
1061
#if CONFIG_AV1_HIGHBITDEPTH
1062
1063
static AOM_FORCE_INLINE void highbd_dr_prediction_z1_4xN_internal_avx2(
1064
382k
    int N, __m128i *dst, const uint16_t *above, int upsample_above, int dx) {
1065
382k
  const int frac_bits = 6 - upsample_above;
1066
382k
  const int max_base_x = ((N + 4) - 1) << upsample_above;
1067
1068
382k
  assert(dx > 0);
1069
  // pre-filter above pixels
1070
  // store in temp buffers:
1071
  //   above[x] * 32 + 16
1072
  //   above[x+1] - above[x]
1073
  // final pixels will be calculated as:
1074
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1075
382k
  __m256i a0, a1, a32, a16;
1076
382k
  __m256i diff, c3f;
1077
382k
  __m128i a_mbase_x, max_base_x128, base_inc128, mask128;
1078
382k
  __m128i a0_128, a1_128;
1079
382k
  a16 = _mm256_set1_epi16(16);
1080
382k
  a_mbase_x = _mm_set1_epi16(above[max_base_x]);
1081
382k
  max_base_x128 = _mm_set1_epi16(max_base_x);
1082
382k
  c3f = _mm256_set1_epi16(0x3f);
1083
1084
382k
  int x = dx;
1085
2.87M
  for (int r = 0; r < N; r++) {
1086
2.49M
    __m256i b, res, shift;
1087
2.49M
    __m128i res1;
1088
1089
2.49M
    int base = x >> frac_bits;
1090
2.49M
    if (base >= max_base_x) {
1091
8.79k
      for (int i = r; i < N; ++i) {
1092
5.07k
        dst[i] = a_mbase_x;  // save 4 values
1093
5.07k
      }
1094
3.71k
      return;
1095
3.71k
    }
1096
1097
2.49M
    a0_128 = _mm_loadu_si128((__m128i *)(above + base));
1098
2.49M
    a1_128 = _mm_loadu_si128((__m128i *)(above + base + 1));
1099
1100
2.49M
    if (upsample_above) {
1101
1.02M
      a0_128 = _mm_shuffle_epi8(a0_128, *(__m128i *)HighbdEvenOddMaskx4[0]);
1102
1.02M
      a1_128 = _mm_srli_si128(a0_128, 8);
1103
1104
1.02M
      base_inc128 = _mm_setr_epi16(base, base + 2, base + 4, base + 6, base + 8,
1105
1.02M
                                   base + 10, base + 12, base + 14);
1106
1.02M
      shift = _mm256_srli_epi16(
1107
1.02M
          _mm256_and_si256(
1108
1.02M
              _mm256_slli_epi16(_mm256_set1_epi16(x), upsample_above),
1109
1.02M
              _mm256_set1_epi16(0x3f)),
1110
1.02M
          1);
1111
1.47M
    } else {
1112
1.47M
      base_inc128 = _mm_setr_epi16(base, base + 1, base + 2, base + 3, base + 4,
1113
1.47M
                                   base + 5, base + 6, base + 7);
1114
1.47M
      shift = _mm256_srli_epi16(_mm256_and_si256(_mm256_set1_epi16(x), c3f), 1);
1115
1.47M
    }
1116
2.49M
    a0 = _mm256_castsi128_si256(a0_128);
1117
2.49M
    a1 = _mm256_castsi128_si256(a1_128);
1118
2.49M
    diff = _mm256_sub_epi16(a1, a0);   // a[x+1] - a[x]
1119
2.49M
    a32 = _mm256_slli_epi16(a0, 5);    // a[x] * 32
1120
2.49M
    a32 = _mm256_add_epi16(a32, a16);  // a[x] * 32 + 16
1121
1122
2.49M
    b = _mm256_mullo_epi16(diff, shift);
1123
2.49M
    res = _mm256_add_epi16(a32, b);
1124
2.49M
    res = _mm256_srli_epi16(res, 5);
1125
2.49M
    res1 = _mm256_castsi256_si128(res);
1126
1127
2.49M
    mask128 = _mm_cmpgt_epi16(max_base_x128, base_inc128);
1128
2.49M
    dst[r] = _mm_blendv_epi8(a_mbase_x, res1, mask128);
1129
2.49M
    x += dx;
1130
2.49M
  }
1131
382k
}
1132
1133
static AOM_FORCE_INLINE void highbd_dr_prediction_32bit_z1_4xN_internal_avx2(
1134
183k
    int N, __m128i *dst, const uint16_t *above, int upsample_above, int dx) {
1135
183k
  const int frac_bits = 6 - upsample_above;
1136
183k
  const int max_base_x = ((N + 4) - 1) << upsample_above;
1137
1138
183k
  assert(dx > 0);
1139
  // pre-filter above pixels
1140
  // store in temp buffers:
1141
  //   above[x] * 32 + 16
1142
  //   above[x+1] - above[x]
1143
  // final pixels will be calculated as:
1144
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1145
183k
  __m256i a0, a1, a32, a16;
1146
183k
  __m256i diff;
1147
183k
  __m128i a_mbase_x, max_base_x128, base_inc128, mask128;
1148
1149
183k
  a16 = _mm256_set1_epi32(16);
1150
183k
  a_mbase_x = _mm_set1_epi16(above[max_base_x]);
1151
183k
  max_base_x128 = _mm_set1_epi32(max_base_x);
1152
1153
183k
  int x = dx;
1154
1.49M
  for (int r = 0; r < N; r++) {
1155
1.31M
    __m256i b, res, shift;
1156
1.31M
    __m128i res1;
1157
1158
1.31M
    int base = x >> frac_bits;
1159
1.31M
    if (base >= max_base_x) {
1160
3.65k
      for (int i = r; i < N; ++i) {
1161
2.57k
        dst[i] = a_mbase_x;  // save 4 values
1162
2.57k
      }
1163
1.07k
      return;
1164
1.07k
    }
1165
1166
1.31M
    a0 = _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i *)(above + base)));
1167
1.31M
    a1 = _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i *)(above + base + 1)));
1168
1169
1.31M
    if (upsample_above) {
1170
204k
      a0 = _mm256_permutevar8x32_epi32(
1171
204k
          a0, _mm256_set_epi32(7, 5, 3, 1, 6, 4, 2, 0));
1172
204k
      a1 = _mm256_castsi128_si256(_mm256_extracti128_si256(a0, 1));
1173
204k
      base_inc128 = _mm_setr_epi32(base, base + 2, base + 4, base + 6);
1174
204k
      shift = _mm256_srli_epi32(
1175
204k
          _mm256_and_si256(
1176
204k
              _mm256_slli_epi32(_mm256_set1_epi32(x), upsample_above),
1177
204k
              _mm256_set1_epi32(0x3f)),
1178
204k
          1);
1179
1.11M
    } else {
1180
1.11M
      base_inc128 = _mm_setr_epi32(base, base + 1, base + 2, base + 3);
1181
1.11M
      shift = _mm256_srli_epi32(
1182
1.11M
          _mm256_and_si256(_mm256_set1_epi32(x), _mm256_set1_epi32(0x3f)), 1);
1183
1.11M
    }
1184
1185
1.31M
    diff = _mm256_sub_epi32(a1, a0);   // a[x+1] - a[x]
1186
1.31M
    a32 = _mm256_slli_epi32(a0, 5);    // a[x] * 32
1187
1.31M
    a32 = _mm256_add_epi32(a32, a16);  // a[x] * 32 + 16
1188
1189
1.31M
    b = _mm256_mullo_epi32(diff, shift);
1190
1.31M
    res = _mm256_add_epi32(a32, b);
1191
1.31M
    res = _mm256_srli_epi32(res, 5);
1192
1193
1.31M
    res1 = _mm256_castsi256_si128(res);
1194
1.31M
    res1 = _mm_packus_epi32(res1, res1);
1195
1196
1.31M
    mask128 = _mm_cmpgt_epi32(max_base_x128, base_inc128);
1197
1.31M
    mask128 = _mm_packs_epi32(mask128, mask128);  // goto 16 bit
1198
1.31M
    dst[r] = _mm_blendv_epi8(a_mbase_x, res1, mask128);
1199
1.31M
    x += dx;
1200
1.31M
  }
1201
183k
}
1202
1203
static void highbd_dr_prediction_z1_4xN_avx2(int N, uint16_t *dst,
1204
                                             ptrdiff_t stride,
1205
                                             const uint16_t *above,
1206
                                             int upsample_above, int dx,
1207
200k
                                             int bd) {
1208
200k
  __m128i dstvec[16];
1209
200k
  if (bd < 12) {
1210
110k
    highbd_dr_prediction_z1_4xN_internal_avx2(N, dstvec, above, upsample_above,
1211
110k
                                              dx);
1212
110k
  } else {
1213
90.0k
    highbd_dr_prediction_32bit_z1_4xN_internal_avx2(N, dstvec, above,
1214
90.0k
                                                    upsample_above, dx);
1215
90.0k
  }
1216
1.52M
  for (int i = 0; i < N; i++) {
1217
1.32M
    _mm_storel_epi64((__m128i *)(dst + stride * i), dstvec[i]);
1218
1.32M
  }
1219
200k
}
1220
1221
static AOM_FORCE_INLINE void highbd_dr_prediction_32bit_z1_8xN_internal_avx2(
1222
319k
    int N, __m128i *dst, const uint16_t *above, int upsample_above, int dx) {
1223
319k
  const int frac_bits = 6 - upsample_above;
1224
319k
  const int max_base_x = ((8 + N) - 1) << upsample_above;
1225
1226
319k
  assert(dx > 0);
1227
  // pre-filter above pixels
1228
  // store in temp buffers:
1229
  //   above[x] * 32 + 16
1230
  //   above[x+1] - above[x]
1231
  // final pixels will be calculated as:
1232
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1233
319k
  __m256i a0, a1, a0_1, a1_1, a32, a16;
1234
319k
  __m256i a_mbase_x, diff, max_base_x256, base_inc256, mask256;
1235
1236
319k
  a16 = _mm256_set1_epi32(16);
1237
319k
  a_mbase_x = _mm256_set1_epi16(above[max_base_x]);
1238
319k
  max_base_x256 = _mm256_set1_epi32(max_base_x);
1239
1240
319k
  int x = dx;
1241
3.46M
  for (int r = 0; r < N; r++) {
1242
3.15M
    __m256i b, res, res1, shift;
1243
1244
3.15M
    int base = x >> frac_bits;
1245
3.15M
    if (base >= max_base_x) {
1246
3.37k
      for (int i = r; i < N; ++i) {
1247
2.32k
        dst[i] = _mm256_castsi256_si128(a_mbase_x);  // save 8 values
1248
2.32k
      }
1249
1.05k
      return;
1250
1.05k
    }
1251
1252
3.14M
    a0 = _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i *)(above + base)));
1253
3.14M
    a1 = _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i *)(above + base + 1)));
1254
1255
3.14M
    if (upsample_above) {
1256
404k
      a0 = _mm256_permutevar8x32_epi32(
1257
404k
          a0, _mm256_set_epi32(7, 5, 3, 1, 6, 4, 2, 0));
1258
404k
      a1 = _mm256_castsi128_si256(_mm256_extracti128_si256(a0, 1));
1259
1260
404k
      a0_1 =
1261
404k
          _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i *)(above + base + 8)));
1262
404k
      a0_1 = _mm256_permutevar8x32_epi32(
1263
404k
          a0_1, _mm256_set_epi32(7, 5, 3, 1, 6, 4, 2, 0));
1264
404k
      a1_1 = _mm256_castsi128_si256(_mm256_extracti128_si256(a0_1, 1));
1265
1266
404k
      a0 = _mm256_inserti128_si256(a0, _mm256_castsi256_si128(a0_1), 1);
1267
404k
      a1 = _mm256_inserti128_si256(a1, _mm256_castsi256_si128(a1_1), 1);
1268
404k
      base_inc256 =
1269
404k
          _mm256_setr_epi32(base, base + 2, base + 4, base + 6, base + 8,
1270
404k
                            base + 10, base + 12, base + 14);
1271
404k
      shift = _mm256_srli_epi32(
1272
404k
          _mm256_and_si256(
1273
404k
              _mm256_slli_epi32(_mm256_set1_epi32(x), upsample_above),
1274
404k
              _mm256_set1_epi32(0x3f)),
1275
404k
          1);
1276
2.74M
    } else {
1277
2.74M
      base_inc256 = _mm256_setr_epi32(base, base + 1, base + 2, base + 3,
1278
2.74M
                                      base + 4, base + 5, base + 6, base + 7);
1279
2.74M
      shift = _mm256_srli_epi32(
1280
2.74M
          _mm256_and_si256(_mm256_set1_epi32(x), _mm256_set1_epi32(0x3f)), 1);
1281
2.74M
    }
1282
1283
3.14M
    diff = _mm256_sub_epi32(a1, a0);   // a[x+1] - a[x]
1284
3.14M
    a32 = _mm256_slli_epi32(a0, 5);    // a[x] * 32
1285
3.14M
    a32 = _mm256_add_epi32(a32, a16);  // a[x] * 32 + 16
1286
1287
3.14M
    b = _mm256_mullo_epi32(diff, shift);
1288
3.14M
    res = _mm256_add_epi32(a32, b);
1289
3.14M
    res = _mm256_srli_epi32(res, 5);
1290
1291
3.14M
    res1 = _mm256_packus_epi32(
1292
3.14M
        res, _mm256_castsi128_si256(_mm256_extracti128_si256(res, 1)));
1293
1294
3.14M
    mask256 = _mm256_cmpgt_epi32(max_base_x256, base_inc256);
1295
3.14M
    mask256 = _mm256_packs_epi32(
1296
3.14M
        mask256, _mm256_castsi128_si256(
1297
3.14M
                     _mm256_extracti128_si256(mask256, 1)));  // goto 16 bit
1298
3.14M
    res1 = _mm256_blendv_epi8(a_mbase_x, res1, mask256);
1299
3.14M
    dst[r] = _mm256_castsi256_si128(res1);
1300
3.14M
    x += dx;
1301
3.14M
  }
1302
319k
}
1303
1304
static AOM_FORCE_INLINE void highbd_dr_prediction_z1_8xN_internal_avx2(
1305
337k
    int N, __m128i *dst, const uint16_t *above, int upsample_above, int dx) {
1306
337k
  const int frac_bits = 6 - upsample_above;
1307
337k
  const int max_base_x = ((8 + N) - 1) << upsample_above;
1308
1309
337k
  assert(dx > 0);
1310
  // pre-filter above pixels
1311
  // store in temp buffers:
1312
  //   above[x] * 32 + 16
1313
  //   above[x+1] - above[x]
1314
  // final pixels will be calculated as:
1315
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1316
337k
  __m256i a0, a1, a32, a16, c3f;
1317
337k
  __m256i a_mbase_x, diff, max_base_x256, base_inc256, mask256;
1318
337k
  __m128i a0_x128, a1_x128;
1319
1320
337k
  a16 = _mm256_set1_epi16(16);
1321
337k
  a_mbase_x = _mm256_set1_epi16(above[max_base_x]);
1322
337k
  max_base_x256 = _mm256_set1_epi16(max_base_x);
1323
337k
  c3f = _mm256_set1_epi16(0x3f);
1324
1325
337k
  int x = dx;
1326
4.67M
  for (int r = 0; r < N; r++) {
1327
4.34M
    __m256i b, res, res1, shift;
1328
1329
4.34M
    int base = x >> frac_bits;
1330
4.34M
    if (base >= max_base_x) {
1331
6.27k
      for (int i = r; i < N; ++i) {
1332
4.49k
        dst[i] = _mm256_castsi256_si128(a_mbase_x);  // save 8 values
1333
4.49k
      }
1334
1.78k
      return;
1335
1.78k
    }
1336
1337
4.34M
    a0_x128 = _mm_loadu_si128((__m128i *)(above + base));
1338
4.34M
    if (upsample_above) {
1339
854k
      __m128i mask, atmp0, atmp1, atmp2, atmp3;
1340
854k
      a1_x128 = _mm_loadu_si128((__m128i *)(above + base + 8));
1341
854k
      atmp0 = _mm_shuffle_epi8(a0_x128, *(__m128i *)HighbdEvenOddMaskx[0]);
1342
854k
      atmp1 = _mm_shuffle_epi8(a1_x128, *(__m128i *)HighbdEvenOddMaskx[0]);
1343
854k
      atmp2 =
1344
854k
          _mm_shuffle_epi8(a0_x128, *(__m128i *)(HighbdEvenOddMaskx[0] + 16));
1345
854k
      atmp3 =
1346
854k
          _mm_shuffle_epi8(a1_x128, *(__m128i *)(HighbdEvenOddMaskx[0] + 16));
1347
854k
      mask =
1348
854k
          _mm_cmpgt_epi8(*(__m128i *)HighbdEvenOddMaskx[0], _mm_set1_epi8(15));
1349
854k
      a0_x128 = _mm_blendv_epi8(atmp0, atmp1, mask);
1350
854k
      mask = _mm_cmpgt_epi8(*(__m128i *)(HighbdEvenOddMaskx[0] + 16),
1351
854k
                            _mm_set1_epi8(15));
1352
854k
      a1_x128 = _mm_blendv_epi8(atmp2, atmp3, mask);
1353
1354
854k
      base_inc256 = _mm256_setr_epi16(base, base + 2, base + 4, base + 6,
1355
854k
                                      base + 8, base + 10, base + 12, base + 14,
1356
854k
                                      0, 0, 0, 0, 0, 0, 0, 0);
1357
854k
      shift = _mm256_srli_epi16(
1358
854k
          _mm256_and_si256(
1359
854k
              _mm256_slli_epi16(_mm256_set1_epi16(x), upsample_above), c3f),
1360
854k
          1);
1361
3.48M
    } else {
1362
3.48M
      a1_x128 = _mm_loadu_si128((__m128i *)(above + base + 1));
1363
3.48M
      base_inc256 = _mm256_setr_epi16(base, base + 1, base + 2, base + 3,
1364
3.48M
                                      base + 4, base + 5, base + 6, base + 7, 0,
1365
3.48M
                                      0, 0, 0, 0, 0, 0, 0);
1366
3.48M
      shift = _mm256_srli_epi16(_mm256_and_si256(_mm256_set1_epi16(x), c3f), 1);
1367
3.48M
    }
1368
4.34M
    a0 = _mm256_castsi128_si256(a0_x128);
1369
4.34M
    a1 = _mm256_castsi128_si256(a1_x128);
1370
1371
4.34M
    diff = _mm256_sub_epi16(a1, a0);   // a[x+1] - a[x]
1372
4.34M
    a32 = _mm256_slli_epi16(a0, 5);    // a[x] * 32
1373
4.34M
    a32 = _mm256_add_epi16(a32, a16);  // a[x] * 32 + 16
1374
1375
4.34M
    b = _mm256_mullo_epi16(diff, shift);
1376
4.34M
    res = _mm256_add_epi16(a32, b);
1377
4.34M
    res = _mm256_srli_epi16(res, 5);
1378
1379
4.34M
    mask256 = _mm256_cmpgt_epi16(max_base_x256, base_inc256);
1380
4.34M
    res1 = _mm256_blendv_epi8(a_mbase_x, res, mask256);
1381
4.34M
    dst[r] = _mm256_castsi256_si128(res1);
1382
4.34M
    x += dx;
1383
4.34M
  }
1384
337k
}
1385
1386
static void highbd_dr_prediction_z1_8xN_avx2(int N, uint16_t *dst,
1387
                                             ptrdiff_t stride,
1388
                                             const uint16_t *above,
1389
                                             int upsample_above, int dx,
1390
270k
                                             int bd) {
1391
270k
  __m128i dstvec[32];
1392
270k
  if (bd < 12) {
1393
127k
    highbd_dr_prediction_z1_8xN_internal_avx2(N, dstvec, above, upsample_above,
1394
127k
                                              dx);
1395
143k
  } else {
1396
143k
    highbd_dr_prediction_32bit_z1_8xN_internal_avx2(N, dstvec, above,
1397
143k
                                                    upsample_above, dx);
1398
143k
  }
1399
2.80M
  for (int i = 0; i < N; i++) {
1400
2.53M
    _mm_storeu_si128((__m128i *)(dst + stride * i), dstvec[i]);
1401
2.53M
  }
1402
270k
}
1403
1404
static AOM_FORCE_INLINE void highbd_dr_prediction_32bit_z1_16xN_internal_avx2(
1405
155k
    int N, __m256i *dstvec, const uint16_t *above, int upsample_above, int dx) {
1406
  // here upsample_above is 0 by design of av1_use_intra_edge_upsample
1407
155k
  (void)upsample_above;
1408
155k
  const int frac_bits = 6;
1409
155k
  const int max_base_x = ((16 + N) - 1);
1410
1411
  // pre-filter above pixels
1412
  // store in temp buffers:
1413
  //   above[x] * 32 + 16
1414
  //   above[x+1] - above[x]
1415
  // final pixels will be calculated as:
1416
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1417
155k
  __m256i a0, a0_1, a1, a1_1, a32, a16;
1418
155k
  __m256i a_mbase_x, diff, max_base_x256, base_inc256, mask256;
1419
1420
155k
  a16 = _mm256_set1_epi32(16);
1421
155k
  a_mbase_x = _mm256_set1_epi16(above[max_base_x]);
1422
155k
  max_base_x256 = _mm256_set1_epi16(max_base_x);
1423
1424
155k
  int x = dx;
1425
1.78M
  for (int r = 0; r < N; r++) {
1426
1.63M
    __m256i b, res[2], res1;
1427
1428
1.63M
    int base = x >> frac_bits;
1429
1.63M
    if (base >= max_base_x) {
1430
1.82k
      for (int i = r; i < N; ++i) {
1431
1.53k
        dstvec[i] = a_mbase_x;  // save 16 values
1432
1.53k
      }
1433
285
      return;
1434
285
    }
1435
1.63M
    __m256i shift = _mm256_srli_epi32(
1436
1.63M
        _mm256_and_si256(_mm256_set1_epi32(x), _mm256_set1_epi32(0x3f)), 1);
1437
1438
1.63M
    a0 = _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i *)(above + base)));
1439
1.63M
    a1 = _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i *)(above + base + 1)));
1440
1441
1.63M
    diff = _mm256_sub_epi32(a1, a0);   // a[x+1] - a[x]
1442
1.63M
    a32 = _mm256_slli_epi32(a0, 5);    // a[x] * 32
1443
1.63M
    a32 = _mm256_add_epi32(a32, a16);  // a[x] * 32 + 16
1444
1.63M
    b = _mm256_mullo_epi32(diff, shift);
1445
1446
1.63M
    res[0] = _mm256_add_epi32(a32, b);
1447
1.63M
    res[0] = _mm256_srli_epi32(res[0], 5);
1448
1.63M
    res[0] = _mm256_packus_epi32(
1449
1.63M
        res[0], _mm256_castsi128_si256(_mm256_extracti128_si256(res[0], 1)));
1450
1451
1.63M
    int mdif = max_base_x - base;
1452
1.63M
    if (mdif > 8) {
1453
1.62M
      a0_1 =
1454
1.62M
          _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i *)(above + base + 8)));
1455
1.62M
      a1_1 =
1456
1.62M
          _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i *)(above + base + 9)));
1457
1458
1.62M
      diff = _mm256_sub_epi32(a1_1, a0_1);  // a[x+1] - a[x]
1459
1.62M
      a32 = _mm256_slli_epi32(a0_1, 5);     // a[x] * 32
1460
1.62M
      a32 = _mm256_add_epi32(a32, a16);     // a[x] * 32 + 16
1461
1.62M
      b = _mm256_mullo_epi32(diff, shift);
1462
1463
1.62M
      res[1] = _mm256_add_epi32(a32, b);
1464
1.62M
      res[1] = _mm256_srli_epi32(res[1], 5);
1465
1.62M
      res[1] = _mm256_packus_epi32(
1466
1.62M
          res[1], _mm256_castsi128_si256(_mm256_extracti128_si256(res[1], 1)));
1467
1.62M
    } else {
1468
4.08k
      res[1] = a_mbase_x;
1469
4.08k
    }
1470
1.63M
    res1 = _mm256_inserti128_si256(res[0], _mm256_castsi256_si128(res[1]),
1471
1.63M
                                   1);  // 16 16bit values
1472
1473
1.63M
    base_inc256 = _mm256_setr_epi16(base, base + 1, base + 2, base + 3,
1474
1.63M
                                    base + 4, base + 5, base + 6, base + 7,
1475
1.63M
                                    base + 8, base + 9, base + 10, base + 11,
1476
1.63M
                                    base + 12, base + 13, base + 14, base + 15);
1477
1.63M
    mask256 = _mm256_cmpgt_epi16(max_base_x256, base_inc256);
1478
1.63M
    dstvec[r] = _mm256_blendv_epi8(a_mbase_x, res1, mask256);
1479
1.63M
    x += dx;
1480
1.63M
  }
1481
155k
}
1482
1483
static AOM_FORCE_INLINE void highbd_dr_prediction_z1_16xN_internal_avx2(
1484
305k
    int N, __m256i *dstvec, const uint16_t *above, int upsample_above, int dx) {
1485
  // here upsample_above is 0 by design of av1_use_intra_edge_upsample
1486
305k
  (void)upsample_above;
1487
305k
  const int frac_bits = 6;
1488
305k
  const int max_base_x = ((16 + N) - 1);
1489
1490
  // pre-filter above pixels
1491
  // store in temp buffers:
1492
  //   above[x] * 32 + 16
1493
  //   above[x+1] - above[x]
1494
  // final pixels will be calculated as:
1495
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1496
305k
  __m256i a0, a1, a32, a16, c3f;
1497
305k
  __m256i a_mbase_x, diff, max_base_x256, base_inc256, mask256;
1498
1499
305k
  a16 = _mm256_set1_epi16(16);
1500
305k
  a_mbase_x = _mm256_set1_epi16(above[max_base_x]);
1501
305k
  max_base_x256 = _mm256_set1_epi16(max_base_x);
1502
305k
  c3f = _mm256_set1_epi16(0x3f);
1503
1504
305k
  int x = dx;
1505
5.98M
  for (int r = 0; r < N; r++) {
1506
5.68M
    __m256i b, res;
1507
1508
5.68M
    int base = x >> frac_bits;
1509
5.68M
    if (base >= max_base_x) {
1510
3.77k
      for (int i = r; i < N; ++i) {
1511
2.94k
        dstvec[i] = a_mbase_x;  // save 16 values
1512
2.94k
      }
1513
829
      return;
1514
829
    }
1515
5.68M
    __m256i shift =
1516
5.68M
        _mm256_srli_epi16(_mm256_and_si256(_mm256_set1_epi16(x), c3f), 1);
1517
1518
5.68M
    a0 = _mm256_loadu_si256((__m256i *)(above + base));
1519
5.68M
    a1 = _mm256_loadu_si256((__m256i *)(above + base + 1));
1520
1521
5.68M
    diff = _mm256_sub_epi16(a1, a0);   // a[x+1] - a[x]
1522
5.68M
    a32 = _mm256_slli_epi16(a0, 5);    // a[x] * 32
1523
5.68M
    a32 = _mm256_add_epi16(a32, a16);  // a[x] * 32 + 16
1524
5.68M
    b = _mm256_mullo_epi16(diff, shift);
1525
1526
5.68M
    res = _mm256_add_epi16(a32, b);
1527
5.68M
    res = _mm256_srli_epi16(res, 5);  // 16 16bit values
1528
1529
5.68M
    base_inc256 = _mm256_setr_epi16(base, base + 1, base + 2, base + 3,
1530
5.68M
                                    base + 4, base + 5, base + 6, base + 7,
1531
5.68M
                                    base + 8, base + 9, base + 10, base + 11,
1532
5.68M
                                    base + 12, base + 13, base + 14, base + 15);
1533
5.68M
    mask256 = _mm256_cmpgt_epi16(max_base_x256, base_inc256);
1534
5.68M
    dstvec[r] = _mm256_blendv_epi8(a_mbase_x, res, mask256);
1535
5.68M
    x += dx;
1536
5.68M
  }
1537
305k
}
1538
1539
static void highbd_dr_prediction_z1_16xN_avx2(int N, uint16_t *dst,
1540
                                              ptrdiff_t stride,
1541
                                              const uint16_t *above,
1542
                                              int upsample_above, int dx,
1543
235k
                                              int bd) {
1544
235k
  __m256i dstvec[64];
1545
235k
  if (bd < 12) {
1546
129k
    highbd_dr_prediction_z1_16xN_internal_avx2(N, dstvec, above, upsample_above,
1547
129k
                                               dx);
1548
129k
  } else {
1549
105k
    highbd_dr_prediction_32bit_z1_16xN_internal_avx2(N, dstvec, above,
1550
105k
                                                     upsample_above, dx);
1551
105k
  }
1552
3.29M
  for (int i = 0; i < N; i++) {
1553
3.06M
    _mm256_storeu_si256((__m256i *)(dst + stride * i), dstvec[i]);
1554
3.06M
  }
1555
235k
}
1556
1557
static AOM_FORCE_INLINE void highbd_dr_prediction_32bit_z1_32xN_internal_avx2(
1558
22.8k
    int N, __m256i *dstvec, const uint16_t *above, int upsample_above, int dx) {
1559
  // here upsample_above is 0 by design of av1_use_intra_edge_upsample
1560
22.8k
  (void)upsample_above;
1561
22.8k
  const int frac_bits = 6;
1562
22.8k
  const int max_base_x = ((32 + N) - 1);
1563
1564
  // pre-filter above pixels
1565
  // store in temp buffers:
1566
  //   above[x] * 32 + 16
1567
  //   above[x+1] - above[x]
1568
  // final pixels will be calculated as:
1569
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1570
22.8k
  __m256i a0, a0_1, a1, a1_1, a32, a16, c3f;
1571
22.8k
  __m256i a_mbase_x, diff, max_base_x256, base_inc256, mask256;
1572
1573
22.8k
  a16 = _mm256_set1_epi32(16);
1574
22.8k
  a_mbase_x = _mm256_set1_epi16(above[max_base_x]);
1575
22.8k
  max_base_x256 = _mm256_set1_epi16(max_base_x);
1576
22.8k
  c3f = _mm256_set1_epi16(0x3f);
1577
1578
22.8k
  int x = dx;
1579
533k
  for (int r = 0; r < N; r++) {
1580
511k
    __m256i b, res[2], res1;
1581
1582
511k
    int base = x >> frac_bits;
1583
511k
    if (base >= max_base_x) {
1584
0
      for (int i = r; i < N; ++i) {
1585
0
        dstvec[i] = a_mbase_x;  // save 32 values
1586
0
        dstvec[i + N] = a_mbase_x;
1587
0
      }
1588
0
      return;
1589
0
    }
1590
1591
511k
    __m256i shift =
1592
511k
        _mm256_srli_epi32(_mm256_and_si256(_mm256_set1_epi32(x), c3f), 1);
1593
1594
1.53M
    for (int j = 0; j < 32; j += 16) {
1595
1.02M
      int mdif = max_base_x - (base + j);
1596
1.02M
      if (mdif <= 0) {
1597
573
        res1 = a_mbase_x;
1598
1.02M
      } else {
1599
1.02M
        a0 = _mm256_cvtepu16_epi32(
1600
1.02M
            _mm_loadu_si128((__m128i *)(above + base + j)));
1601
1.02M
        a1 = _mm256_cvtepu16_epi32(
1602
1.02M
            _mm_loadu_si128((__m128i *)(above + base + 1 + j)));
1603
1604
1.02M
        diff = _mm256_sub_epi32(a1, a0);   // a[x+1] - a[x]
1605
1.02M
        a32 = _mm256_slli_epi32(a0, 5);    // a[x] * 32
1606
1.02M
        a32 = _mm256_add_epi32(a32, a16);  // a[x] * 32 + 16
1607
1.02M
        b = _mm256_mullo_epi32(diff, shift);
1608
1609
1.02M
        res[0] = _mm256_add_epi32(a32, b);
1610
1.02M
        res[0] = _mm256_srli_epi32(res[0], 5);
1611
1.02M
        res[0] = _mm256_packus_epi32(
1612
1.02M
            res[0],
1613
1.02M
            _mm256_castsi128_si256(_mm256_extracti128_si256(res[0], 1)));
1614
1.02M
        if (mdif > 8) {
1615
1.01M
          a0_1 = _mm256_cvtepu16_epi32(
1616
1.01M
              _mm_loadu_si128((__m128i *)(above + base + 8 + j)));
1617
1.01M
          a1_1 = _mm256_cvtepu16_epi32(
1618
1.01M
              _mm_loadu_si128((__m128i *)(above + base + 9 + j)));
1619
1620
1.01M
          diff = _mm256_sub_epi32(a1_1, a0_1);  // a[x+1] - a[x]
1621
1.01M
          a32 = _mm256_slli_epi32(a0_1, 5);     // a[x] * 32
1622
1.01M
          a32 = _mm256_add_epi32(a32, a16);     // a[x] * 32 + 16
1623
1.01M
          b = _mm256_mullo_epi32(diff, shift);
1624
1625
1.01M
          res[1] = _mm256_add_epi32(a32, b);
1626
1.01M
          res[1] = _mm256_srli_epi32(res[1], 5);
1627
1.01M
          res[1] = _mm256_packus_epi32(
1628
1.01M
              res[1],
1629
1.01M
              _mm256_castsi128_si256(_mm256_extracti128_si256(res[1], 1)));
1630
1.01M
        } else {
1631
4.97k
          res[1] = a_mbase_x;
1632
4.97k
        }
1633
1.02M
        res1 = _mm256_inserti128_si256(res[0], _mm256_castsi256_si128(res[1]),
1634
1.02M
                                       1);  // 16 16bit values
1635
1.02M
        base_inc256 = _mm256_setr_epi16(
1636
1.02M
            base + j, base + j + 1, base + j + 2, base + j + 3, base + j + 4,
1637
1.02M
            base + j + 5, base + j + 6, base + j + 7, base + j + 8,
1638
1.02M
            base + j + 9, base + j + 10, base + j + 11, base + j + 12,
1639
1.02M
            base + j + 13, base + j + 14, base + j + 15);
1640
1641
1.02M
        mask256 = _mm256_cmpgt_epi16(max_base_x256, base_inc256);
1642
1.02M
        res1 = _mm256_blendv_epi8(a_mbase_x, res1, mask256);
1643
1.02M
      }
1644
1.02M
      if (!j) {
1645
511k
        dstvec[r] = res1;
1646
511k
      } else {
1647
511k
        dstvec[r + N] = res1;
1648
511k
      }
1649
1.02M
    }
1650
511k
    x += dx;
1651
511k
  }
1652
22.8k
}
1653
1654
static AOM_FORCE_INLINE void highbd_dr_prediction_z1_32xN_internal_avx2(
1655
205k
    int N, __m256i *dstvec, const uint16_t *above, int upsample_above, int dx) {
1656
  // here upsample_above is 0 by design of av1_use_intra_edge_upsample
1657
205k
  (void)upsample_above;
1658
205k
  const int frac_bits = 6;
1659
205k
  const int max_base_x = ((32 + N) - 1);
1660
1661
  // pre-filter above pixels
1662
  // store in temp buffers:
1663
  //   above[x] * 32 + 16
1664
  //   above[x+1] - above[x]
1665
  // final pixels will be calculated as:
1666
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1667
205k
  __m256i a0, a1, a32, a16, c3f;
1668
205k
  __m256i a_mbase_x, diff, max_base_x256, base_inc256, mask256;
1669
1670
205k
  a16 = _mm256_set1_epi16(16);
1671
205k
  a_mbase_x = _mm256_set1_epi16(above[max_base_x]);
1672
205k
  max_base_x256 = _mm256_set1_epi16(max_base_x);
1673
205k
  c3f = _mm256_set1_epi16(0x3f);
1674
1675
205k
  int x = dx;
1676
5.76M
  for (int r = 0; r < N; r++) {
1677
5.55M
    __m256i b, res;
1678
1679
5.55M
    int base = x >> frac_bits;
1680
5.55M
    if (base >= max_base_x) {
1681
0
      for (int i = r; i < N; ++i) {
1682
0
        dstvec[i] = a_mbase_x;  // save 32 values
1683
0
        dstvec[i + N] = a_mbase_x;
1684
0
      }
1685
0
      return;
1686
0
    }
1687
1688
5.55M
    __m256i shift =
1689
5.55M
        _mm256_srli_epi16(_mm256_and_si256(_mm256_set1_epi16(x), c3f), 1);
1690
1691
16.6M
    for (int j = 0; j < 32; j += 16) {
1692
11.1M
      int mdif = max_base_x - (base + j);
1693
11.1M
      if (mdif <= 0) {
1694
773
        res = a_mbase_x;
1695
11.1M
      } else {
1696
11.1M
        a0 = _mm256_loadu_si256((__m256i *)(above + base + j));
1697
11.1M
        a1 = _mm256_loadu_si256((__m256i *)(above + base + 1 + j));
1698
1699
11.1M
        diff = _mm256_sub_epi16(a1, a0);   // a[x+1] - a[x]
1700
11.1M
        a32 = _mm256_slli_epi16(a0, 5);    // a[x] * 32
1701
11.1M
        a32 = _mm256_add_epi16(a32, a16);  // a[x] * 32 + 16
1702
11.1M
        b = _mm256_mullo_epi16(diff, shift);
1703
1704
11.1M
        res = _mm256_add_epi16(a32, b);
1705
11.1M
        res = _mm256_srli_epi16(res, 5);
1706
1707
11.1M
        base_inc256 = _mm256_setr_epi16(
1708
11.1M
            base + j, base + j + 1, base + j + 2, base + j + 3, base + j + 4,
1709
11.1M
            base + j + 5, base + j + 6, base + j + 7, base + j + 8,
1710
11.1M
            base + j + 9, base + j + 10, base + j + 11, base + j + 12,
1711
11.1M
            base + j + 13, base + j + 14, base + j + 15);
1712
1713
11.1M
        mask256 = _mm256_cmpgt_epi16(max_base_x256, base_inc256);
1714
11.1M
        res = _mm256_blendv_epi8(a_mbase_x, res, mask256);
1715
11.1M
      }
1716
11.1M
      if (!j) {
1717
5.55M
        dstvec[r] = res;
1718
5.55M
      } else {
1719
5.55M
        dstvec[r + N] = res;
1720
5.55M
      }
1721
11.1M
    }
1722
5.55M
    x += dx;
1723
5.55M
  }
1724
205k
}
1725
1726
static void highbd_dr_prediction_z1_32xN_avx2(int N, uint16_t *dst,
1727
                                              ptrdiff_t stride,
1728
                                              const uint16_t *above,
1729
                                              int upsample_above, int dx,
1730
87.9k
                                              int bd) {
1731
87.9k
  __m256i dstvec[128];
1732
87.9k
  if (bd < 12) {
1733
75.9k
    highbd_dr_prediction_z1_32xN_internal_avx2(N, dstvec, above, upsample_above,
1734
75.9k
                                               dx);
1735
75.9k
  } else {
1736
11.9k
    highbd_dr_prediction_32bit_z1_32xN_internal_avx2(N, dstvec, above,
1737
11.9k
                                                     upsample_above, dx);
1738
11.9k
  }
1739
2.42M
  for (int i = 0; i < N; i++) {
1740
2.34M
    _mm256_storeu_si256((__m256i *)(dst + stride * i), dstvec[i]);
1741
2.34M
    _mm256_storeu_si256((__m256i *)(dst + stride * i + 16), dstvec[i + N]);
1742
2.34M
  }
1743
87.9k
}
1744
1745
static void highbd_dr_prediction_32bit_z1_64xN_avx2(int N, uint16_t *dst,
1746
                                                    ptrdiff_t stride,
1747
                                                    const uint16_t *above,
1748
                                                    int upsample_above,
1749
13.2k
                                                    int dx) {
1750
  // here upsample_above is 0 by design of av1_use_intra_edge_upsample
1751
13.2k
  (void)upsample_above;
1752
13.2k
  const int frac_bits = 6;
1753
13.2k
  const int max_base_x = ((64 + N) - 1);
1754
1755
  // pre-filter above pixels
1756
  // store in temp buffers:
1757
  //   above[x] * 32 + 16
1758
  //   above[x+1] - above[x]
1759
  // final pixels will be calculated as:
1760
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1761
13.2k
  __m256i a0, a0_1, a1, a1_1, a32, a16;
1762
13.2k
  __m256i a_mbase_x, diff, max_base_x256, base_inc256, mask256;
1763
1764
13.2k
  a16 = _mm256_set1_epi32(16);
1765
13.2k
  a_mbase_x = _mm256_set1_epi16(above[max_base_x]);
1766
13.2k
  max_base_x256 = _mm256_set1_epi16(max_base_x);
1767
1768
13.2k
  int x = dx;
1769
792k
  for (int r = 0; r < N; r++, dst += stride) {
1770
779k
    __m256i b, res[2], res1;
1771
1772
779k
    int base = x >> frac_bits;
1773
779k
    if (base >= max_base_x) {
1774
0
      for (int i = r; i < N; ++i) {
1775
0
        _mm256_storeu_si256((__m256i *)dst, a_mbase_x);  // save 32 values
1776
0
        _mm256_storeu_si256((__m256i *)(dst + 16), a_mbase_x);
1777
0
        _mm256_storeu_si256((__m256i *)(dst + 32), a_mbase_x);
1778
0
        _mm256_storeu_si256((__m256i *)(dst + 48), a_mbase_x);
1779
0
        dst += stride;
1780
0
      }
1781
0
      return;
1782
0
    }
1783
1784
779k
    __m256i shift = _mm256_srli_epi32(
1785
779k
        _mm256_and_si256(_mm256_set1_epi32(x), _mm256_set1_epi32(0x3f)), 1);
1786
1787
779k
    __m128i a0_128, a0_1_128, a1_128, a1_1_128;
1788
3.89M
    for (int j = 0; j < 64; j += 16) {
1789
3.11M
      int mdif = max_base_x - (base + j);
1790
3.11M
      if (mdif <= 0) {
1791
3.74k
        _mm256_storeu_si256((__m256i *)(dst + j), a_mbase_x);
1792
3.11M
      } else {
1793
3.11M
        a0_128 = _mm_loadu_si128((__m128i *)(above + base + j));
1794
3.11M
        a1_128 = _mm_loadu_si128((__m128i *)(above + base + 1 + j));
1795
3.11M
        a0 = _mm256_cvtepu16_epi32(a0_128);
1796
3.11M
        a1 = _mm256_cvtepu16_epi32(a1_128);
1797
1798
3.11M
        diff = _mm256_sub_epi32(a1, a0);   // a[x+1] - a[x]
1799
3.11M
        a32 = _mm256_slli_epi32(a0, 5);    // a[x] * 32
1800
3.11M
        a32 = _mm256_add_epi32(a32, a16);  // a[x] * 32 + 16
1801
3.11M
        b = _mm256_mullo_epi32(diff, shift);
1802
1803
3.11M
        res[0] = _mm256_add_epi32(a32, b);
1804
3.11M
        res[0] = _mm256_srli_epi32(res[0], 5);
1805
3.11M
        res[0] = _mm256_packus_epi32(
1806
3.11M
            res[0],
1807
3.11M
            _mm256_castsi128_si256(_mm256_extracti128_si256(res[0], 1)));
1808
3.11M
        if (mdif > 8) {
1809
3.10M
          a0_1_128 = _mm_loadu_si128((__m128i *)(above + base + 8 + j));
1810
3.10M
          a1_1_128 = _mm_loadu_si128((__m128i *)(above + base + 9 + j));
1811
3.10M
          a0_1 = _mm256_cvtepu16_epi32(a0_1_128);
1812
3.10M
          a1_1 = _mm256_cvtepu16_epi32(a1_1_128);
1813
1814
3.10M
          diff = _mm256_sub_epi32(a1_1, a0_1);  // a[x+1] - a[x]
1815
3.10M
          a32 = _mm256_slli_epi32(a0_1, 5);     // a[x] * 32
1816
3.10M
          a32 = _mm256_add_epi32(a32, a16);     // a[x] * 32 + 16
1817
3.10M
          b = _mm256_mullo_epi32(diff, shift);
1818
1819
3.10M
          res[1] = _mm256_add_epi32(a32, b);
1820
3.10M
          res[1] = _mm256_srli_epi32(res[1], 5);
1821
3.10M
          res[1] = _mm256_packus_epi32(
1822
3.10M
              res[1],
1823
3.10M
              _mm256_castsi128_si256(_mm256_extracti128_si256(res[1], 1)));
1824
3.10M
        } else {
1825
6.47k
          res[1] = a_mbase_x;
1826
6.47k
        }
1827
3.11M
        res1 = _mm256_inserti128_si256(res[0], _mm256_castsi256_si128(res[1]),
1828
3.11M
                                       1);  // 16 16bit values
1829
3.11M
        base_inc256 = _mm256_setr_epi16(
1830
3.11M
            base + j, base + j + 1, base + j + 2, base + j + 3, base + j + 4,
1831
3.11M
            base + j + 5, base + j + 6, base + j + 7, base + j + 8,
1832
3.11M
            base + j + 9, base + j + 10, base + j + 11, base + j + 12,
1833
3.11M
            base + j + 13, base + j + 14, base + j + 15);
1834
1835
3.11M
        mask256 = _mm256_cmpgt_epi16(max_base_x256, base_inc256);
1836
3.11M
        res1 = _mm256_blendv_epi8(a_mbase_x, res1, mask256);
1837
3.11M
        _mm256_storeu_si256((__m256i *)(dst + j), res1);
1838
3.11M
      }
1839
3.11M
    }
1840
779k
    x += dx;
1841
779k
  }
1842
13.2k
}
1843
1844
static void highbd_dr_prediction_z1_64xN_avx2(int N, uint16_t *dst,
1845
                                              ptrdiff_t stride,
1846
                                              const uint16_t *above,
1847
46.7k
                                              int upsample_above, int dx) {
1848
  // here upsample_above is 0 by design of av1_use_intra_edge_upsample
1849
46.7k
  (void)upsample_above;
1850
46.7k
  const int frac_bits = 6;
1851
46.7k
  const int max_base_x = ((64 + N) - 1);
1852
1853
  // pre-filter above pixels
1854
  // store in temp buffers:
1855
  //   above[x] * 32 + 16
1856
  //   above[x+1] - above[x]
1857
  // final pixels will be calculated as:
1858
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1859
46.7k
  __m256i a0, a1, a32, a16, c3f;
1860
46.7k
  __m256i a_mbase_x, diff, max_base_x256, base_inc256, mask256;
1861
1862
46.7k
  a16 = _mm256_set1_epi16(16);
1863
46.7k
  a_mbase_x = _mm256_set1_epi16(above[max_base_x]);
1864
46.7k
  max_base_x256 = _mm256_set1_epi16(max_base_x);
1865
46.7k
  c3f = _mm256_set1_epi16(0x3f);
1866
1867
46.7k
  int x = dx;
1868
2.45M
  for (int r = 0; r < N; r++, dst += stride) {
1869
2.40M
    __m256i b, res;
1870
1871
2.40M
    int base = x >> frac_bits;
1872
2.40M
    if (base >= max_base_x) {
1873
0
      for (int i = r; i < N; ++i) {
1874
0
        _mm256_storeu_si256((__m256i *)dst, a_mbase_x);  // save 32 values
1875
0
        _mm256_storeu_si256((__m256i *)(dst + 16), a_mbase_x);
1876
0
        _mm256_storeu_si256((__m256i *)(dst + 32), a_mbase_x);
1877
0
        _mm256_storeu_si256((__m256i *)(dst + 48), a_mbase_x);
1878
0
        dst += stride;
1879
0
      }
1880
0
      return;
1881
0
    }
1882
1883
2.40M
    __m256i shift =
1884
2.40M
        _mm256_srli_epi16(_mm256_and_si256(_mm256_set1_epi16(x), c3f), 1);
1885
1886
12.0M
    for (int j = 0; j < 64; j += 16) {
1887
9.61M
      int mdif = max_base_x - (base + j);
1888
9.61M
      if (mdif <= 0) {
1889
3.07k
        _mm256_storeu_si256((__m256i *)(dst + j), a_mbase_x);
1890
9.61M
      } else {
1891
9.61M
        a0 = _mm256_loadu_si256((__m256i *)(above + base + j));
1892
9.61M
        a1 = _mm256_loadu_si256((__m256i *)(above + base + 1 + j));
1893
1894
9.61M
        diff = _mm256_sub_epi16(a1, a0);   // a[x+1] - a[x]
1895
9.61M
        a32 = _mm256_slli_epi16(a0, 5);    // a[x] * 32
1896
9.61M
        a32 = _mm256_add_epi16(a32, a16);  // a[x] * 32 + 16
1897
9.61M
        b = _mm256_mullo_epi16(diff, shift);
1898
1899
9.61M
        res = _mm256_add_epi16(a32, b);
1900
9.61M
        res = _mm256_srli_epi16(res, 5);
1901
1902
9.61M
        base_inc256 = _mm256_setr_epi16(
1903
9.61M
            base + j, base + j + 1, base + j + 2, base + j + 3, base + j + 4,
1904
9.61M
            base + j + 5, base + j + 6, base + j + 7, base + j + 8,
1905
9.61M
            base + j + 9, base + j + 10, base + j + 11, base + j + 12,
1906
9.61M
            base + j + 13, base + j + 14, base + j + 15);
1907
1908
9.61M
        mask256 = _mm256_cmpgt_epi16(max_base_x256, base_inc256);
1909
9.61M
        res = _mm256_blendv_epi8(a_mbase_x, res, mask256);
1910
9.61M
        _mm256_storeu_si256((__m256i *)(dst + j), res);  // 16 16bit values
1911
9.61M
      }
1912
9.61M
    }
1913
2.40M
    x += dx;
1914
2.40M
  }
1915
46.7k
}
1916
1917
// Directional prediction, zone 1: 0 < angle < 90
1918
void av1_highbd_dr_prediction_z1_avx2(uint16_t *dst, ptrdiff_t stride, int bw,
1919
                                      int bh, const uint16_t *above,
1920
                                      const uint16_t *left, int upsample_above,
1921
813k
                                      int dx, int dy, int bd) {
1922
813k
  (void)left;
1923
813k
  (void)dy;
1924
1925
813k
  switch (bw) {
1926
200k
    case 4:
1927
200k
      highbd_dr_prediction_z1_4xN_avx2(bh, dst, stride, above, upsample_above,
1928
200k
                                       dx, bd);
1929
200k
      break;
1930
270k
    case 8:
1931
270k
      highbd_dr_prediction_z1_8xN_avx2(bh, dst, stride, above, upsample_above,
1932
270k
                                       dx, bd);
1933
270k
      break;
1934
235k
    case 16:
1935
235k
      highbd_dr_prediction_z1_16xN_avx2(bh, dst, stride, above, upsample_above,
1936
235k
                                        dx, bd);
1937
235k
      break;
1938
84.7k
    case 32:
1939
84.7k
      highbd_dr_prediction_z1_32xN_avx2(bh, dst, stride, above, upsample_above,
1940
84.7k
                                        dx, bd);
1941
84.7k
      break;
1942
22.0k
    case 64:
1943
22.0k
      if (bd < 12) {
1944
13.1k
        highbd_dr_prediction_z1_64xN_avx2(bh, dst, stride, above,
1945
13.1k
                                          upsample_above, dx);
1946
13.1k
      } else {
1947
8.88k
        highbd_dr_prediction_32bit_z1_64xN_avx2(bh, dst, stride, above,
1948
8.88k
                                                upsample_above, dx);
1949
8.88k
      }
1950
22.0k
      break;
1951
0
    default: break;
1952
813k
  }
1953
813k
  return;
1954
813k
}
1955
1956
static void highbd_transpose_TX_16X16(const uint16_t *src, ptrdiff_t pitchSrc,
1957
541k
                                      uint16_t *dst, ptrdiff_t pitchDst) {
1958
541k
  __m256i r[16];
1959
541k
  __m256i d[16];
1960
9.20M
  for (int j = 0; j < 16; j++) {
1961
8.66M
    r[j] = _mm256_loadu_si256((__m256i *)(src + j * pitchSrc));
1962
8.66M
  }
1963
541k
  highbd_transpose16x16_avx2(r, d);
1964
9.20M
  for (int j = 0; j < 16; j++) {
1965
8.66M
    _mm256_storeu_si256((__m256i *)(dst + j * pitchDst), d[j]);
1966
8.66M
  }
1967
541k
}
1968
1969
static void highbd_transpose(const uint16_t *src, ptrdiff_t pitchSrc,
1970
                             uint16_t *dst, ptrdiff_t pitchDst, int width,
1971
41.1k
                             int height) {
1972
199k
  for (int j = 0; j < height; j += 16)
1973
699k
    for (int i = 0; i < width; i += 16)
1974
541k
      highbd_transpose_TX_16X16(src + i * pitchSrc + j, pitchSrc,
1975
541k
                                dst + j * pitchDst + i, pitchDst);
1976
41.1k
}
1977
1978
static void highbd_dr_prediction_32bit_z2_Nx4_avx2(
1979
    int N, uint16_t *dst, ptrdiff_t stride, const uint16_t *above,
1980
    const uint16_t *left, int upsample_above, int upsample_left, int dx,
1981
297k
    int dy) {
1982
297k
  const int min_base_x = -(1 << upsample_above);
1983
297k
  const int min_base_y = -(1 << upsample_left);
1984
297k
  const int frac_bits_x = 6 - upsample_above;
1985
297k
  const int frac_bits_y = 6 - upsample_left;
1986
1987
297k
  assert(dx > 0);
1988
  // pre-filter above pixels
1989
  // store in temp buffers:
1990
  //   above[x] * 32 + 16
1991
  //   above[x+1] - above[x]
1992
  // final pixels will be calculated as:
1993
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1994
297k
  __m256i a0_x, a1_x, a32, a16;
1995
297k
  __m256i diff;
1996
297k
  __m128i c3f, min_base_y128;
1997
1998
297k
  a16 = _mm256_set1_epi32(16);
1999
297k
  c3f = _mm_set1_epi32(0x3f);
2000
297k
  min_base_y128 = _mm_set1_epi32(min_base_y);
2001
2002
1.83M
  for (int r = 0; r < N; r++) {
2003
1.53M
    __m256i b, res, shift;
2004
1.53M
    __m128i resx, resy, resxy;
2005
1.53M
    __m128i a0_x128, a1_x128;
2006
1.53M
    int y = r + 1;
2007
1.53M
    int base_x = (-y * dx) >> frac_bits_x;
2008
1.53M
    int base_shift = 0;
2009
1.53M
    if (base_x < (min_base_x - 1)) {
2010
1.30M
      base_shift = (min_base_x - base_x - 1) >> upsample_above;
2011
1.30M
    }
2012
1.53M
    int base_min_diff =
2013
1.53M
        (min_base_x - base_x + upsample_above) >> upsample_above;
2014
1.53M
    if (base_min_diff > 4) {
2015
1.07M
      base_min_diff = 4;
2016
1.07M
    } else {
2017
464k
      if (base_min_diff < 0) base_min_diff = 0;
2018
464k
    }
2019
2020
1.53M
    if (base_shift > 3) {
2021
1.07M
      a0_x = _mm256_setzero_si256();
2022
1.07M
      a1_x = _mm256_setzero_si256();
2023
1.07M
      shift = _mm256_setzero_si256();
2024
1.07M
    } else {
2025
464k
      a0_x128 = _mm_loadu_si128((__m128i *)(above + base_x + base_shift));
2026
464k
      if (upsample_above) {
2027
52.3k
        a0_x128 = _mm_shuffle_epi8(a0_x128,
2028
52.3k
                                   *(__m128i *)HighbdEvenOddMaskx4[base_shift]);
2029
52.3k
        a1_x128 = _mm_srli_si128(a0_x128, 8);
2030
2031
52.3k
        shift = _mm256_castsi128_si256(_mm_srli_epi32(
2032
52.3k
            _mm_and_si128(
2033
52.3k
                _mm_slli_epi32(
2034
52.3k
                    _mm_setr_epi32(-y * dx, (1 << 6) - y * dx,
2035
52.3k
                                   (2 << 6) - y * dx, (3 << 6) - y * dx),
2036
52.3k
                    upsample_above),
2037
52.3k
                c3f),
2038
52.3k
            1));
2039
411k
      } else {
2040
411k
        a0_x128 =
2041
411k
            _mm_shuffle_epi8(a0_x128, *(__m128i *)HighbdLoadMaskx[base_shift]);
2042
411k
        a1_x128 = _mm_srli_si128(a0_x128, 2);
2043
2044
411k
        shift = _mm256_castsi128_si256(_mm_srli_epi32(
2045
411k
            _mm_and_si128(_mm_setr_epi32(-y * dx, (1 << 6) - y * dx,
2046
411k
                                         (2 << 6) - y * dx, (3 << 6) - y * dx),
2047
411k
                          c3f),
2048
411k
            1));
2049
411k
      }
2050
464k
      a0_x = _mm256_cvtepu16_epi32(a0_x128);
2051
464k
      a1_x = _mm256_cvtepu16_epi32(a1_x128);
2052
464k
    }
2053
    // y calc
2054
1.53M
    __m128i a0_y, a1_y, shifty;
2055
1.53M
    if (base_x < min_base_x) {
2056
1.40M
      __m128i r6, c1234, dy128, y_c128, base_y_c128, mask128;
2057
1.40M
      DECLARE_ALIGNED(32, int, base_y_c[4]);
2058
1.40M
      r6 = _mm_set1_epi32(r << 6);
2059
1.40M
      dy128 = _mm_set1_epi32(dy);
2060
1.40M
      c1234 = _mm_setr_epi32(1, 2, 3, 4);
2061
1.40M
      y_c128 = _mm_sub_epi32(r6, _mm_mullo_epi32(c1234, dy128));
2062
1.40M
      base_y_c128 = _mm_srai_epi32(y_c128, frac_bits_y);
2063
1.40M
      mask128 = _mm_cmpgt_epi32(min_base_y128, base_y_c128);
2064
1.40M
      base_y_c128 = _mm_andnot_si128(mask128, base_y_c128);
2065
1.40M
      _mm_store_si128((__m128i *)base_y_c, base_y_c128);
2066
2067
1.40M
      a0_y = _mm_setr_epi32(left[base_y_c[0]], left[base_y_c[1]],
2068
1.40M
                            left[base_y_c[2]], left[base_y_c[3]]);
2069
1.40M
      a1_y = _mm_setr_epi32(left[base_y_c[0] + 1], left[base_y_c[1] + 1],
2070
1.40M
                            left[base_y_c[2] + 1], left[base_y_c[3] + 1]);
2071
2072
1.40M
      if (upsample_left) {
2073
232k
        shifty = _mm_srli_epi32(
2074
232k
            _mm_and_si128(_mm_slli_epi32(y_c128, upsample_left), c3f), 1);
2075
1.16M
      } else {
2076
1.16M
        shifty = _mm_srli_epi32(_mm_and_si128(y_c128, c3f), 1);
2077
1.16M
      }
2078
1.40M
      a0_x = _mm256_inserti128_si256(a0_x, a0_y, 1);
2079
1.40M
      a1_x = _mm256_inserti128_si256(a1_x, a1_y, 1);
2080
1.40M
      shift = _mm256_inserti128_si256(shift, shifty, 1);
2081
1.40M
    }
2082
2083
1.53M
    diff = _mm256_sub_epi32(a1_x, a0_x);  // a[x+1] - a[x]
2084
1.53M
    a32 = _mm256_slli_epi32(a0_x, 5);     // a[x] * 32
2085
1.53M
    a32 = _mm256_add_epi32(a32, a16);     // a[x] * 32 + 16
2086
2087
1.53M
    b = _mm256_mullo_epi32(diff, shift);
2088
1.53M
    res = _mm256_add_epi32(a32, b);
2089
1.53M
    res = _mm256_srli_epi32(res, 5);
2090
2091
1.53M
    resx = _mm256_castsi256_si128(res);
2092
1.53M
    resx = _mm_packus_epi32(resx, resx);
2093
2094
1.53M
    resy = _mm256_extracti128_si256(res, 1);
2095
1.53M
    resy = _mm_packus_epi32(resy, resy);
2096
2097
1.53M
    resxy =
2098
1.53M
        _mm_blendv_epi8(resx, resy, *(__m128i *)HighbdBaseMask[base_min_diff]);
2099
1.53M
    _mm_storel_epi64((__m128i *)(dst), resxy);
2100
1.53M
    dst += stride;
2101
1.53M
  }
2102
297k
}
2103
2104
static void highbd_dr_prediction_z2_Nx4_avx2(
2105
    int N, uint16_t *dst, ptrdiff_t stride, const uint16_t *above,
2106
    const uint16_t *left, int upsample_above, int upsample_left, int dx,
2107
220k
    int dy) {
2108
220k
  const int min_base_x = -(1 << upsample_above);
2109
220k
  const int min_base_y = -(1 << upsample_left);
2110
220k
  const int frac_bits_x = 6 - upsample_above;
2111
220k
  const int frac_bits_y = 6 - upsample_left;
2112
2113
220k
  assert(dx > 0);
2114
  // pre-filter above pixels
2115
  // store in temp buffers:
2116
  //   above[x] * 32 + 16
2117
  //   above[x+1] - above[x]
2118
  // final pixels will be calculated as:
2119
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
2120
220k
  __m256i a0_x, a1_x, a32, a16;
2121
220k
  __m256i diff;
2122
220k
  __m128i c3f, min_base_y128;
2123
2124
220k
  a16 = _mm256_set1_epi16(16);
2125
220k
  c3f = _mm_set1_epi16(0x3f);
2126
220k
  min_base_y128 = _mm_set1_epi16(min_base_y);
2127
2128
1.62M
  for (int r = 0; r < N; r++) {
2129
1.40M
    __m256i b, res, shift;
2130
1.40M
    __m128i resx, resy, resxy;
2131
1.40M
    __m128i a0_x128, a1_x128;
2132
1.40M
    int y = r + 1;
2133
1.40M
    int base_x = (-y * dx) >> frac_bits_x;
2134
1.40M
    int base_shift = 0;
2135
1.40M
    if (base_x < (min_base_x - 1)) {
2136
978k
      base_shift = (min_base_x - base_x - 1) >> upsample_above;
2137
978k
    }
2138
1.40M
    int base_min_diff =
2139
1.40M
        (min_base_x - base_x + upsample_above) >> upsample_above;
2140
1.40M
    if (base_min_diff > 4) {
2141
624k
      base_min_diff = 4;
2142
777k
    } else {
2143
777k
      if (base_min_diff < 0) base_min_diff = 0;
2144
777k
    }
2145
2146
1.40M
    if (base_shift > 3) {
2147
624k
      a0_x = _mm256_setzero_si256();
2148
624k
      a1_x = _mm256_setzero_si256();
2149
624k
      shift = _mm256_setzero_si256();
2150
777k
    } else {
2151
777k
      a0_x128 = _mm_loadu_si128((__m128i *)(above + base_x + base_shift));
2152
777k
      if (upsample_above) {
2153
283k
        a0_x128 = _mm_shuffle_epi8(a0_x128,
2154
283k
                                   *(__m128i *)HighbdEvenOddMaskx4[base_shift]);
2155
283k
        a1_x128 = _mm_srli_si128(a0_x128, 8);
2156
2157
283k
        shift = _mm256_castsi128_si256(_mm_srli_epi16(
2158
283k
            _mm_and_si128(
2159
283k
                _mm_slli_epi16(_mm_setr_epi16(-y * dx, (1 << 6) - y * dx,
2160
283k
                                              (2 << 6) - y * dx,
2161
283k
                                              (3 << 6) - y * dx, 0, 0, 0, 0),
2162
283k
                               upsample_above),
2163
283k
                c3f),
2164
283k
            1));
2165
493k
      } else {
2166
493k
        a0_x128 =
2167
493k
            _mm_shuffle_epi8(a0_x128, *(__m128i *)HighbdLoadMaskx[base_shift]);
2168
493k
        a1_x128 = _mm_srli_si128(a0_x128, 2);
2169
2170
493k
        shift = _mm256_castsi128_si256(_mm_srli_epi16(
2171
493k
            _mm_and_si128(
2172
493k
                _mm_setr_epi16(-y * dx, (1 << 6) - y * dx, (2 << 6) - y * dx,
2173
493k
                               (3 << 6) - y * dx, 0, 0, 0, 0),
2174
493k
                c3f),
2175
493k
            1));
2176
493k
      }
2177
777k
      a0_x = _mm256_castsi128_si256(a0_x128);
2178
777k
      a1_x = _mm256_castsi128_si256(a1_x128);
2179
777k
    }
2180
    // y calc
2181
1.40M
    __m128i a0_y, a1_y, shifty;
2182
1.40M
    if (base_x < min_base_x) {
2183
1.13M
      __m128i r6, c1234, dy128, y_c128, base_y_c128, mask128;
2184
1.13M
      DECLARE_ALIGNED(32, int16_t, base_y_c[8]);
2185
1.13M
      r6 = _mm_set1_epi16(r << 6);
2186
1.13M
      dy128 = _mm_set1_epi16(dy);
2187
1.13M
      c1234 = _mm_setr_epi16(1, 2, 3, 4, 0, 0, 0, 0);
2188
1.13M
      y_c128 = _mm_sub_epi16(r6, _mm_mullo_epi16(c1234, dy128));
2189
1.13M
      base_y_c128 = _mm_srai_epi16(y_c128, frac_bits_y);
2190
1.13M
      mask128 = _mm_cmpgt_epi16(min_base_y128, base_y_c128);
2191
1.13M
      base_y_c128 = _mm_andnot_si128(mask128, base_y_c128);
2192
1.13M
      _mm_store_si128((__m128i *)base_y_c, base_y_c128);
2193
2194
1.13M
      a0_y = _mm_setr_epi16(left[base_y_c[0]], left[base_y_c[1]],
2195
1.13M
                            left[base_y_c[2]], left[base_y_c[3]], 0, 0, 0, 0);
2196
1.13M
      a1_y = _mm_setr_epi16(left[base_y_c[0] + 1], left[base_y_c[1] + 1],
2197
1.13M
                            left[base_y_c[2] + 1], left[base_y_c[3] + 1], 0, 0,
2198
1.13M
                            0, 0);
2199
2200
1.13M
      if (upsample_left) {
2201
374k
        shifty = _mm_srli_epi16(
2202
374k
            _mm_and_si128(_mm_slli_epi16(y_c128, upsample_left), c3f), 1);
2203
759k
      } else {
2204
759k
        shifty = _mm_srli_epi16(_mm_and_si128(y_c128, c3f), 1);
2205
759k
      }
2206
1.13M
      a0_x = _mm256_inserti128_si256(a0_x, a0_y, 1);
2207
1.13M
      a1_x = _mm256_inserti128_si256(a1_x, a1_y, 1);
2208
1.13M
      shift = _mm256_inserti128_si256(shift, shifty, 1);
2209
1.13M
    }
2210
2211
1.40M
    diff = _mm256_sub_epi16(a1_x, a0_x);  // a[x+1] - a[x]
2212
1.40M
    a32 = _mm256_slli_epi16(a0_x, 5);     // a[x] * 32
2213
1.40M
    a32 = _mm256_add_epi16(a32, a16);     // a[x] * 32 + 16
2214
2215
1.40M
    b = _mm256_mullo_epi16(diff, shift);
2216
1.40M
    res = _mm256_add_epi16(a32, b);
2217
1.40M
    res = _mm256_srli_epi16(res, 5);
2218
2219
1.40M
    resx = _mm256_castsi256_si128(res);
2220
1.40M
    resy = _mm256_extracti128_si256(res, 1);
2221
1.40M
    resxy =
2222
1.40M
        _mm_blendv_epi8(resx, resy, *(__m128i *)HighbdBaseMask[base_min_diff]);
2223
1.40M
    _mm_storel_epi64((__m128i *)(dst), resxy);
2224
1.40M
    dst += stride;
2225
1.40M
  }
2226
220k
}
2227
2228
static void highbd_dr_prediction_32bit_z2_Nx8_avx2(
2229
    int N, uint16_t *dst, ptrdiff_t stride, const uint16_t *above,
2230
    const uint16_t *left, int upsample_above, int upsample_left, int dx,
2231
300k
    int dy) {
2232
300k
  const int min_base_x = -(1 << upsample_above);
2233
300k
  const int min_base_y = -(1 << upsample_left);
2234
300k
  const int frac_bits_x = 6 - upsample_above;
2235
300k
  const int frac_bits_y = 6 - upsample_left;
2236
2237
  // pre-filter above pixels
2238
  // store in temp buffers:
2239
  //   above[x] * 32 + 16
2240
  //   above[x+1] - above[x]
2241
  // final pixels will be calculated as:
2242
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
2243
300k
  __m256i a0_x, a1_x, a0_y, a1_y, a32, a16, c3f, min_base_y256;
2244
300k
  __m256i diff;
2245
300k
  __m128i a0_x128, a1_x128;
2246
2247
300k
  a16 = _mm256_set1_epi32(16);
2248
300k
  c3f = _mm256_set1_epi32(0x3f);
2249
300k
  min_base_y256 = _mm256_set1_epi32(min_base_y);
2250
2251
3.14M
  for (int r = 0; r < N; r++) {
2252
2.84M
    __m256i b, res, shift;
2253
2.84M
    __m128i resx, resy, resxy;
2254
2.84M
    int y = r + 1;
2255
2.84M
    int base_x = (-y * dx) >> frac_bits_x;
2256
2.84M
    int base_shift = 0;
2257
2.84M
    if (base_x < (min_base_x - 1)) {
2258
2.21M
      base_shift = (min_base_x - base_x - 1) >> upsample_above;
2259
2.21M
    }
2260
2.84M
    int base_min_diff =
2261
2.84M
        (min_base_x - base_x + upsample_above) >> upsample_above;
2262
2.84M
    if (base_min_diff > 8) {
2263
1.43M
      base_min_diff = 8;
2264
1.43M
    } else {
2265
1.40M
      if (base_min_diff < 0) base_min_diff = 0;
2266
1.40M
    }
2267
2268
2.84M
    if (base_shift > 7) {
2269
1.43M
      resx = _mm_setzero_si128();
2270
1.43M
    } else {
2271
1.40M
      a0_x128 = _mm_loadu_si128((__m128i *)(above + base_x + base_shift));
2272
1.40M
      if (upsample_above) {
2273
94.6k
        __m128i mask, atmp0, atmp1, atmp2, atmp3;
2274
94.6k
        a1_x128 = _mm_loadu_si128((__m128i *)(above + base_x + 8 + base_shift));
2275
94.6k
        atmp0 = _mm_shuffle_epi8(a0_x128,
2276
94.6k
                                 *(__m128i *)HighbdEvenOddMaskx[base_shift]);
2277
94.6k
        atmp1 = _mm_shuffle_epi8(a1_x128,
2278
94.6k
                                 *(__m128i *)HighbdEvenOddMaskx[base_shift]);
2279
94.6k
        atmp2 = _mm_shuffle_epi8(
2280
94.6k
            a0_x128, *(__m128i *)(HighbdEvenOddMaskx[base_shift] + 16));
2281
94.6k
        atmp3 = _mm_shuffle_epi8(
2282
94.6k
            a1_x128, *(__m128i *)(HighbdEvenOddMaskx[base_shift] + 16));
2283
94.6k
        mask = _mm_cmpgt_epi8(*(__m128i *)HighbdEvenOddMaskx[base_shift],
2284
94.6k
                              _mm_set1_epi8(15));
2285
94.6k
        a0_x128 = _mm_blendv_epi8(atmp0, atmp1, mask);
2286
94.6k
        mask = _mm_cmpgt_epi8(*(__m128i *)(HighbdEvenOddMaskx[base_shift] + 16),
2287
94.6k
                              _mm_set1_epi8(15));
2288
94.6k
        a1_x128 = _mm_blendv_epi8(atmp2, atmp3, mask);
2289
94.6k
        shift = _mm256_srli_epi32(
2290
94.6k
            _mm256_and_si256(
2291
94.6k
                _mm256_slli_epi32(
2292
94.6k
                    _mm256_setr_epi32(-y * dx, (1 << 6) - y * dx,
2293
94.6k
                                      (2 << 6) - y * dx, (3 << 6) - y * dx,
2294
94.6k
                                      (4 << 6) - y * dx, (5 << 6) - y * dx,
2295
94.6k
                                      (6 << 6) - y * dx, (7 << 6) - y * dx),
2296
94.6k
                    upsample_above),
2297
94.6k
                c3f),
2298
94.6k
            1);
2299
1.31M
      } else {
2300
1.31M
        a1_x128 = _mm_loadu_si128((__m128i *)(above + base_x + 1 + base_shift));
2301
1.31M
        a0_x128 =
2302
1.31M
            _mm_shuffle_epi8(a0_x128, *(__m128i *)HighbdLoadMaskx[base_shift]);
2303
1.31M
        a1_x128 =
2304
1.31M
            _mm_shuffle_epi8(a1_x128, *(__m128i *)HighbdLoadMaskx[base_shift]);
2305
2306
1.31M
        shift = _mm256_srli_epi32(
2307
1.31M
            _mm256_and_si256(
2308
1.31M
                _mm256_setr_epi32(-y * dx, (1 << 6) - y * dx, (2 << 6) - y * dx,
2309
1.31M
                                  (3 << 6) - y * dx, (4 << 6) - y * dx,
2310
1.31M
                                  (5 << 6) - y * dx, (6 << 6) - y * dx,
2311
1.31M
                                  (7 << 6) - y * dx),
2312
1.31M
                c3f),
2313
1.31M
            1);
2314
1.31M
      }
2315
1.40M
      a0_x = _mm256_cvtepu16_epi32(a0_x128);
2316
1.40M
      a1_x = _mm256_cvtepu16_epi32(a1_x128);
2317
2318
1.40M
      diff = _mm256_sub_epi32(a1_x, a0_x);  // a[x+1] - a[x]
2319
1.40M
      a32 = _mm256_slli_epi32(a0_x, 5);     // a[x] * 32
2320
1.40M
      a32 = _mm256_add_epi32(a32, a16);     // a[x] * 32 + 16
2321
2322
1.40M
      b = _mm256_mullo_epi32(diff, shift);
2323
1.40M
      res = _mm256_add_epi32(a32, b);
2324
1.40M
      res = _mm256_srli_epi32(res, 5);
2325
2326
1.40M
      resx = _mm256_castsi256_si128(_mm256_packus_epi32(
2327
1.40M
          res, _mm256_castsi128_si256(_mm256_extracti128_si256(res, 1))));
2328
1.40M
    }
2329
    // y calc
2330
2.84M
    if (base_x < min_base_x) {
2331
2.42M
      DECLARE_ALIGNED(32, int, base_y_c[8]);
2332
2.42M
      __m256i r6, c256, dy256, y_c256, base_y_c256, mask256;
2333
2.42M
      r6 = _mm256_set1_epi32(r << 6);
2334
2.42M
      dy256 = _mm256_set1_epi32(dy);
2335
2.42M
      c256 = _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 8);
2336
2.42M
      y_c256 = _mm256_sub_epi32(r6, _mm256_mullo_epi32(c256, dy256));
2337
2.42M
      base_y_c256 = _mm256_srai_epi32(y_c256, frac_bits_y);
2338
2.42M
      mask256 = _mm256_cmpgt_epi32(min_base_y256, base_y_c256);
2339
2.42M
      base_y_c256 = _mm256_andnot_si256(mask256, base_y_c256);
2340
2.42M
      _mm256_store_si256((__m256i *)base_y_c, base_y_c256);
2341
2342
2.42M
      a0_y = _mm256_cvtepu16_epi32(_mm_setr_epi16(
2343
2.42M
          left[base_y_c[0]], left[base_y_c[1]], left[base_y_c[2]],
2344
2.42M
          left[base_y_c[3]], left[base_y_c[4]], left[base_y_c[5]],
2345
2.42M
          left[base_y_c[6]], left[base_y_c[7]]));
2346
2.42M
      a1_y = _mm256_cvtepu16_epi32(_mm_setr_epi16(
2347
2.42M
          left[base_y_c[0] + 1], left[base_y_c[1] + 1], left[base_y_c[2] + 1],
2348
2.42M
          left[base_y_c[3] + 1], left[base_y_c[4] + 1], left[base_y_c[5] + 1],
2349
2.42M
          left[base_y_c[6] + 1], left[base_y_c[7] + 1]));
2350
2351
2.42M
      if (upsample_left) {
2352
143k
        shift = _mm256_srli_epi32(
2353
143k
            _mm256_and_si256(_mm256_slli_epi32((y_c256), upsample_left), c3f),
2354
143k
            1);
2355
2.28M
      } else {
2356
2.28M
        shift = _mm256_srli_epi32(_mm256_and_si256(y_c256, c3f), 1);
2357
2.28M
      }
2358
2.42M
      diff = _mm256_sub_epi32(a1_y, a0_y);  // a[x+1] - a[x]
2359
2.42M
      a32 = _mm256_slli_epi32(a0_y, 5);     // a[x] * 32
2360
2.42M
      a32 = _mm256_add_epi32(a32, a16);     // a[x] * 32 + 16
2361
2362
2.42M
      b = _mm256_mullo_epi32(diff, shift);
2363
2.42M
      res = _mm256_add_epi32(a32, b);
2364
2.42M
      res = _mm256_srli_epi32(res, 5);
2365
2366
2.42M
      resy = _mm256_castsi256_si128(_mm256_packus_epi32(
2367
2.42M
          res, _mm256_castsi128_si256(_mm256_extracti128_si256(res, 1))));
2368
2.42M
    } else {
2369
410k
      resy = resx;
2370
410k
    }
2371
2.84M
    resxy =
2372
2.84M
        _mm_blendv_epi8(resx, resy, *(__m128i *)HighbdBaseMask[base_min_diff]);
2373
2.84M
    _mm_storeu_si128((__m128i *)(dst), resxy);
2374
2.84M
    dst += stride;
2375
2.84M
  }
2376
300k
}
2377
2378
static void highbd_dr_prediction_z2_Nx8_avx2(
2379
    int N, uint16_t *dst, ptrdiff_t stride, const uint16_t *above,
2380
    const uint16_t *left, int upsample_above, int upsample_left, int dx,
2381
245k
    int dy) {
2382
245k
  const int min_base_x = -(1 << upsample_above);
2383
245k
  const int min_base_y = -(1 << upsample_left);
2384
245k
  const int frac_bits_x = 6 - upsample_above;
2385
245k
  const int frac_bits_y = 6 - upsample_left;
2386
2387
  // pre-filter above pixels
2388
  // store in temp buffers:
2389
  //   above[x] * 32 + 16
2390
  //   above[x+1] - above[x]
2391
  // final pixels will be calculated as:
2392
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
2393
245k
  __m128i c3f, min_base_y128;
2394
245k
  __m256i a0_x, a1_x, diff, a32, a16;
2395
245k
  __m128i a0_x128, a1_x128;
2396
2397
245k
  a16 = _mm256_set1_epi16(16);
2398
245k
  c3f = _mm_set1_epi16(0x3f);
2399
245k
  min_base_y128 = _mm_set1_epi16(min_base_y);
2400
2401
2.69M
  for (int r = 0; r < N; r++) {
2402
2.44M
    __m256i b, res, shift;
2403
2.44M
    __m128i resx, resy, resxy;
2404
2.44M
    int y = r + 1;
2405
2.44M
    int base_x = (-y * dx) >> frac_bits_x;
2406
2.44M
    int base_shift = 0;
2407
2.44M
    if (base_x < (min_base_x - 1)) {
2408
1.83M
      base_shift = (min_base_x - base_x - 1) >> upsample_above;
2409
1.83M
    }
2410
2.44M
    int base_min_diff =
2411
2.44M
        (min_base_x - base_x + upsample_above) >> upsample_above;
2412
2.44M
    if (base_min_diff > 8) {
2413
1.09M
      base_min_diff = 8;
2414
1.35M
    } else {
2415
1.35M
      if (base_min_diff < 0) base_min_diff = 0;
2416
1.35M
    }
2417
2418
2.44M
    if (base_shift > 7) {
2419
1.09M
      a0_x = _mm256_setzero_si256();
2420
1.09M
      a1_x = _mm256_setzero_si256();
2421
1.09M
      shift = _mm256_setzero_si256();
2422
1.35M
    } else {
2423
1.35M
      a0_x128 = _mm_loadu_si128((__m128i *)(above + base_x + base_shift));
2424
1.35M
      if (upsample_above) {
2425
337k
        __m128i mask, atmp0, atmp1, atmp2, atmp3;
2426
337k
        a1_x128 = _mm_loadu_si128((__m128i *)(above + base_x + 8 + base_shift));
2427
337k
        atmp0 = _mm_shuffle_epi8(a0_x128,
2428
337k
                                 *(__m128i *)HighbdEvenOddMaskx[base_shift]);
2429
337k
        atmp1 = _mm_shuffle_epi8(a1_x128,
2430
337k
                                 *(__m128i *)HighbdEvenOddMaskx[base_shift]);
2431
337k
        atmp2 = _mm_shuffle_epi8(
2432
337k
            a0_x128, *(__m128i *)(HighbdEvenOddMaskx[base_shift] + 16));
2433
337k
        atmp3 = _mm_shuffle_epi8(
2434
337k
            a1_x128, *(__m128i *)(HighbdEvenOddMaskx[base_shift] + 16));
2435
337k
        mask = _mm_cmpgt_epi8(*(__m128i *)HighbdEvenOddMaskx[base_shift],
2436
337k
                              _mm_set1_epi8(15));
2437
337k
        a0_x128 = _mm_blendv_epi8(atmp0, atmp1, mask);
2438
337k
        mask = _mm_cmpgt_epi8(*(__m128i *)(HighbdEvenOddMaskx[base_shift] + 16),
2439
337k
                              _mm_set1_epi8(15));
2440
337k
        a1_x128 = _mm_blendv_epi8(atmp2, atmp3, mask);
2441
2442
337k
        shift = _mm256_castsi128_si256(_mm_srli_epi16(
2443
337k
            _mm_and_si128(
2444
337k
                _mm_slli_epi16(
2445
337k
                    _mm_setr_epi16(-y * dx, (1 << 6) - y * dx,
2446
337k
                                   (2 << 6) - y * dx, (3 << 6) - y * dx,
2447
337k
                                   (4 << 6) - y * dx, (5 << 6) - y * dx,
2448
337k
                                   (6 << 6) - y * dx, (7 << 6) - y * dx),
2449
337k
                    upsample_above),
2450
337k
                c3f),
2451
337k
            1));
2452
1.01M
      } else {
2453
1.01M
        a1_x128 = _mm_loadu_si128((__m128i *)(above + base_x + 1 + base_shift));
2454
1.01M
        a0_x128 =
2455
1.01M
            _mm_shuffle_epi8(a0_x128, *(__m128i *)HighbdLoadMaskx[base_shift]);
2456
1.01M
        a1_x128 =
2457
1.01M
            _mm_shuffle_epi8(a1_x128, *(__m128i *)HighbdLoadMaskx[base_shift]);
2458
2459
1.01M
        shift = _mm256_castsi128_si256(_mm_srli_epi16(
2460
1.01M
            _mm_and_si128(_mm_setr_epi16(-y * dx, (1 << 6) - y * dx,
2461
1.01M
                                         (2 << 6) - y * dx, (3 << 6) - y * dx,
2462
1.01M
                                         (4 << 6) - y * dx, (5 << 6) - y * dx,
2463
1.01M
                                         (6 << 6) - y * dx, (7 << 6) - y * dx),
2464
1.01M
                          c3f),
2465
1.01M
            1));
2466
1.01M
      }
2467
1.35M
      a0_x = _mm256_castsi128_si256(a0_x128);
2468
1.35M
      a1_x = _mm256_castsi128_si256(a1_x128);
2469
1.35M
    }
2470
2471
    // y calc
2472
2.44M
    __m128i a0_y, a1_y, shifty;
2473
2.44M
    if (base_x < min_base_x) {
2474
2.05M
      DECLARE_ALIGNED(32, int16_t, base_y_c[8]);
2475
2.05M
      __m128i r6, c1234, dy128, y_c128, base_y_c128, mask128;
2476
2.05M
      r6 = _mm_set1_epi16(r << 6);
2477
2.05M
      dy128 = _mm_set1_epi16(dy);
2478
2.05M
      c1234 = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8);
2479
2.05M
      y_c128 = _mm_sub_epi16(r6, _mm_mullo_epi16(c1234, dy128));
2480
2.05M
      base_y_c128 = _mm_srai_epi16(y_c128, frac_bits_y);
2481
2.05M
      mask128 = _mm_cmpgt_epi16(min_base_y128, base_y_c128);
2482
2.05M
      base_y_c128 = _mm_andnot_si128(mask128, base_y_c128);
2483
2.05M
      _mm_store_si128((__m128i *)base_y_c, base_y_c128);
2484
2485
2.05M
      a0_y = _mm_setr_epi16(left[base_y_c[0]], left[base_y_c[1]],
2486
2.05M
                            left[base_y_c[2]], left[base_y_c[3]],
2487
2.05M
                            left[base_y_c[4]], left[base_y_c[5]],
2488
2.05M
                            left[base_y_c[6]], left[base_y_c[7]]);
2489
2.05M
      a1_y = _mm_setr_epi16(left[base_y_c[0] + 1], left[base_y_c[1] + 1],
2490
2.05M
                            left[base_y_c[2] + 1], left[base_y_c[3] + 1],
2491
2.05M
                            left[base_y_c[4] + 1], left[base_y_c[5] + 1],
2492
2.05M
                            left[base_y_c[6] + 1], left[base_y_c[7] + 1]);
2493
2494
2.05M
      if (upsample_left) {
2495
479k
        shifty = _mm_srli_epi16(
2496
479k
            _mm_and_si128(_mm_slli_epi16((y_c128), upsample_left), c3f), 1);
2497
1.57M
      } else {
2498
1.57M
        shifty = _mm_srli_epi16(_mm_and_si128(y_c128, c3f), 1);
2499
1.57M
      }
2500
2.05M
      a0_x = _mm256_inserti128_si256(a0_x, a0_y, 1);
2501
2.05M
      a1_x = _mm256_inserti128_si256(a1_x, a1_y, 1);
2502
2.05M
      shift = _mm256_inserti128_si256(shift, shifty, 1);
2503
2.05M
    }
2504
2505
2.44M
    diff = _mm256_sub_epi16(a1_x, a0_x);  // a[x+1] - a[x]
2506
2.44M
    a32 = _mm256_slli_epi16(a0_x, 5);     // a[x] * 32
2507
2.44M
    a32 = _mm256_add_epi16(a32, a16);     // a[x] * 32 + 16
2508
2509
2.44M
    b = _mm256_mullo_epi16(diff, shift);
2510
2.44M
    res = _mm256_add_epi16(a32, b);
2511
2.44M
    res = _mm256_srli_epi16(res, 5);
2512
2513
2.44M
    resx = _mm256_castsi256_si128(res);
2514
2.44M
    resy = _mm256_extracti128_si256(res, 1);
2515
2516
2.44M
    resxy =
2517
2.44M
        _mm_blendv_epi8(resx, resy, *(__m128i *)HighbdBaseMask[base_min_diff]);
2518
2.44M
    _mm_storeu_si128((__m128i *)(dst), resxy);
2519
2.44M
    dst += stride;
2520
2.44M
  }
2521
245k
}
2522
2523
static void highbd_dr_prediction_32bit_z2_HxW_avx2(
2524
    int H, int W, uint16_t *dst, ptrdiff_t stride, const uint16_t *above,
2525
    const uint16_t *left, int upsample_above, int upsample_left, int dx,
2526
188k
    int dy) {
2527
  // here upsample_above and upsample_left are 0 by design of
2528
  // av1_use_intra_edge_upsample
2529
188k
  const int min_base_x = -1;
2530
188k
  const int min_base_y = -1;
2531
188k
  (void)upsample_above;
2532
188k
  (void)upsample_left;
2533
188k
  const int frac_bits_x = 6;
2534
188k
  const int frac_bits_y = 6;
2535
2536
  // pre-filter above pixels
2537
  // store in temp buffers:
2538
  //   above[x] * 32 + 16
2539
  //   above[x+1] - above[x]
2540
  // final pixels will be calculated as:
2541
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
2542
188k
  __m256i a0_x, a1_x, a0_y, a1_y, a32, a0_1_x, a1_1_x, a16, c1;
2543
188k
  __m256i diff, min_base_y256, c3f, dy256, c1234, c0123, c8;
2544
188k
  __m128i a0_x128, a1_x128, a0_1_x128, a1_1_x128;
2545
188k
  DECLARE_ALIGNED(32, int, base_y_c[16]);
2546
2547
188k
  a16 = _mm256_set1_epi32(16);
2548
188k
  c1 = _mm256_srli_epi32(a16, 4);
2549
188k
  c8 = _mm256_srli_epi32(a16, 1);
2550
188k
  min_base_y256 = _mm256_set1_epi32(min_base_y);
2551
188k
  c3f = _mm256_set1_epi32(0x3f);
2552
188k
  dy256 = _mm256_set1_epi32(dy);
2553
188k
  c0123 = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
2554
188k
  c1234 = _mm256_add_epi32(c0123, c1);
2555
2556
2.55M
  for (int r = 0; r < H; r++) {
2557
2.36M
    __m256i b, res, shift, ydx;
2558
2.36M
    __m256i resx[2], resy[2];
2559
2.36M
    __m256i resxy, j256, r6;
2560
6.75M
    for (int j = 0; j < W; j += 16) {
2561
4.39M
      j256 = _mm256_set1_epi32(j);
2562
4.39M
      int y = r + 1;
2563
4.39M
      ydx = _mm256_set1_epi32(y * dx);
2564
2565
4.39M
      int base_x = ((j << 6) - y * dx) >> frac_bits_x;
2566
4.39M
      int base_shift = 0;
2567
4.39M
      if ((base_x) < (min_base_x - 1)) {
2568
2.75M
        base_shift = (min_base_x - base_x - 1);
2569
2.75M
      }
2570
4.39M
      int base_min_diff = (min_base_x - base_x);
2571
4.39M
      if (base_min_diff > 16) {
2572
1.75M
        base_min_diff = 16;
2573
2.63M
      } else {
2574
2.63M
        if (base_min_diff < 0) base_min_diff = 0;
2575
2.63M
      }
2576
2577
4.39M
      if (base_shift > 7) {
2578
2.13M
        resx[0] = _mm256_setzero_si256();
2579
2.26M
      } else {
2580
2.26M
        a0_x128 = _mm_loadu_si128((__m128i *)(above + base_x + base_shift));
2581
2.26M
        a1_x128 = _mm_loadu_si128((__m128i *)(above + base_x + base_shift + 1));
2582
2.26M
        a0_x128 =
2583
2.26M
            _mm_shuffle_epi8(a0_x128, *(__m128i *)HighbdLoadMaskx[base_shift]);
2584
2.26M
        a1_x128 =
2585
2.26M
            _mm_shuffle_epi8(a1_x128, *(__m128i *)HighbdLoadMaskx[base_shift]);
2586
2587
2.26M
        a0_x = _mm256_cvtepu16_epi32(a0_x128);
2588
2.26M
        a1_x = _mm256_cvtepu16_epi32(a1_x128);
2589
2590
2.26M
        r6 = _mm256_slli_epi32(_mm256_add_epi32(c0123, j256), 6);
2591
2.26M
        shift = _mm256_srli_epi32(
2592
2.26M
            _mm256_and_si256(_mm256_sub_epi32(r6, ydx), c3f), 1);
2593
2594
2.26M
        diff = _mm256_sub_epi32(a1_x, a0_x);  // a[x+1] - a[x]
2595
2.26M
        a32 = _mm256_slli_epi32(a0_x, 5);     // a[x] * 32
2596
2.26M
        a32 = _mm256_add_epi32(a32, a16);     // a[x] * 32 + 16
2597
2598
2.26M
        b = _mm256_mullo_epi32(diff, shift);
2599
2.26M
        res = _mm256_add_epi32(a32, b);
2600
2.26M
        res = _mm256_srli_epi32(res, 5);
2601
2602
2.26M
        resx[0] = _mm256_packus_epi32(
2603
2.26M
            res, _mm256_castsi128_si256(_mm256_extracti128_si256(res, 1)));
2604
2.26M
      }
2605
4.39M
      int base_shift8 = 0;
2606
4.39M
      if ((base_x + 8) < (min_base_x - 1)) {
2607
2.08M
        base_shift8 = (min_base_x - (base_x + 8) - 1);
2608
2.08M
      }
2609
4.39M
      if (base_shift8 > 7) {
2610
1.75M
        resx[1] = _mm256_setzero_si256();
2611
2.63M
      } else {
2612
2.63M
        a0_1_x128 =
2613
2.63M
            _mm_loadu_si128((__m128i *)(above + base_x + base_shift8 + 8));
2614
2.63M
        a1_1_x128 =
2615
2.63M
            _mm_loadu_si128((__m128i *)(above + base_x + base_shift8 + 9));
2616
2.63M
        a0_1_x128 = _mm_shuffle_epi8(a0_1_x128,
2617
2.63M
                                     *(__m128i *)HighbdLoadMaskx[base_shift8]);
2618
2.63M
        a1_1_x128 = _mm_shuffle_epi8(a1_1_x128,
2619
2.63M
                                     *(__m128i *)HighbdLoadMaskx[base_shift8]);
2620
2621
2.63M
        a0_1_x = _mm256_cvtepu16_epi32(a0_1_x128);
2622
2.63M
        a1_1_x = _mm256_cvtepu16_epi32(a1_1_x128);
2623
2624
2.63M
        r6 = _mm256_slli_epi32(
2625
2.63M
            _mm256_add_epi32(c0123, _mm256_add_epi32(j256, c8)), 6);
2626
2.63M
        shift = _mm256_srli_epi32(
2627
2.63M
            _mm256_and_si256(_mm256_sub_epi32(r6, ydx), c3f), 1);
2628
2629
2.63M
        diff = _mm256_sub_epi32(a1_1_x, a0_1_x);  // a[x+1] - a[x]
2630
2.63M
        a32 = _mm256_slli_epi32(a0_1_x, 5);       // a[x] * 32
2631
2.63M
        a32 = _mm256_add_epi32(a32, a16);         // a[x] * 32 + 16
2632
2.63M
        b = _mm256_mullo_epi32(diff, shift);
2633
2634
2.63M
        resx[1] = _mm256_add_epi32(a32, b);
2635
2.63M
        resx[1] = _mm256_srli_epi32(resx[1], 5);
2636
2.63M
        resx[1] = _mm256_packus_epi32(
2637
2.63M
            resx[1],
2638
2.63M
            _mm256_castsi128_si256(_mm256_extracti128_si256(resx[1], 1)));
2639
2.63M
      }
2640
4.39M
      resx[0] =
2641
4.39M
          _mm256_inserti128_si256(resx[0], _mm256_castsi256_si128(resx[1]),
2642
4.39M
                                  1);  // 16 16bit values
2643
2644
      // y calc
2645
4.39M
      resy[0] = _mm256_setzero_si256();
2646
4.39M
      if ((base_x < min_base_x)) {
2647
2.93M
        __m256i c256, y_c256, y_c_1_256, base_y_c256, mask256;
2648
2.93M
        r6 = _mm256_set1_epi32(r << 6);
2649
2.93M
        c256 = _mm256_add_epi32(j256, c1234);
2650
2.93M
        y_c256 = _mm256_sub_epi32(r6, _mm256_mullo_epi32(c256, dy256));
2651
2.93M
        base_y_c256 = _mm256_srai_epi32(y_c256, frac_bits_y);
2652
2.93M
        mask256 = _mm256_cmpgt_epi32(min_base_y256, base_y_c256);
2653
2.93M
        base_y_c256 = _mm256_andnot_si256(mask256, base_y_c256);
2654
2.93M
        _mm256_store_si256((__m256i *)base_y_c, base_y_c256);
2655
2.93M
        c256 = _mm256_add_epi32(c256, c8);
2656
2.93M
        y_c_1_256 = _mm256_sub_epi32(r6, _mm256_mullo_epi32(c256, dy256));
2657
2.93M
        base_y_c256 = _mm256_srai_epi32(y_c_1_256, frac_bits_y);
2658
2.93M
        mask256 = _mm256_cmpgt_epi32(min_base_y256, base_y_c256);
2659
2.93M
        base_y_c256 = _mm256_andnot_si256(mask256, base_y_c256);
2660
2.93M
        _mm256_store_si256((__m256i *)(base_y_c + 8), base_y_c256);
2661
2662
2.93M
        a0_y = _mm256_cvtepu16_epi32(_mm_setr_epi16(
2663
2.93M
            left[base_y_c[0]], left[base_y_c[1]], left[base_y_c[2]],
2664
2.93M
            left[base_y_c[3]], left[base_y_c[4]], left[base_y_c[5]],
2665
2.93M
            left[base_y_c[6]], left[base_y_c[7]]));
2666
2.93M
        a1_y = _mm256_cvtepu16_epi32(_mm_setr_epi16(
2667
2.93M
            left[base_y_c[0] + 1], left[base_y_c[1] + 1], left[base_y_c[2] + 1],
2668
2.93M
            left[base_y_c[3] + 1], left[base_y_c[4] + 1], left[base_y_c[5] + 1],
2669
2.93M
            left[base_y_c[6] + 1], left[base_y_c[7] + 1]));
2670
2671
2.93M
        shift = _mm256_srli_epi32(_mm256_and_si256(y_c256, c3f), 1);
2672
2673
2.93M
        diff = _mm256_sub_epi32(a1_y, a0_y);  // a[x+1] - a[x]
2674
2.93M
        a32 = _mm256_slli_epi32(a0_y, 5);     // a[x] * 32
2675
2.93M
        a32 = _mm256_add_epi32(a32, a16);     // a[x] * 32 + 16
2676
2677
2.93M
        b = _mm256_mullo_epi32(diff, shift);
2678
2.93M
        res = _mm256_add_epi32(a32, b);
2679
2.93M
        res = _mm256_srli_epi32(res, 5);
2680
2681
2.93M
        resy[0] = _mm256_packus_epi32(
2682
2.93M
            res, _mm256_castsi128_si256(_mm256_extracti128_si256(res, 1)));
2683
2684
2.93M
        a0_y = _mm256_cvtepu16_epi32(_mm_setr_epi16(
2685
2.93M
            left[base_y_c[8]], left[base_y_c[9]], left[base_y_c[10]],
2686
2.93M
            left[base_y_c[11]], left[base_y_c[12]], left[base_y_c[13]],
2687
2.93M
            left[base_y_c[14]], left[base_y_c[15]]));
2688
2.93M
        a1_y = _mm256_cvtepu16_epi32(
2689
2.93M
            _mm_setr_epi16(left[base_y_c[8] + 1], left[base_y_c[9] + 1],
2690
2.93M
                           left[base_y_c[10] + 1], left[base_y_c[11] + 1],
2691
2.93M
                           left[base_y_c[12] + 1], left[base_y_c[13] + 1],
2692
2.93M
                           left[base_y_c[14] + 1], left[base_y_c[15] + 1]));
2693
2.93M
        shift = _mm256_srli_epi32(_mm256_and_si256(y_c_1_256, c3f), 1);
2694
2695
2.93M
        diff = _mm256_sub_epi32(a1_y, a0_y);  // a[x+1] - a[x]
2696
2.93M
        a32 = _mm256_slli_epi32(a0_y, 5);     // a[x] * 32
2697
2.93M
        a32 = _mm256_add_epi32(a32, a16);     // a[x] * 32 + 16
2698
2699
2.93M
        b = _mm256_mullo_epi32(diff, shift);
2700
2.93M
        res = _mm256_add_epi32(a32, b);
2701
2.93M
        res = _mm256_srli_epi32(res, 5);
2702
2703
2.93M
        resy[1] = _mm256_packus_epi32(
2704
2.93M
            res, _mm256_castsi128_si256(_mm256_extracti128_si256(res, 1)));
2705
2706
2.93M
        resy[0] =
2707
2.93M
            _mm256_inserti128_si256(resy[0], _mm256_castsi256_si128(resy[1]),
2708
2.93M
                                    1);  // 16 16bit values
2709
2.93M
      }
2710
2711
4.39M
      resxy = _mm256_blendv_epi8(resx[0], resy[0],
2712
4.39M
                                 *(__m256i *)HighbdBaseMask[base_min_diff]);
2713
4.39M
      _mm256_storeu_si256((__m256i *)(dst + j), resxy);
2714
4.39M
    }  // for j
2715
2.36M
    dst += stride;
2716
2.36M
  }
2717
188k
}
2718
2719
static void highbd_dr_prediction_z2_HxW_avx2(
2720
    int H, int W, uint16_t *dst, ptrdiff_t stride, const uint16_t *above,
2721
    const uint16_t *left, int upsample_above, int upsample_left, int dx,
2722
468k
    int dy) {
2723
  // here upsample_above and upsample_left are 0 by design of
2724
  // av1_use_intra_edge_upsample
2725
468k
  const int min_base_x = -1;
2726
468k
  const int min_base_y = -1;
2727
468k
  (void)upsample_above;
2728
468k
  (void)upsample_left;
2729
468k
  const int frac_bits_x = 6;
2730
468k
  const int frac_bits_y = 6;
2731
2732
  // pre-filter above pixels
2733
  // store in temp buffers:
2734
  //   above[x] * 32 + 16
2735
  //   above[x+1] - above[x]
2736
  // final pixels will be calculated as:
2737
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
2738
468k
  __m256i a0_x, a1_x, a32, a16, c3f, c1;
2739
468k
  __m256i diff, min_base_y256, dy256, c1234, c0123;
2740
468k
  DECLARE_ALIGNED(32, int16_t, base_y_c[16]);
2741
2742
468k
  a16 = _mm256_set1_epi16(16);
2743
468k
  c1 = _mm256_srli_epi16(a16, 4);
2744
468k
  min_base_y256 = _mm256_set1_epi16(min_base_y);
2745
468k
  c3f = _mm256_set1_epi16(0x3f);
2746
468k
  dy256 = _mm256_set1_epi16(dy);
2747
468k
  c0123 =
2748
468k
      _mm256_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
2749
468k
  c1234 = _mm256_add_epi16(c0123, c1);
2750
2751
9.71M
  for (int r = 0; r < H; r++) {
2752
9.24M
    __m256i b, res, shift;
2753
9.24M
    __m256i resx, resy, ydx;
2754
9.24M
    __m256i resxy, j256, r6;
2755
9.24M
    __m128i a0_x128, a1_x128, a0_1_x128, a1_1_x128;
2756
9.24M
    int y = r + 1;
2757
9.24M
    ydx = _mm256_set1_epi16((short)(y * dx));
2758
2759
25.6M
    for (int j = 0; j < W; j += 16) {
2760
16.4M
      j256 = _mm256_set1_epi16(j);
2761
16.4M
      int base_x = ((j << 6) - y * dx) >> frac_bits_x;
2762
16.4M
      int base_shift = 0;
2763
16.4M
      if ((base_x) < (min_base_x - 1)) {
2764
12.1M
        base_shift = (min_base_x - (base_x)-1);
2765
12.1M
      }
2766
16.4M
      int base_min_diff = (min_base_x - base_x);
2767
16.4M
      if (base_min_diff > 16) {
2768
8.93M
        base_min_diff = 16;
2769
8.93M
      } else {
2770
7.48M
        if (base_min_diff < 0) base_min_diff = 0;
2771
7.48M
      }
2772
2773
16.4M
      if (base_shift < 8) {
2774
6.24M
        a0_x128 = _mm_loadu_si128((__m128i *)(above + base_x + base_shift));
2775
6.24M
        a1_x128 = _mm_loadu_si128((__m128i *)(above + base_x + base_shift + 1));
2776
6.24M
        a0_x128 =
2777
6.24M
            _mm_shuffle_epi8(a0_x128, *(__m128i *)HighbdLoadMaskx[base_shift]);
2778
6.24M
        a1_x128 =
2779
6.24M
            _mm_shuffle_epi8(a1_x128, *(__m128i *)HighbdLoadMaskx[base_shift]);
2780
2781
6.24M
        a0_x = _mm256_castsi128_si256(a0_x128);
2782
6.24M
        a1_x = _mm256_castsi128_si256(a1_x128);
2783
10.1M
      } else {
2784
10.1M
        a0_x = _mm256_setzero_si256();
2785
10.1M
        a1_x = _mm256_setzero_si256();
2786
10.1M
      }
2787
2788
16.4M
      int base_shift1 = 0;
2789
16.4M
      if (base_shift > 8) {
2790
9.98M
        base_shift1 = base_shift - 8;
2791
9.98M
      }
2792
16.4M
      if (base_shift1 < 8) {
2793
7.48M
        a0_1_x128 =
2794
7.48M
            _mm_loadu_si128((__m128i *)(above + base_x + base_shift1 + 8));
2795
7.48M
        a1_1_x128 =
2796
7.48M
            _mm_loadu_si128((__m128i *)(above + base_x + base_shift1 + 9));
2797
7.48M
        a0_1_x128 = _mm_shuffle_epi8(a0_1_x128,
2798
7.48M
                                     *(__m128i *)HighbdLoadMaskx[base_shift1]);
2799
7.48M
        a1_1_x128 = _mm_shuffle_epi8(a1_1_x128,
2800
7.48M
                                     *(__m128i *)HighbdLoadMaskx[base_shift1]);
2801
2802
7.48M
        a0_x = _mm256_inserti128_si256(a0_x, a0_1_x128, 1);
2803
7.48M
        a1_x = _mm256_inserti128_si256(a1_x, a1_1_x128, 1);
2804
7.48M
      }
2805
16.4M
      r6 = _mm256_slli_epi16(_mm256_add_epi16(c0123, j256), 6);
2806
16.4M
      shift = _mm256_srli_epi16(
2807
16.4M
          _mm256_and_si256(_mm256_sub_epi16(r6, ydx), c3f), 1);
2808
2809
16.4M
      diff = _mm256_sub_epi16(a1_x, a0_x);  // a[x+1] - a[x]
2810
16.4M
      a32 = _mm256_slli_epi16(a0_x, 5);     // a[x] * 32
2811
16.4M
      a32 = _mm256_add_epi16(a32, a16);     // a[x] * 32 + 16
2812
2813
16.4M
      b = _mm256_mullo_epi16(diff, shift);
2814
16.4M
      res = _mm256_add_epi16(a32, b);
2815
16.4M
      resx = _mm256_srli_epi16(res, 5);  // 16 16-bit values
2816
2817
      // y calc
2818
16.4M
      resy = _mm256_setzero_si256();
2819
16.4M
      __m256i a0_y, a1_y, shifty;
2820
16.4M
      if ((base_x < min_base_x)) {
2821
12.8M
        __m256i c256, y_c256, base_y_c256, mask256, mul16;
2822
12.8M
        r6 = _mm256_set1_epi16(r << 6);
2823
12.8M
        c256 = _mm256_add_epi16(j256, c1234);
2824
12.8M
        mul16 = _mm256_min_epu16(_mm256_mullo_epi16(c256, dy256),
2825
12.8M
                                 _mm256_srli_epi16(min_base_y256, 1));
2826
12.8M
        y_c256 = _mm256_sub_epi16(r6, mul16);
2827
12.8M
        base_y_c256 = _mm256_srai_epi16(y_c256, frac_bits_y);
2828
12.8M
        mask256 = _mm256_cmpgt_epi16(min_base_y256, base_y_c256);
2829
12.8M
        base_y_c256 = _mm256_andnot_si256(mask256, base_y_c256);
2830
12.8M
        _mm256_store_si256((__m256i *)base_y_c, base_y_c256);
2831
2832
12.8M
        a0_y = _mm256_setr_epi16(
2833
12.8M
            left[base_y_c[0]], left[base_y_c[1]], left[base_y_c[2]],
2834
12.8M
            left[base_y_c[3]], left[base_y_c[4]], left[base_y_c[5]],
2835
12.8M
            left[base_y_c[6]], left[base_y_c[7]], left[base_y_c[8]],
2836
12.8M
            left[base_y_c[9]], left[base_y_c[10]], left[base_y_c[11]],
2837
12.8M
            left[base_y_c[12]], left[base_y_c[13]], left[base_y_c[14]],
2838
12.8M
            left[base_y_c[15]]);
2839
12.8M
        base_y_c256 = _mm256_add_epi16(base_y_c256, c1);
2840
12.8M
        _mm256_store_si256((__m256i *)base_y_c, base_y_c256);
2841
2842
12.8M
        a1_y = _mm256_setr_epi16(
2843
12.8M
            left[base_y_c[0]], left[base_y_c[1]], left[base_y_c[2]],
2844
12.8M
            left[base_y_c[3]], left[base_y_c[4]], left[base_y_c[5]],
2845
12.8M
            left[base_y_c[6]], left[base_y_c[7]], left[base_y_c[8]],
2846
12.8M
            left[base_y_c[9]], left[base_y_c[10]], left[base_y_c[11]],
2847
12.8M
            left[base_y_c[12]], left[base_y_c[13]], left[base_y_c[14]],
2848
12.8M
            left[base_y_c[15]]);
2849
2850
12.8M
        shifty = _mm256_srli_epi16(_mm256_and_si256(y_c256, c3f), 1);
2851
2852
12.8M
        diff = _mm256_sub_epi16(a1_y, a0_y);  // a[x+1] - a[x]
2853
12.8M
        a32 = _mm256_slli_epi16(a0_y, 5);     // a[x] * 32
2854
12.8M
        a32 = _mm256_add_epi16(a32, a16);     // a[x] * 32 + 16
2855
2856
12.8M
        b = _mm256_mullo_epi16(diff, shifty);
2857
12.8M
        res = _mm256_add_epi16(a32, b);
2858
12.8M
        resy = _mm256_srli_epi16(res, 5);
2859
12.8M
      }
2860
2861
16.4M
      resxy = _mm256_blendv_epi8(resx, resy,
2862
16.4M
                                 *(__m256i *)HighbdBaseMask[base_min_diff]);
2863
16.4M
      _mm256_storeu_si256((__m256i *)(dst + j), resxy);
2864
16.4M
    }  // for j
2865
9.24M
    dst += stride;
2866
9.24M
  }
2867
468k
}
2868
2869
// Directional prediction, zone 2: 90 < angle < 180
2870
void av1_highbd_dr_prediction_z2_avx2(uint16_t *dst, ptrdiff_t stride, int bw,
2871
                                      int bh, const uint16_t *above,
2872
                                      const uint16_t *left, int upsample_above,
2873
                                      int upsample_left, int dx, int dy,
2874
1.72M
                                      int bd) {
2875
1.72M
  (void)bd;
2876
1.72M
  assert(dx > 0);
2877
1.72M
  assert(dy > 0);
2878
1.72M
  switch (bw) {
2879
517k
    case 4:
2880
517k
      if (bd < 12) {
2881
220k
        highbd_dr_prediction_z2_Nx4_avx2(bh, dst, stride, above, left,
2882
220k
                                         upsample_above, upsample_left, dx, dy);
2883
297k
      } else {
2884
297k
        highbd_dr_prediction_32bit_z2_Nx4_avx2(bh, dst, stride, above, left,
2885
297k
                                               upsample_above, upsample_left,
2886
297k
                                               dx, dy);
2887
297k
      }
2888
517k
      break;
2889
546k
    case 8:
2890
546k
      if (bd < 12) {
2891
245k
        highbd_dr_prediction_z2_Nx8_avx2(bh, dst, stride, above, left,
2892
245k
                                         upsample_above, upsample_left, dx, dy);
2893
300k
      } else {
2894
300k
        highbd_dr_prediction_32bit_z2_Nx8_avx2(bh, dst, stride, above, left,
2895
300k
                                               upsample_above, upsample_left,
2896
300k
                                               dx, dy);
2897
300k
      }
2898
546k
      break;
2899
656k
    default:
2900
656k
      if (bd < 12) {
2901
468k
        highbd_dr_prediction_z2_HxW_avx2(bh, bw, dst, stride, above, left,
2902
468k
                                         upsample_above, upsample_left, dx, dy);
2903
468k
      } else {
2904
188k
        highbd_dr_prediction_32bit_z2_HxW_avx2(bh, bw, dst, stride, above, left,
2905
188k
                                               upsample_above, upsample_left,
2906
188k
                                               dx, dy);
2907
188k
      }
2908
656k
      break;
2909
1.72M
  }
2910
1.72M
}
2911
2912
//  Directional prediction, zone 3 functions
2913
static void highbd_dr_prediction_z3_4x4_avx2(uint16_t *dst, ptrdiff_t stride,
2914
                                             const uint16_t *left,
2915
                                             int upsample_left, int dy,
2916
234k
                                             int bd) {
2917
234k
  __m128i dstvec[4], d[4];
2918
234k
  if (bd < 12) {
2919
190k
    highbd_dr_prediction_z1_4xN_internal_avx2(4, dstvec, left, upsample_left,
2920
190k
                                              dy);
2921
190k
  } else {
2922
43.8k
    highbd_dr_prediction_32bit_z1_4xN_internal_avx2(4, dstvec, left,
2923
43.8k
                                                    upsample_left, dy);
2924
43.8k
  }
2925
234k
  highbd_transpose4x8_8x4_low_sse2(&dstvec[0], &dstvec[1], &dstvec[2],
2926
234k
                                   &dstvec[3], &d[0], &d[1], &d[2], &d[3]);
2927
234k
  _mm_storel_epi64((__m128i *)(dst + 0 * stride), d[0]);
2928
234k
  _mm_storel_epi64((__m128i *)(dst + 1 * stride), d[1]);
2929
234k
  _mm_storel_epi64((__m128i *)(dst + 2 * stride), d[2]);
2930
234k
  _mm_storel_epi64((__m128i *)(dst + 3 * stride), d[3]);
2931
234k
  return;
2932
234k
}
2933
2934
static void highbd_dr_prediction_z3_8x8_avx2(uint16_t *dst, ptrdiff_t stride,
2935
                                             const uint16_t *left,
2936
                                             int upsample_left, int dy,
2937
212k
                                             int bd) {
2938
212k
  __m128i dstvec[8], d[8];
2939
212k
  if (bd < 12) {
2940
100k
    highbd_dr_prediction_z1_8xN_internal_avx2(8, dstvec, left, upsample_left,
2941
100k
                                              dy);
2942
112k
  } else {
2943
112k
    highbd_dr_prediction_32bit_z1_8xN_internal_avx2(8, dstvec, left,
2944
112k
                                                    upsample_left, dy);
2945
112k
  }
2946
212k
  highbd_transpose8x8_sse2(&dstvec[0], &dstvec[1], &dstvec[2], &dstvec[3],
2947
212k
                           &dstvec[4], &dstvec[5], &dstvec[6], &dstvec[7],
2948
212k
                           &d[0], &d[1], &d[2], &d[3], &d[4], &d[5], &d[6],
2949
212k
                           &d[7]);
2950
1.91M
  for (int i = 0; i < 8; i++) {
2951
1.70M
    _mm_storeu_si128((__m128i *)(dst + i * stride), d[i]);
2952
1.70M
  }
2953
212k
}
2954
2955
static void highbd_dr_prediction_z3_4x8_avx2(uint16_t *dst, ptrdiff_t stride,
2956
                                             const uint16_t *left,
2957
                                             int upsample_left, int dy,
2958
32.2k
                                             int bd) {
2959
32.2k
  __m128i dstvec[4], d[8];
2960
32.2k
  if (bd < 12) {
2961
17.8k
    highbd_dr_prediction_z1_8xN_internal_avx2(4, dstvec, left, upsample_left,
2962
17.8k
                                              dy);
2963
17.8k
  } else {
2964
14.3k
    highbd_dr_prediction_32bit_z1_8xN_internal_avx2(4, dstvec, left,
2965
14.3k
                                                    upsample_left, dy);
2966
14.3k
  }
2967
2968
32.2k
  highbd_transpose4x8_8x4_sse2(&dstvec[0], &dstvec[1], &dstvec[2], &dstvec[3],
2969
32.2k
                               &d[0], &d[1], &d[2], &d[3], &d[4], &d[5], &d[6],
2970
32.2k
                               &d[7]);
2971
289k
  for (int i = 0; i < 8; i++) {
2972
257k
    _mm_storel_epi64((__m128i *)(dst + i * stride), d[i]);
2973
257k
  }
2974
32.2k
}
2975
2976
static void highbd_dr_prediction_z3_8x4_avx2(uint16_t *dst, ptrdiff_t stride,
2977
                                             const uint16_t *left,
2978
                                             int upsample_left, int dy,
2979
66.4k
                                             int bd) {
2980
66.4k
  __m128i dstvec[8], d[4];
2981
66.4k
  if (bd < 12) {
2982
34.1k
    highbd_dr_prediction_z1_4xN_internal_avx2(8, dstvec, left, upsample_left,
2983
34.1k
                                              dy);
2984
34.1k
  } else {
2985
32.3k
    highbd_dr_prediction_32bit_z1_4xN_internal_avx2(8, dstvec, left,
2986
32.3k
                                                    upsample_left, dy);
2987
32.3k
  }
2988
2989
66.4k
  highbd_transpose8x8_low_sse2(&dstvec[0], &dstvec[1], &dstvec[2], &dstvec[3],
2990
66.4k
                               &dstvec[4], &dstvec[5], &dstvec[6], &dstvec[7],
2991
66.4k
                               &d[0], &d[1], &d[2], &d[3]);
2992
66.4k
  _mm_storeu_si128((__m128i *)(dst + 0 * stride), d[0]);
2993
66.4k
  _mm_storeu_si128((__m128i *)(dst + 1 * stride), d[1]);
2994
66.4k
  _mm_storeu_si128((__m128i *)(dst + 2 * stride), d[2]);
2995
66.4k
  _mm_storeu_si128((__m128i *)(dst + 3 * stride), d[3]);
2996
66.4k
}
2997
2998
static void highbd_dr_prediction_z3_8x16_avx2(uint16_t *dst, ptrdiff_t stride,
2999
                                              const uint16_t *left,
3000
                                              int upsample_left, int dy,
3001
43.4k
                                              int bd) {
3002
43.4k
  __m256i dstvec[8], d[8];
3003
43.4k
  if (bd < 12) {
3004
25.7k
    highbd_dr_prediction_z1_16xN_internal_avx2(8, dstvec, left, upsample_left,
3005
25.7k
                                               dy);
3006
25.7k
  } else {
3007
17.6k
    highbd_dr_prediction_32bit_z1_16xN_internal_avx2(8, dstvec, left,
3008
17.6k
                                                     upsample_left, dy);
3009
17.6k
  }
3010
43.4k
  highbd_transpose8x16_16x8_avx2(dstvec, d);
3011
390k
  for (int i = 0; i < 8; i++) {
3012
347k
    _mm_storeu_si128((__m128i *)(dst + i * stride),
3013
347k
                     _mm256_castsi256_si128(d[i]));
3014
347k
  }
3015
390k
  for (int i = 8; i < 16; i++) {
3016
347k
    _mm_storeu_si128((__m128i *)(dst + i * stride),
3017
347k
                     _mm256_extracti128_si256(d[i - 8], 1));
3018
347k
  }
3019
43.4k
}
3020
3021
static void highbd_dr_prediction_z3_16x8_avx2(uint16_t *dst, ptrdiff_t stride,
3022
                                              const uint16_t *left,
3023
                                              int upsample_left, int dy,
3024
86.9k
                                              int bd) {
3025
86.9k
  __m128i dstvec[16], d[16];
3026
86.9k
  if (bd < 12) {
3027
46.5k
    highbd_dr_prediction_z1_8xN_internal_avx2(16, dstvec, left, upsample_left,
3028
46.5k
                                              dy);
3029
46.5k
  } else {
3030
40.4k
    highbd_dr_prediction_32bit_z1_8xN_internal_avx2(16, dstvec, left,
3031
40.4k
                                                    upsample_left, dy);
3032
40.4k
  }
3033
260k
  for (int i = 0; i < 16; i += 8) {
3034
173k
    highbd_transpose8x8_sse2(&dstvec[0 + i], &dstvec[1 + i], &dstvec[2 + i],
3035
173k
                             &dstvec[3 + i], &dstvec[4 + i], &dstvec[5 + i],
3036
173k
                             &dstvec[6 + i], &dstvec[7 + i], &d[0 + i],
3037
173k
                             &d[1 + i], &d[2 + i], &d[3 + i], &d[4 + i],
3038
173k
                             &d[5 + i], &d[6 + i], &d[7 + i]);
3039
173k
  }
3040
782k
  for (int i = 0; i < 8; i++) {
3041
695k
    _mm_storeu_si128((__m128i *)(dst + i * stride), d[i]);
3042
695k
    _mm_storeu_si128((__m128i *)(dst + i * stride + 8), d[i + 8]);
3043
695k
  }
3044
86.9k
}
3045
3046
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3047
static void highbd_dr_prediction_z3_4x16_avx2(uint16_t *dst, ptrdiff_t stride,
3048
                                              const uint16_t *left,
3049
                                              int upsample_left, int dy,
3050
27.3k
                                              int bd) {
3051
27.3k
  __m256i dstvec[4], d[4], d1;
3052
27.3k
  if (bd < 12) {
3053
14.9k
    highbd_dr_prediction_z1_16xN_internal_avx2(4, dstvec, left, upsample_left,
3054
14.9k
                                               dy);
3055
14.9k
  } else {
3056
12.3k
    highbd_dr_prediction_32bit_z1_16xN_internal_avx2(4, dstvec, left,
3057
12.3k
                                                     upsample_left, dy);
3058
12.3k
  }
3059
27.3k
  highbd_transpose4x16_avx2(dstvec, d);
3060
136k
  for (int i = 0; i < 4; i++) {
3061
109k
    _mm_storel_epi64((__m128i *)(dst + i * stride),
3062
109k
                     _mm256_castsi256_si128(d[i]));
3063
109k
    d1 = _mm256_bsrli_epi128(d[i], 8);
3064
109k
    _mm_storel_epi64((__m128i *)(dst + (i + 4) * stride),
3065
109k
                     _mm256_castsi256_si128(d1));
3066
109k
    _mm_storel_epi64((__m128i *)(dst + (i + 8) * stride),
3067
109k
                     _mm256_extracti128_si256(d[i], 1));
3068
109k
    _mm_storel_epi64((__m128i *)(dst + (i + 12) * stride),
3069
109k
                     _mm256_extracti128_si256(d1, 1));
3070
109k
  }
3071
27.3k
}
3072
3073
static void highbd_dr_prediction_z3_16x4_avx2(uint16_t *dst, ptrdiff_t stride,
3074
                                              const uint16_t *left,
3075
                                              int upsample_left, int dy,
3076
64.0k
                                              int bd) {
3077
64.0k
  __m128i dstvec[16], d[8];
3078
64.0k
  if (bd < 12) {
3079
46.5k
    highbd_dr_prediction_z1_4xN_internal_avx2(16, dstvec, left, upsample_left,
3080
46.5k
                                              dy);
3081
46.5k
  } else {
3082
17.4k
    highbd_dr_prediction_32bit_z1_4xN_internal_avx2(16, dstvec, left,
3083
17.4k
                                                    upsample_left, dy);
3084
17.4k
  }
3085
64.0k
  highbd_transpose16x4_8x8_sse2(dstvec, d);
3086
3087
64.0k
  _mm_storeu_si128((__m128i *)(dst + 0 * stride), d[0]);
3088
64.0k
  _mm_storeu_si128((__m128i *)(dst + 0 * stride + 8), d[1]);
3089
64.0k
  _mm_storeu_si128((__m128i *)(dst + 1 * stride), d[2]);
3090
64.0k
  _mm_storeu_si128((__m128i *)(dst + 1 * stride + 8), d[3]);
3091
64.0k
  _mm_storeu_si128((__m128i *)(dst + 2 * stride), d[4]);
3092
64.0k
  _mm_storeu_si128((__m128i *)(dst + 2 * stride + 8), d[5]);
3093
64.0k
  _mm_storeu_si128((__m128i *)(dst + 3 * stride), d[6]);
3094
64.0k
  _mm_storeu_si128((__m128i *)(dst + 3 * stride + 8), d[7]);
3095
64.0k
}
3096
3097
static void highbd_dr_prediction_z3_8x32_avx2(uint16_t *dst, ptrdiff_t stride,
3098
                                              const uint16_t *left,
3099
                                              int upsample_left, int dy,
3100
12.8k
                                              int bd) {
3101
12.8k
  __m256i dstvec[16], d[16];
3102
12.8k
  if (bd < 12) {
3103
10.4k
    highbd_dr_prediction_z1_32xN_internal_avx2(8, dstvec, left, upsample_left,
3104
10.4k
                                               dy);
3105
10.4k
  } else {
3106
2.36k
    highbd_dr_prediction_32bit_z1_32xN_internal_avx2(8, dstvec, left,
3107
2.36k
                                                     upsample_left, dy);
3108
2.36k
  }
3109
3110
38.5k
  for (int i = 0; i < 16; i += 8) {
3111
25.6k
    highbd_transpose8x16_16x8_avx2(dstvec + i, d + i);
3112
25.6k
  }
3113
3114
115k
  for (int i = 0; i < 8; i++) {
3115
102k
    _mm_storeu_si128((__m128i *)(dst + i * stride),
3116
102k
                     _mm256_castsi256_si128(d[i]));
3117
102k
  }
3118
115k
  for (int i = 0; i < 8; i++) {
3119
102k
    _mm_storeu_si128((__m128i *)(dst + (i + 8) * stride),
3120
102k
                     _mm256_extracti128_si256(d[i], 1));
3121
102k
  }
3122
115k
  for (int i = 8; i < 16; i++) {
3123
102k
    _mm_storeu_si128((__m128i *)(dst + (i + 8) * stride),
3124
102k
                     _mm256_castsi256_si128(d[i]));
3125
102k
  }
3126
115k
  for (int i = 8; i < 16; i++) {
3127
102k
    _mm_storeu_si128((__m128i *)(dst + (i + 16) * stride),
3128
102k
                     _mm256_extracti128_si256(d[i], 1));
3129
102k
  }
3130
12.8k
}
3131
3132
static void highbd_dr_prediction_z3_32x8_avx2(uint16_t *dst, ptrdiff_t stride,
3133
                                              const uint16_t *left,
3134
                                              int upsample_left, int dy,
3135
54.3k
                                              int bd) {
3136
54.3k
  __m128i dstvec[32], d[32];
3137
54.3k
  if (bd < 12) {
3138
45.3k
    highbd_dr_prediction_z1_8xN_internal_avx2(32, dstvec, left, upsample_left,
3139
45.3k
                                              dy);
3140
45.3k
  } else {
3141
8.98k
    highbd_dr_prediction_32bit_z1_8xN_internal_avx2(32, dstvec, left,
3142
8.98k
                                                    upsample_left, dy);
3143
8.98k
  }
3144
3145
271k
  for (int i = 0; i < 32; i += 8) {
3146
217k
    highbd_transpose8x8_sse2(&dstvec[0 + i], &dstvec[1 + i], &dstvec[2 + i],
3147
217k
                             &dstvec[3 + i], &dstvec[4 + i], &dstvec[5 + i],
3148
217k
                             &dstvec[6 + i], &dstvec[7 + i], &d[0 + i],
3149
217k
                             &d[1 + i], &d[2 + i], &d[3 + i], &d[4 + i],
3150
217k
                             &d[5 + i], &d[6 + i], &d[7 + i]);
3151
217k
  }
3152
489k
  for (int i = 0; i < 8; i++) {
3153
434k
    _mm_storeu_si128((__m128i *)(dst + i * stride), d[i]);
3154
434k
    _mm_storeu_si128((__m128i *)(dst + i * stride + 8), d[i + 8]);
3155
434k
    _mm_storeu_si128((__m128i *)(dst + i * stride + 16), d[i + 16]);
3156
434k
    _mm_storeu_si128((__m128i *)(dst + i * stride + 24), d[i + 24]);
3157
434k
  }
3158
54.3k
}
3159
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3160
3161
static void highbd_dr_prediction_z3_16x16_avx2(uint16_t *dst, ptrdiff_t stride,
3162
                                               const uint16_t *left,
3163
                                               int upsample_left, int dy,
3164
110k
                                               int bd) {
3165
110k
  __m256i dstvec[16], d[16];
3166
110k
  if (bd < 12) {
3167
93.4k
    highbd_dr_prediction_z1_16xN_internal_avx2(16, dstvec, left, upsample_left,
3168
93.4k
                                               dy);
3169
93.4k
  } else {
3170
16.9k
    highbd_dr_prediction_32bit_z1_16xN_internal_avx2(16, dstvec, left,
3171
16.9k
                                                     upsample_left, dy);
3172
16.9k
  }
3173
3174
110k
  highbd_transpose16x16_avx2(dstvec, d);
3175
3176
1.87M
  for (int i = 0; i < 16; i++) {
3177
1.76M
    _mm256_storeu_si256((__m256i *)(dst + i * stride), d[i]);
3178
1.76M
  }
3179
110k
}
3180
3181
static void highbd_dr_prediction_z3_32x32_avx2(uint16_t *dst, ptrdiff_t stride,
3182
                                               const uint16_t *left,
3183
                                               int upsample_left, int dy,
3184
98.4k
                                               int bd) {
3185
98.4k
  __m256i dstvec[64], d[16];
3186
98.4k
  if (bd < 12) {
3187
91.6k
    highbd_dr_prediction_z1_32xN_internal_avx2(32, dstvec, left, upsample_left,
3188
91.6k
                                               dy);
3189
91.6k
  } else {
3190
6.75k
    highbd_dr_prediction_32bit_z1_32xN_internal_avx2(32, dstvec, left,
3191
6.75k
                                                     upsample_left, dy);
3192
6.75k
  }
3193
98.4k
  highbd_transpose16x16_avx2(dstvec, d);
3194
1.67M
  for (int j = 0; j < 16; j++) {
3195
1.57M
    _mm256_storeu_si256((__m256i *)(dst + j * stride), d[j]);
3196
1.57M
  }
3197
98.4k
  highbd_transpose16x16_avx2(dstvec + 16, d);
3198
1.67M
  for (int j = 0; j < 16; j++) {
3199
1.57M
    _mm256_storeu_si256((__m256i *)(dst + j * stride + 16), d[j]);
3200
1.57M
  }
3201
98.4k
  highbd_transpose16x16_avx2(dstvec + 32, d);
3202
1.67M
  for (int j = 0; j < 16; j++) {
3203
1.57M
    _mm256_storeu_si256((__m256i *)(dst + (j + 16) * stride), d[j]);
3204
1.57M
  }
3205
98.4k
  highbd_transpose16x16_avx2(dstvec + 48, d);
3206
1.67M
  for (int j = 0; j < 16; j++) {
3207
1.57M
    _mm256_storeu_si256((__m256i *)(dst + (j + 16) * stride + 16), d[j]);
3208
1.57M
  }
3209
98.4k
}
3210
3211
static void highbd_dr_prediction_z3_64x64_avx2(uint16_t *dst, ptrdiff_t stride,
3212
                                               const uint16_t *left,
3213
                                               int upsample_left, int dy,
3214
29.6k
                                               int bd) {
3215
29.6k
  DECLARE_ALIGNED(16, uint16_t, dstT[64 * 64]);
3216
29.6k
  if (bd < 12) {
3217
26.2k
    highbd_dr_prediction_z1_64xN_avx2(64, dstT, 64, left, upsample_left, dy);
3218
26.2k
  } else {
3219
3.40k
    highbd_dr_prediction_32bit_z1_64xN_avx2(64, dstT, 64, left, upsample_left,
3220
3.40k
                                            dy);
3221
3.40k
  }
3222
29.6k
  highbd_transpose(dstT, 64, dst, stride, 64, 64);
3223
29.6k
}
3224
3225
static void highbd_dr_prediction_z3_16x32_avx2(uint16_t *dst, ptrdiff_t stride,
3226
                                               const uint16_t *left,
3227
                                               int upsample_left, int dy,
3228
29.4k
                                               int bd) {
3229
29.4k
  __m256i dstvec[32], d[32];
3230
29.4k
  if (bd < 12) {
3231
27.7k
    highbd_dr_prediction_z1_32xN_internal_avx2(16, dstvec, left, upsample_left,
3232
27.7k
                                               dy);
3233
27.7k
  } else {
3234
1.77k
    highbd_dr_prediction_32bit_z1_32xN_internal_avx2(16, dstvec, left,
3235
1.77k
                                                     upsample_left, dy);
3236
1.77k
  }
3237
147k
  for (int i = 0; i < 32; i += 8) {
3238
117k
    highbd_transpose8x16_16x8_avx2(dstvec + i, d + i);
3239
117k
  }
3240
  // store
3241
88.4k
  for (int j = 0; j < 32; j += 16) {
3242
530k
    for (int i = 0; i < 8; i++) {
3243
471k
      _mm_storeu_si128((__m128i *)(dst + (i + j) * stride),
3244
471k
                       _mm256_castsi256_si128(d[(i + j)]));
3245
471k
    }
3246
530k
    for (int i = 0; i < 8; i++) {
3247
471k
      _mm_storeu_si128((__m128i *)(dst + (i + j) * stride + 8),
3248
471k
                       _mm256_castsi256_si128(d[(i + j) + 8]));
3249
471k
    }
3250
530k
    for (int i = 8; i < 16; i++) {
3251
471k
      _mm256_storeu_si256(
3252
471k
          (__m256i *)(dst + (i + j) * stride),
3253
471k
          _mm256_inserti128_si256(
3254
471k
              d[(i + j)], _mm256_extracti128_si256(d[(i + j) - 8], 1), 0));
3255
471k
    }
3256
58.9k
  }
3257
29.4k
}
3258
3259
static void highbd_dr_prediction_z3_32x16_avx2(uint16_t *dst, ptrdiff_t stride,
3260
                                               const uint16_t *left,
3261
                                               int upsample_left, int dy,
3262
27.3k
                                               int bd) {
3263
27.3k
  __m256i dstvec[32], d[16];
3264
27.3k
  if (bd < 12) {
3265
24.7k
    highbd_dr_prediction_z1_16xN_internal_avx2(32, dstvec, left, upsample_left,
3266
24.7k
                                               dy);
3267
24.7k
  } else {
3268
2.57k
    highbd_dr_prediction_32bit_z1_16xN_internal_avx2(32, dstvec, left,
3269
2.57k
                                                     upsample_left, dy);
3270
2.57k
  }
3271
82.0k
  for (int i = 0; i < 32; i += 16) {
3272
54.7k
    highbd_transpose16x16_avx2((dstvec + i), d);
3273
930k
    for (int j = 0; j < 16; j++) {
3274
875k
      _mm256_storeu_si256((__m256i *)(dst + j * stride + i), d[j]);
3275
875k
    }
3276
54.7k
  }
3277
27.3k
}
3278
3279
static void highbd_dr_prediction_z3_32x64_avx2(uint16_t *dst, ptrdiff_t stride,
3280
                                               const uint16_t *left,
3281
                                               int upsample_left, int dy,
3282
2.20k
                                               int bd) {
3283
2.20k
  uint16_t dstT[64 * 32];
3284
2.20k
  if (bd < 12) {
3285
1.86k
    highbd_dr_prediction_z1_64xN_avx2(32, dstT, 64, left, upsample_left, dy);
3286
1.86k
  } else {
3287
334
    highbd_dr_prediction_32bit_z1_64xN_avx2(32, dstT, 64, left, upsample_left,
3288
334
                                            dy);
3289
334
  }
3290
2.20k
  highbd_transpose(dstT, 64, dst, stride, 32, 64);
3291
2.20k
}
3292
3293
static void highbd_dr_prediction_z3_64x32_avx2(uint16_t *dst, ptrdiff_t stride,
3294
                                               const uint16_t *left,
3295
                                               int upsample_left, int dy,
3296
3.13k
                                               int bd) {
3297
3.13k
  DECLARE_ALIGNED(16, uint16_t, dstT[32 * 64]);
3298
3.13k
  highbd_dr_prediction_z1_32xN_avx2(64, dstT, 32, left, upsample_left, dy, bd);
3299
3.13k
  highbd_transpose(dstT, 32, dst, stride, 64, 32);
3300
3.13k
  return;
3301
3.13k
}
3302
3303
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3304
static void highbd_dr_prediction_z3_16x64_avx2(uint16_t *dst, ptrdiff_t stride,
3305
                                               const uint16_t *left,
3306
                                               int upsample_left, int dy,
3307
6.13k
                                               int bd) {
3308
6.13k
  DECLARE_ALIGNED(16, uint16_t, dstT[64 * 16]);
3309
6.13k
  if (bd < 12) {
3310
5.51k
    highbd_dr_prediction_z1_64xN_avx2(16, dstT, 64, left, upsample_left, dy);
3311
5.51k
  } else {
3312
619
    highbd_dr_prediction_32bit_z1_64xN_avx2(16, dstT, 64, left, upsample_left,
3313
619
                                            dy);
3314
619
  }
3315
6.13k
  highbd_transpose(dstT, 64, dst, stride, 16, 64);
3316
6.13k
}
3317
3318
static void highbd_dr_prediction_z3_64x16_avx2(uint16_t *dst, ptrdiff_t stride,
3319
                                               const uint16_t *left,
3320
                                               int upsample_left, int dy,
3321
18.1k
                                               int bd) {
3322
18.1k
  __m256i dstvec[64], d[16];
3323
18.1k
  if (bd < 12) {
3324
17.1k
    highbd_dr_prediction_z1_16xN_internal_avx2(64, dstvec, left, upsample_left,
3325
17.1k
                                               dy);
3326
17.1k
  } else {
3327
1.02k
    highbd_dr_prediction_32bit_z1_16xN_internal_avx2(64, dstvec, left,
3328
1.02k
                                                     upsample_left, dy);
3329
1.02k
  }
3330
90.7k
  for (int i = 0; i < 64; i += 16) {
3331
72.5k
    highbd_transpose16x16_avx2((dstvec + i), d);
3332
1.23M
    for (int j = 0; j < 16; j++) {
3333
1.16M
      _mm256_storeu_si256((__m256i *)(dst + j * stride + i), d[j]);
3334
1.16M
    }
3335
72.5k
  }
3336
18.1k
}
3337
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3338
3339
void av1_highbd_dr_prediction_z3_avx2(uint16_t *dst, ptrdiff_t stride, int bw,
3340
                                      int bh, const uint16_t *above,
3341
                                      const uint16_t *left, int upsample_left,
3342
1.15M
                                      int dx, int dy, int bd) {
3343
1.15M
  (void)above;
3344
1.15M
  (void)dx;
3345
3346
1.15M
  assert(dx == 1);
3347
1.15M
  assert(dy > 0);
3348
1.15M
  if (bw == bh) {
3349
685k
    switch (bw) {
3350
234k
      case 4:
3351
234k
        highbd_dr_prediction_z3_4x4_avx2(dst, stride, left, upsample_left, dy,
3352
234k
                                         bd);
3353
234k
        break;
3354
212k
      case 8:
3355
212k
        highbd_dr_prediction_z3_8x8_avx2(dst, stride, left, upsample_left, dy,
3356
212k
                                         bd);
3357
212k
        break;
3358
110k
      case 16:
3359
110k
        highbd_dr_prediction_z3_16x16_avx2(dst, stride, left, upsample_left, dy,
3360
110k
                                           bd);
3361
110k
        break;
3362
98.4k
      case 32:
3363
98.4k
        highbd_dr_prediction_z3_32x32_avx2(dst, stride, left, upsample_left, dy,
3364
98.4k
                                           bd);
3365
98.4k
        break;
3366
29.6k
      case 64:
3367
29.6k
        highbd_dr_prediction_z3_64x64_avx2(dst, stride, left, upsample_left, dy,
3368
29.6k
                                           bd);
3369
29.6k
        break;
3370
685k
    }
3371
685k
  } else {
3372
473k
    if (bw < bh) {
3373
153k
      if (bw + bw == bh) {
3374
107k
        switch (bw) {
3375
32.2k
          case 4:
3376
32.2k
            highbd_dr_prediction_z3_4x8_avx2(dst, stride, left, upsample_left,
3377
32.2k
                                             dy, bd);
3378
32.2k
            break;
3379
43.4k
          case 8:
3380
43.4k
            highbd_dr_prediction_z3_8x16_avx2(dst, stride, left, upsample_left,
3381
43.4k
                                              dy, bd);
3382
43.4k
            break;
3383
29.4k
          case 16:
3384
29.4k
            highbd_dr_prediction_z3_16x32_avx2(dst, stride, left, upsample_left,
3385
29.4k
                                               dy, bd);
3386
29.4k
            break;
3387
2.20k
          case 32:
3388
2.20k
            highbd_dr_prediction_z3_32x64_avx2(dst, stride, left, upsample_left,
3389
2.20k
                                               dy, bd);
3390
2.20k
            break;
3391
107k
        }
3392
107k
      } else {
3393
46.2k
        switch (bw) {
3394
0
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3395
27.3k
          case 4:
3396
27.3k
            highbd_dr_prediction_z3_4x16_avx2(dst, stride, left, upsample_left,
3397
27.3k
                                              dy, bd);
3398
27.3k
            break;
3399
12.8k
          case 8:
3400
12.8k
            highbd_dr_prediction_z3_8x32_avx2(dst, stride, left, upsample_left,
3401
12.8k
                                              dy, bd);
3402
12.8k
            break;
3403
6.13k
          case 16:
3404
6.13k
            highbd_dr_prediction_z3_16x64_avx2(dst, stride, left, upsample_left,
3405
6.13k
                                               dy, bd);
3406
6.13k
            break;
3407
46.2k
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3408
46.2k
        }
3409
46.2k
      }
3410
320k
    } else {
3411
320k
      if (bh + bh == bw) {
3412
183k
        switch (bh) {
3413
66.4k
          case 4:
3414
66.4k
            highbd_dr_prediction_z3_8x4_avx2(dst, stride, left, upsample_left,
3415
66.4k
                                             dy, bd);
3416
66.4k
            break;
3417
86.9k
          case 8:
3418
86.9k
            highbd_dr_prediction_z3_16x8_avx2(dst, stride, left, upsample_left,
3419
86.9k
                                              dy, bd);
3420
86.9k
            break;
3421
27.3k
          case 16:
3422
27.3k
            highbd_dr_prediction_z3_32x16_avx2(dst, stride, left, upsample_left,
3423
27.3k
                                               dy, bd);
3424
27.3k
            break;
3425
3.13k
          case 32:
3426
3.13k
            highbd_dr_prediction_z3_64x32_avx2(dst, stride, left, upsample_left,
3427
3.13k
                                               dy, bd);
3428
3.13k
            break;
3429
183k
        }
3430
183k
      } else {
3431
136k
        switch (bh) {
3432
0
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3433
64.0k
          case 4:
3434
64.0k
            highbd_dr_prediction_z3_16x4_avx2(dst, stride, left, upsample_left,
3435
64.0k
                                              dy, bd);
3436
64.0k
            break;
3437
54.3k
          case 8:
3438
54.3k
            highbd_dr_prediction_z3_32x8_avx2(dst, stride, left, upsample_left,
3439
54.3k
                                              dy, bd);
3440
54.3k
            break;
3441
18.1k
          case 16:
3442
18.1k
            highbd_dr_prediction_z3_64x16_avx2(dst, stride, left, upsample_left,
3443
18.1k
                                               dy, bd);
3444
18.1k
            break;
3445
136k
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3446
136k
        }
3447
136k
      }
3448
320k
    }
3449
473k
  }
3450
1.15M
  return;
3451
1.15M
}
3452
#endif  // CONFIG_AV1_HIGHBITDEPTH
3453
3454
// Low bit depth functions
3455
static DECLARE_ALIGNED(32, uint8_t, BaseMask[33][32]) = {
3456
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3457
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
3458
  { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3459
    0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
3460
  { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3461
    0,    0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
3462
  { 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3463
    0,    0,    0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
3464
  { 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3465
    0,    0,    0,    0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
3466
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3467
    0,    0,    0,    0,    0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
3468
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3469
    0,    0,    0,    0,    0,    0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
3470
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3471
    0,    0,    0,    0,    0,    0,    0,    0, 0, 0, 0, 0, 0, 0, 0, 0 },
3472
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0,
3473
    0,    0,    0,    0,    0,    0,    0,    0,    0, 0, 0, 0, 0, 0, 0, 0 },
3474
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0,
3475
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 0, 0, 0, 0, 0, 0 },
3476
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,
3477
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
3478
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3479
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3480
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
3481
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3482
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3483
    0xff, 0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
3484
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3485
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3486
    0xff, 0xff, 0,    0,    0,    0,    0,    0,    0,    0,    0,
3487
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3488
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3489
    0xff, 0xff, 0xff, 0,    0,    0,    0,    0,    0,    0,    0,
3490
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3491
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3492
    0xff, 0xff, 0xff, 0xff, 0,    0,    0,    0,    0,    0,    0,
3493
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3494
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3495
    0xff, 0xff, 0xff, 0xff, 0xff, 0,    0,    0,    0,    0,    0,
3496
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3497
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3498
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,    0,    0,    0,    0,
3499
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3500
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3501
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,    0,    0,    0,
3502
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3503
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3504
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,    0,    0,
3505
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3506
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3507
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,    0,
3508
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3509
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3510
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,
3511
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3512
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3513
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3514
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0 },
3515
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3516
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3517
    0xff, 0,    0,    0,    0,    0,    0,    0,    0,    0 },
3518
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3519
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3520
    0xff, 0xff, 0,    0,    0,    0,    0,    0,    0,    0 },
3521
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3522
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3523
    0xff, 0xff, 0xff, 0,    0,    0,    0,    0,    0,    0 },
3524
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3525
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3526
    0xff, 0xff, 0xff, 0xff, 0,    0,    0,    0,    0,    0 },
3527
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3528
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3529
    0xff, 0xff, 0xff, 0xff, 0xff, 0,    0,    0,    0,    0 },
3530
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3531
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3532
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,    0,    0,    0 },
3533
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3534
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3535
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,    0,    0 },
3536
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3537
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3538
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,    0 },
3539
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3540
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3541
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0 },
3542
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3543
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3544
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
3545
};
3546
3547
/* clang-format on */
3548
static AOM_FORCE_INLINE void dr_prediction_z1_HxW_internal_avx2(
3549
    int H, int W, __m128i *dst, const uint8_t *above, int upsample_above,
3550
906k
    int dx) {
3551
906k
  const int frac_bits = 6 - upsample_above;
3552
906k
  const int max_base_x = ((W + H) - 1) << upsample_above;
3553
3554
906k
  assert(dx > 0);
3555
  // pre-filter above pixels
3556
  // store in temp buffers:
3557
  //   above[x] * 32 + 16
3558
  //   above[x+1] - above[x]
3559
  // final pixels will be calculated as:
3560
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
3561
906k
  __m256i a0, a1, a32, a16;
3562
906k
  __m256i diff, c3f;
3563
906k
  __m128i a_mbase_x;
3564
3565
906k
  a16 = _mm256_set1_epi16(16);
3566
906k
  a_mbase_x = _mm_set1_epi8((int8_t)above[max_base_x]);
3567
906k
  c3f = _mm256_set1_epi16(0x3f);
3568
3569
906k
  int x = dx;
3570
12.1M
  for (int r = 0; r < W; r++) {
3571
11.2M
    __m256i b, res, shift;
3572
11.2M
    __m128i res1, a0_128, a1_128;
3573
3574
11.2M
    int base = x >> frac_bits;
3575
11.2M
    int base_max_diff = (max_base_x - base) >> upsample_above;
3576
11.2M
    if (base_max_diff <= 0) {
3577
18.6k
      for (int i = r; i < W; ++i) {
3578
12.6k
        dst[i] = a_mbase_x;  // save 4 values
3579
12.6k
      }
3580
5.99k
      return;
3581
5.99k
    }
3582
11.2M
    if (base_max_diff > H) base_max_diff = H;
3583
11.2M
    a0_128 = _mm_loadu_si128((__m128i *)(above + base));
3584
11.2M
    a1_128 = _mm_loadu_si128((__m128i *)(above + base + 1));
3585
3586
11.2M
    if (upsample_above) {
3587
1.56M
      a0_128 = _mm_shuffle_epi8(a0_128, *(__m128i *)EvenOddMaskx[0]);
3588
1.56M
      a1_128 = _mm_srli_si128(a0_128, 8);
3589
3590
1.56M
      shift = _mm256_srli_epi16(
3591
1.56M
          _mm256_and_si256(
3592
1.56M
              _mm256_slli_epi16(_mm256_set1_epi16(x), upsample_above), c3f),
3593
1.56M
          1);
3594
9.64M
    } else {
3595
9.64M
      shift = _mm256_srli_epi16(_mm256_and_si256(_mm256_set1_epi16(x), c3f), 1);
3596
9.64M
    }
3597
11.2M
    a0 = _mm256_cvtepu8_epi16(a0_128);
3598
11.2M
    a1 = _mm256_cvtepu8_epi16(a1_128);
3599
3600
11.2M
    diff = _mm256_sub_epi16(a1, a0);   // a[x+1] - a[x]
3601
11.2M
    a32 = _mm256_slli_epi16(a0, 5);    // a[x] * 32
3602
11.2M
    a32 = _mm256_add_epi16(a32, a16);  // a[x] * 32 + 16
3603
3604
11.2M
    b = _mm256_mullo_epi16(diff, shift);
3605
11.2M
    res = _mm256_add_epi16(a32, b);
3606
11.2M
    res = _mm256_srli_epi16(res, 5);
3607
3608
11.2M
    res = _mm256_packus_epi16(
3609
11.2M
        res, _mm256_castsi128_si256(
3610
11.2M
                 _mm256_extracti128_si256(res, 1)));  // goto 8 bit
3611
11.2M
    res1 = _mm256_castsi256_si128(res);               // 16 8bit values
3612
3613
11.2M
    dst[r] =
3614
11.2M
        _mm_blendv_epi8(a_mbase_x, res1, *(__m128i *)BaseMask[base_max_diff]);
3615
11.2M
    x += dx;
3616
11.2M
  }
3617
906k
}
3618
3619
static void dr_prediction_z1_4xN_avx2(int N, uint8_t *dst, ptrdiff_t stride,
3620
                                      const uint8_t *above, int upsample_above,
3621
104k
                                      int dx) {
3622
104k
  __m128i dstvec[16];
3623
3624
104k
  dr_prediction_z1_HxW_internal_avx2(4, N, dstvec, above, upsample_above, dx);
3625
772k
  for (int i = 0; i < N; i++) {
3626
668k
    *(int *)(dst + stride * i) = _mm_cvtsi128_si32(dstvec[i]);
3627
668k
  }
3628
104k
}
3629
3630
static void dr_prediction_z1_8xN_avx2(int N, uint8_t *dst, ptrdiff_t stride,
3631
                                      const uint8_t *above, int upsample_above,
3632
142k
                                      int dx) {
3633
142k
  __m128i dstvec[32];
3634
3635
142k
  dr_prediction_z1_HxW_internal_avx2(8, N, dstvec, above, upsample_above, dx);
3636
1.70M
  for (int i = 0; i < N; i++) {
3637
1.56M
    _mm_storel_epi64((__m128i *)(dst + stride * i), dstvec[i]);
3638
1.56M
  }
3639
142k
}
3640
3641
static void dr_prediction_z1_16xN_avx2(int N, uint8_t *dst, ptrdiff_t stride,
3642
                                       const uint8_t *above, int upsample_above,
3643
115k
                                       int dx) {
3644
115k
  __m128i dstvec[64];
3645
3646
115k
  dr_prediction_z1_HxW_internal_avx2(16, N, dstvec, above, upsample_above, dx);
3647
1.72M
  for (int i = 0; i < N; i++) {
3648
1.61M
    _mm_storeu_si128((__m128i *)(dst + stride * i), dstvec[i]);
3649
1.61M
  }
3650
115k
}
3651
3652
static AOM_FORCE_INLINE void dr_prediction_z1_32xN_internal_avx2(
3653
170k
    int N, __m256i *dstvec, const uint8_t *above, int upsample_above, int dx) {
3654
  // here upsample_above is 0 by design of av1_use_intra_edge_upsample
3655
170k
  (void)upsample_above;
3656
170k
  const int frac_bits = 6;
3657
170k
  const int max_base_x = ((32 + N) - 1);
3658
3659
  // pre-filter above pixels
3660
  // store in temp buffers:
3661
  //   above[x] * 32 + 16
3662
  //   above[x+1] - above[x]
3663
  // final pixels will be calculated as:
3664
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
3665
170k
  __m256i a0, a1, a32, a16;
3666
170k
  __m256i a_mbase_x, diff, c3f;
3667
3668
170k
  a16 = _mm256_set1_epi16(16);
3669
170k
  a_mbase_x = _mm256_set1_epi8((int8_t)above[max_base_x]);
3670
170k
  c3f = _mm256_set1_epi16(0x3f);
3671
3672
170k
  int x = dx;
3673
4.80M
  for (int r = 0; r < N; r++) {
3674
4.63M
    __m256i b, res, res16[2];
3675
4.63M
    __m128i a0_128, a1_128;
3676
3677
4.63M
    int base = x >> frac_bits;
3678
4.63M
    int base_max_diff = (max_base_x - base);
3679
4.63M
    if (base_max_diff <= 0) {
3680
0
      for (int i = r; i < N; ++i) {
3681
0
        dstvec[i] = a_mbase_x;  // save 32 values
3682
0
      }
3683
0
      return;
3684
0
    }
3685
4.63M
    if (base_max_diff > 32) base_max_diff = 32;
3686
4.63M
    __m256i shift =
3687
4.63M
        _mm256_srli_epi16(_mm256_and_si256(_mm256_set1_epi16(x), c3f), 1);
3688
3689
13.8M
    for (int j = 0, jj = 0; j < 32; j += 16, jj++) {
3690
9.26M
      int mdiff = base_max_diff - j;
3691
9.26M
      if (mdiff <= 0) {
3692
498
        res16[jj] = a_mbase_x;
3693
9.26M
      } else {
3694
9.26M
        a0_128 = _mm_loadu_si128((__m128i *)(above + base + j));
3695
9.26M
        a1_128 = _mm_loadu_si128((__m128i *)(above + base + j + 1));
3696
9.26M
        a0 = _mm256_cvtepu8_epi16(a0_128);
3697
9.26M
        a1 = _mm256_cvtepu8_epi16(a1_128);
3698
3699
9.26M
        diff = _mm256_sub_epi16(a1, a0);   // a[x+1] - a[x]
3700
9.26M
        a32 = _mm256_slli_epi16(a0, 5);    // a[x] * 32
3701
9.26M
        a32 = _mm256_add_epi16(a32, a16);  // a[x] * 32 + 16
3702
9.26M
        b = _mm256_mullo_epi16(diff, shift);
3703
3704
9.26M
        res = _mm256_add_epi16(a32, b);
3705
9.26M
        res = _mm256_srli_epi16(res, 5);
3706
9.26M
        res16[jj] = _mm256_packus_epi16(
3707
9.26M
            res, _mm256_castsi128_si256(
3708
9.26M
                     _mm256_extracti128_si256(res, 1)));  // 16 8bit values
3709
9.26M
      }
3710
9.26M
    }
3711
4.63M
    res16[1] =
3712
4.63M
        _mm256_inserti128_si256(res16[0], _mm256_castsi256_si128(res16[1]),
3713
4.63M
                                1);  // 32 8bit values
3714
3715
4.63M
    dstvec[r] = _mm256_blendv_epi8(
3716
4.63M
        a_mbase_x, res16[1],
3717
4.63M
        *(__m256i *)BaseMask[base_max_diff]);  // 32 8bit values
3718
4.63M
    x += dx;
3719
4.63M
  }
3720
170k
}
3721
3722
static void dr_prediction_z1_32xN_avx2(int N, uint8_t *dst, ptrdiff_t stride,
3723
                                       const uint8_t *above, int upsample_above,
3724
67.9k
                                       int dx) {
3725
67.9k
  __m256i dstvec[64];
3726
67.9k
  dr_prediction_z1_32xN_internal_avx2(N, dstvec, above, upsample_above, dx);
3727
1.97M
  for (int i = 0; i < N; i++) {
3728
1.90M
    _mm256_storeu_si256((__m256i *)(dst + stride * i), dstvec[i]);
3729
1.90M
  }
3730
67.9k
}
3731
3732
static void dr_prediction_z1_64xN_avx2(int N, uint8_t *dst, ptrdiff_t stride,
3733
                                       const uint8_t *above, int upsample_above,
3734
42.0k
                                       int dx) {
3735
  // here upsample_above is 0 by design of av1_use_intra_edge_upsample
3736
42.0k
  (void)upsample_above;
3737
42.0k
  const int frac_bits = 6;
3738
42.0k
  const int max_base_x = ((64 + N) - 1);
3739
3740
  // pre-filter above pixels
3741
  // store in temp buffers:
3742
  //   above[x] * 32 + 16
3743
  //   above[x+1] - above[x]
3744
  // final pixels will be calculated as:
3745
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
3746
42.0k
  __m256i a0, a1, a32, a16;
3747
42.0k
  __m256i a_mbase_x, diff, c3f;
3748
42.0k
  __m128i max_base_x128, base_inc128, mask128;
3749
3750
42.0k
  a16 = _mm256_set1_epi16(16);
3751
42.0k
  a_mbase_x = _mm256_set1_epi8((int8_t)above[max_base_x]);
3752
42.0k
  max_base_x128 = _mm_set1_epi8(max_base_x);
3753
42.0k
  c3f = _mm256_set1_epi16(0x3f);
3754
3755
42.0k
  int x = dx;
3756
2.30M
  for (int r = 0; r < N; r++, dst += stride) {
3757
2.25M
    __m256i b, res;
3758
2.25M
    int base = x >> frac_bits;
3759
2.25M
    if (base >= max_base_x) {
3760
0
      for (int i = r; i < N; ++i) {
3761
0
        _mm256_storeu_si256((__m256i *)dst, a_mbase_x);  // save 32 values
3762
0
        _mm256_storeu_si256((__m256i *)(dst + 32), a_mbase_x);
3763
0
        dst += stride;
3764
0
      }
3765
0
      return;
3766
0
    }
3767
3768
2.25M
    __m256i shift =
3769
2.25M
        _mm256_srli_epi16(_mm256_and_si256(_mm256_set1_epi16(x), c3f), 1);
3770
3771
2.25M
    __m128i a0_128, a1_128, res128;
3772
11.2M
    for (int j = 0; j < 64; j += 16) {
3773
9.03M
      int mdif = max_base_x - (base + j);
3774
9.03M
      if (mdif <= 0) {
3775
2.93k
        _mm_storeu_si128((__m128i *)(dst + j),
3776
2.93k
                         _mm256_castsi256_si128(a_mbase_x));
3777
9.02M
      } else {
3778
9.02M
        a0_128 = _mm_loadu_si128((__m128i *)(above + base + j));
3779
9.02M
        a1_128 = _mm_loadu_si128((__m128i *)(above + base + 1 + j));
3780
9.02M
        a0 = _mm256_cvtepu8_epi16(a0_128);
3781
9.02M
        a1 = _mm256_cvtepu8_epi16(a1_128);
3782
3783
9.02M
        diff = _mm256_sub_epi16(a1, a0);   // a[x+1] - a[x]
3784
9.02M
        a32 = _mm256_slli_epi16(a0, 5);    // a[x] * 32
3785
9.02M
        a32 = _mm256_add_epi16(a32, a16);  // a[x] * 32 + 16
3786
9.02M
        b = _mm256_mullo_epi16(diff, shift);
3787
3788
9.02M
        res = _mm256_add_epi16(a32, b);
3789
9.02M
        res = _mm256_srli_epi16(res, 5);
3790
9.02M
        res = _mm256_packus_epi16(
3791
9.02M
            res, _mm256_castsi128_si256(
3792
9.02M
                     _mm256_extracti128_si256(res, 1)));  // 16 8bit values
3793
3794
9.02M
        base_inc128 =
3795
9.02M
            _mm_setr_epi8((int8_t)(base + j), (int8_t)(base + j + 1),
3796
9.02M
                          (int8_t)(base + j + 2), (int8_t)(base + j + 3),
3797
9.02M
                          (int8_t)(base + j + 4), (int8_t)(base + j + 5),
3798
9.02M
                          (int8_t)(base + j + 6), (int8_t)(base + j + 7),
3799
9.02M
                          (int8_t)(base + j + 8), (int8_t)(base + j + 9),
3800
9.02M
                          (int8_t)(base + j + 10), (int8_t)(base + j + 11),
3801
9.02M
                          (int8_t)(base + j + 12), (int8_t)(base + j + 13),
3802
9.02M
                          (int8_t)(base + j + 14), (int8_t)(base + j + 15));
3803
3804
9.02M
        mask128 = _mm_cmpgt_epi8(_mm_subs_epu8(max_base_x128, base_inc128),
3805
9.02M
                                 _mm_setzero_si128());
3806
9.02M
        res128 = _mm_blendv_epi8(_mm256_castsi256_si128(a_mbase_x),
3807
9.02M
                                 _mm256_castsi256_si128(res), mask128);
3808
9.02M
        _mm_storeu_si128((__m128i *)(dst + j), res128);
3809
9.02M
      }
3810
9.03M
    }
3811
2.25M
    x += dx;
3812
2.25M
  }
3813
42.0k
}
3814
3815
// Directional prediction, zone 1: 0 < angle < 90
3816
void av1_dr_prediction_z1_avx2(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
3817
                               const uint8_t *above, const uint8_t *left,
3818
440k
                               int upsample_above, int dx, int dy) {
3819
440k
  (void)left;
3820
440k
  (void)dy;
3821
440k
  switch (bw) {
3822
104k
    case 4:
3823
104k
      dr_prediction_z1_4xN_avx2(bh, dst, stride, above, upsample_above, dx);
3824
104k
      break;
3825
142k
    case 8:
3826
142k
      dr_prediction_z1_8xN_avx2(bh, dst, stride, above, upsample_above, dx);
3827
142k
      break;
3828
115k
    case 16:
3829
115k
      dr_prediction_z1_16xN_avx2(bh, dst, stride, above, upsample_above, dx);
3830
115k
      break;
3831
65.1k
    case 32:
3832
65.1k
      dr_prediction_z1_32xN_avx2(bh, dst, stride, above, upsample_above, dx);
3833
65.1k
      break;
3834
13.4k
    case 64:
3835
13.4k
      dr_prediction_z1_64xN_avx2(bh, dst, stride, above, upsample_above, dx);
3836
13.4k
      break;
3837
0
    default: break;
3838
440k
  }
3839
440k
  return;
3840
440k
}
3841
3842
static void dr_prediction_z2_Nx4_avx2(int N, uint8_t *dst, ptrdiff_t stride,
3843
                                      const uint8_t *above, const uint8_t *left,
3844
                                      int upsample_above, int upsample_left,
3845
270k
                                      int dx, int dy) {
3846
270k
  const int min_base_x = -(1 << upsample_above);
3847
270k
  const int min_base_y = -(1 << upsample_left);
3848
270k
  const int frac_bits_x = 6 - upsample_above;
3849
270k
  const int frac_bits_y = 6 - upsample_left;
3850
3851
270k
  assert(dx > 0);
3852
  // pre-filter above pixels
3853
  // store in temp buffers:
3854
  //   above[x] * 32 + 16
3855
  //   above[x+1] - above[x]
3856
  // final pixels will be calculated as:
3857
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
3858
270k
  __m128i a0_x, a1_x, a32, a16, diff;
3859
270k
  __m128i c3f, min_base_y128, c1234, dy128;
3860
3861
270k
  a16 = _mm_set1_epi16(16);
3862
270k
  c3f = _mm_set1_epi16(0x3f);
3863
270k
  min_base_y128 = _mm_set1_epi16(min_base_y);
3864
270k
  c1234 = _mm_setr_epi16(0, 1, 2, 3, 4, 0, 0, 0);
3865
270k
  dy128 = _mm_set1_epi16(dy);
3866
3867
1.88M
  for (int r = 0; r < N; r++) {
3868
1.61M
    __m128i b, res, shift, r6, ydx;
3869
1.61M
    __m128i resx, resy, resxy;
3870
1.61M
    __m128i a0_x128, a1_x128;
3871
1.61M
    int y = r + 1;
3872
1.61M
    int base_x = (-y * dx) >> frac_bits_x;
3873
1.61M
    int base_shift = 0;
3874
1.61M
    if (base_x < (min_base_x - 1)) {
3875
1.24M
      base_shift = (min_base_x - base_x - 1) >> upsample_above;
3876
1.24M
    }
3877
1.61M
    int base_min_diff =
3878
1.61M
        (min_base_x - base_x + upsample_above) >> upsample_above;
3879
1.61M
    if (base_min_diff > 4) {
3880
853k
      base_min_diff = 4;
3881
853k
    } else {
3882
762k
      if (base_min_diff < 0) base_min_diff = 0;
3883
762k
    }
3884
3885
1.61M
    if (base_shift > 3) {
3886
853k
      a0_x = _mm_setzero_si128();
3887
853k
      a1_x = _mm_setzero_si128();
3888
853k
      shift = _mm_setzero_si128();
3889
853k
    } else {
3890
762k
      a0_x128 = _mm_loadu_si128((__m128i *)(above + base_x + base_shift));
3891
762k
      ydx = _mm_set1_epi16(y * dx);
3892
762k
      r6 = _mm_slli_epi16(c1234, 6);
3893
3894
762k
      if (upsample_above) {
3895
244k
        a0_x128 =
3896
244k
            _mm_shuffle_epi8(a0_x128, *(__m128i *)EvenOddMaskx[base_shift]);
3897
244k
        a1_x128 = _mm_srli_si128(a0_x128, 8);
3898
3899
244k
        shift = _mm_srli_epi16(
3900
244k
            _mm_and_si128(
3901
244k
                _mm_slli_epi16(_mm_sub_epi16(r6, ydx), upsample_above), c3f),
3902
244k
            1);
3903
517k
      } else {
3904
517k
        a0_x128 = _mm_shuffle_epi8(a0_x128, *(__m128i *)LoadMaskx[base_shift]);
3905
517k
        a1_x128 = _mm_srli_si128(a0_x128, 1);
3906
3907
517k
        shift = _mm_srli_epi16(_mm_and_si128(_mm_sub_epi16(r6, ydx), c3f), 1);
3908
517k
      }
3909
762k
      a0_x = _mm_cvtepu8_epi16(a0_x128);
3910
762k
      a1_x = _mm_cvtepu8_epi16(a1_x128);
3911
762k
    }
3912
    // y calc
3913
1.61M
    __m128i a0_y, a1_y, shifty;
3914
1.61M
    if (base_x < min_base_x) {
3915
1.38M
      DECLARE_ALIGNED(32, int16_t, base_y_c[8]);
3916
1.38M
      __m128i y_c128, base_y_c128, mask128, c1234_;
3917
1.38M
      c1234_ = _mm_srli_si128(c1234, 2);
3918
1.38M
      r6 = _mm_set1_epi16(r << 6);
3919
1.38M
      y_c128 = _mm_sub_epi16(r6, _mm_mullo_epi16(c1234_, dy128));
3920
1.38M
      base_y_c128 = _mm_srai_epi16(y_c128, frac_bits_y);
3921
1.38M
      mask128 = _mm_cmpgt_epi16(min_base_y128, base_y_c128);
3922
1.38M
      base_y_c128 = _mm_andnot_si128(mask128, base_y_c128);
3923
1.38M
      _mm_store_si128((__m128i *)base_y_c, base_y_c128);
3924
3925
1.38M
      a0_y = _mm_setr_epi16(left[base_y_c[0]], left[base_y_c[1]],
3926
1.38M
                            left[base_y_c[2]], left[base_y_c[3]], 0, 0, 0, 0);
3927
1.38M
      base_y_c128 = _mm_add_epi16(base_y_c128, _mm_srli_epi16(a16, 4));
3928
1.38M
      _mm_store_si128((__m128i *)base_y_c, base_y_c128);
3929
1.38M
      a1_y = _mm_setr_epi16(left[base_y_c[0]], left[base_y_c[1]],
3930
1.38M
                            left[base_y_c[2]], left[base_y_c[3]], 0, 0, 0, 0);
3931
3932
1.38M
      if (upsample_left) {
3933
619k
        shifty = _mm_srli_epi16(
3934
619k
            _mm_and_si128(_mm_slli_epi16(y_c128, upsample_left), c3f), 1);
3935
763k
      } else {
3936
763k
        shifty = _mm_srli_epi16(_mm_and_si128(y_c128, c3f), 1);
3937
763k
      }
3938
1.38M
      a0_x = _mm_unpacklo_epi64(a0_x, a0_y);
3939
1.38M
      a1_x = _mm_unpacklo_epi64(a1_x, a1_y);
3940
1.38M
      shift = _mm_unpacklo_epi64(shift, shifty);
3941
1.38M
    }
3942
3943
1.61M
    diff = _mm_sub_epi16(a1_x, a0_x);  // a[x+1] - a[x]
3944
1.61M
    a32 = _mm_slli_epi16(a0_x, 5);     // a[x] * 32
3945
1.61M
    a32 = _mm_add_epi16(a32, a16);     // a[x] * 32 + 16
3946
3947
1.61M
    b = _mm_mullo_epi16(diff, shift);
3948
1.61M
    res = _mm_add_epi16(a32, b);
3949
1.61M
    res = _mm_srli_epi16(res, 5);
3950
3951
1.61M
    resx = _mm_packus_epi16(res, res);
3952
1.61M
    resy = _mm_srli_si128(resx, 4);
3953
3954
1.61M
    resxy = _mm_blendv_epi8(resx, resy, *(__m128i *)BaseMask[base_min_diff]);
3955
1.61M
    *(int *)(dst) = _mm_cvtsi128_si32(resxy);
3956
1.61M
    dst += stride;
3957
1.61M
  }
3958
270k
}
3959
3960
static void dr_prediction_z2_Nx8_avx2(int N, uint8_t *dst, ptrdiff_t stride,
3961
                                      const uint8_t *above, const uint8_t *left,
3962
                                      int upsample_above, int upsample_left,
3963
252k
                                      int dx, int dy) {
3964
252k
  const int min_base_x = -(1 << upsample_above);
3965
252k
  const int min_base_y = -(1 << upsample_left);
3966
252k
  const int frac_bits_x = 6 - upsample_above;
3967
252k
  const int frac_bits_y = 6 - upsample_left;
3968
3969
  // pre-filter above pixels
3970
  // store in temp buffers:
3971
  //   above[x] * 32 + 16
3972
  //   above[x+1] - above[x]
3973
  // final pixels will be calculated as:
3974
  //   (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
3975
252k
  __m256i diff, a32, a16;
3976
252k
  __m256i a0_x, a1_x;
3977
252k
  __m128i a0_x128, a1_x128, min_base_y128, c3f;
3978
252k
  __m128i c1234, dy128;
3979
3980
252k
  a16 = _mm256_set1_epi16(16);
3981
252k
  c3f = _mm_set1_epi16(0x3f);
3982
252k
  min_base_y128 = _mm_set1_epi16(min_base_y);
3983
252k
  dy128 = _mm_set1_epi16(dy);
3984
252k
  c1234 = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8);
3985
3986
2.74M
  for (int r = 0; r < N; r++) {
3987
2.49M
    __m256i b, res, shift;
3988
2.49M
    __m128i resx, resy, resxy, r6, ydx;
3989
3990
2.49M
    int y = r + 1;
3991
2.49M
    int base_x = (-y * dx) >> frac_bits_x;
3992
2.49M
    int base_shift = 0;
3993
2.49M
    if (base_x < (min_base_x - 1)) {
3994
1.94M
      base_shift = (min_base_x - base_x - 1) >> upsample_above;
3995
1.94M
    }
3996
2.49M
    int base_min_diff =
3997
2.49M
        (min_base_x - base_x + upsample_above) >> upsample_above;
3998
2.49M
    if (base_min_diff > 8) {
3999
1.19M
      base_min_diff = 8;
4000
1.29M
    } else {
4001
1.29M
      if (base_min_diff < 0) base_min_diff = 0;
4002
1.29M
    }
4003
4004
2.49M
    if (base_shift > 7) {
4005
1.19M
      a0_x = _mm256_setzero_si256();
4006
1.19M
      a1_x = _mm256_setzero_si256();
4007
1.19M
      shift = _mm256_setzero_si256();
4008
1.29M
    } else {
4009
1.29M
      a0_x128 = _mm_loadu_si128((__m128i *)(above + base_x + base_shift));
4010
1.29M
      ydx = _mm_set1_epi16(y * dx);
4011
1.29M
      r6 = _mm_slli_epi16(_mm_srli_si128(c1234, 2), 6);
4012
1.29M
      if (upsample_above) {
4013
371k
        a0_x128 =
4014
371k
            _mm_shuffle_epi8(a0_x128, *(__m128i *)EvenOddMaskx[base_shift]);
4015
371k
        a1_x128 = _mm_srli_si128(a0_x128, 8);
4016
4017
371k
        shift = _mm256_castsi128_si256(_mm_srli_epi16(
4018
371k
            _mm_and_si128(
4019
371k
                _mm_slli_epi16(_mm_sub_epi16(r6, ydx), upsample_above), c3f),
4020
371k
            1));
4021
928k
      } else {
4022
928k
        a1_x128 = _mm_srli_si128(a0_x128, 1);
4023
928k
        a0_x128 = _mm_shuffle_epi8(a0_x128, *(__m128i *)LoadMaskx[base_shift]);
4024
928k
        a1_x128 = _mm_shuffle_epi8(a1_x128, *(__m128i *)LoadMaskx[base_shift]);
4025
4026
928k
        shift = _mm256_castsi128_si256(
4027
928k
            _mm_srli_epi16(_mm_and_si128(_mm_sub_epi16(r6, ydx), c3f), 1));
4028
928k
      }
4029
1.29M
      a0_x = _mm256_castsi128_si256(_mm_cvtepu8_epi16(a0_x128));
4030
1.29M
      a1_x = _mm256_castsi128_si256(_mm_cvtepu8_epi16(a1_x128));
4031
1.29M
    }
4032
4033
    // y calc
4034
2.49M
    __m128i a0_y, a1_y, shifty;
4035
2.49M
    if (base_x < min_base_x) {
4036
2.13M
      DECLARE_ALIGNED(32, int16_t, base_y_c[16]);
4037
2.13M
      __m128i y_c128, base_y_c128, mask128;
4038
2.13M
      r6 = _mm_set1_epi16(r << 6);
4039
2.13M
      y_c128 = _mm_sub_epi16(r6, _mm_mullo_epi16(c1234, dy128));
4040
2.13M
      base_y_c128 = _mm_srai_epi16(y_c128, frac_bits_y);
4041
2.13M
      mask128 = _mm_cmpgt_epi16(min_base_y128, base_y_c128);
4042
2.13M
      base_y_c128 = _mm_andnot_si128(mask128, base_y_c128);
4043
2.13M
      _mm_store_si128((__m128i *)base_y_c, base_y_c128);
4044
4045
2.13M
      a0_y = _mm_setr_epi16(left[base_y_c[0]], left[base_y_c[1]],
4046
2.13M
                            left[base_y_c[2]], left[base_y_c[3]],
4047
2.13M
                            left[base_y_c[4]], left[base_y_c[5]],
4048
2.13M
                            left[base_y_c[6]], left[base_y_c[7]]);
4049
2.13M
      base_y_c128 = _mm_add_epi16(
4050
2.13M
          base_y_c128, _mm_srli_epi16(_mm256_castsi256_si128(a16), 4));
4051
2.13M
      _mm_store_si128((__m128i *)base_y_c, base_y_c128);
4052
4053
2.13M
      a1_y = _mm_setr_epi16(left[base_y_c[0]], left[base_y_c[1]],
4054
2.13M
                            left[base_y_c[2]], left[base_y_c[3]],
4055
2.13M
                            left[base_y_c[4]], left[base_y_c[5]],
4056
2.13M
                            left[base_y_c[6]], left[base_y_c[7]]);
4057
4058
2.13M
      if (upsample_left) {
4059
545k
        shifty = _mm_srli_epi16(
4060
545k
            _mm_and_si128(_mm_slli_epi16(y_c128, upsample_left), c3f), 1);
4061
1.58M
      } else {
4062
1.58M
        shifty = _mm_srli_epi16(_mm_and_si128(y_c128, c3f), 1);
4063
1.58M
      }
4064
4065
2.13M
      a0_x = _mm256_inserti128_si256(a0_x, a0_y, 1);
4066
2.13M
      a1_x = _mm256_inserti128_si256(a1_x, a1_y, 1);
4067
2.13M
      shift = _mm256_inserti128_si256(shift, shifty, 1);
4068
2.13M
    }
4069
4070
2.49M
    diff = _mm256_sub_epi16(a1_x, a0_x);  // a[x+1] - a[x]
4071
2.49M
    a32 = _mm256_slli_epi16(a0_x, 5);     // a[x] * 32
4072
2.49M
    a32 = _mm256_add_epi16(a32, a16);     // a[x] * 32 + 16
4073
4074
2.49M
    b = _mm256_mullo_epi16(diff, shift);
4075
2.49M
    res = _mm256_add_epi16(a32, b);
4076
2.49M
    res = _mm256_srli_epi16(res, 5);
4077
4078
2.49M
    resx = _mm_packus_epi16(_mm256_castsi256_si128(res),
4079
2.49M
                            _mm256_castsi256_si128(res));
4080
2.49M
    resy = _mm256_extracti128_si256(res, 1);
4081
2.49M
    resy = _mm_packus_epi16(resy, resy);
4082
4083
2.49M
    resxy = _mm_blendv_epi8(resx, resy, *(__m128i *)BaseMask[base_min_diff]);
4084
2.49M
    _mm_storel_epi64((__m128i *)(dst), resxy);
4085
2.49M
    dst += stride;
4086
2.49M
  }
4087
252k
}
4088
4089
static void dr_prediction_z2_HxW_avx2(int H, int W, uint8_t *dst,
4090
                                      ptrdiff_t stride, const uint8_t *above,
4091
                                      const uint8_t *left, int upsample_above,
4092
402k
                                      int upsample_left, int dx, int dy) {
4093
  // here upsample_above and upsample_left are 0 by design of
4094
  // av1_use_intra_edge_upsample
4095
402k
  const int min_base_x = -1;
4096
402k
  const int min_base_y = -1;
4097
402k
  (void)upsample_above;
4098
402k
  (void)upsample_left;
4099
402k
  const int frac_bits_x = 6;
4100
402k
  const int frac_bits_y = 6;
4101
4102
402k
  __m256i a0_x, a1_x, a0_y, a1_y, a32, a16, c1234, c0123;
4103
402k
  __m256i diff, min_base_y256, c3f, shifty, dy256, c1;
4104
402k
  __m128i a0_x128, a1_x128;
4105
4106
402k
  DECLARE_ALIGNED(32, int16_t, base_y_c[16]);
4107
402k
  a16 = _mm256_set1_epi16(16);
4108
402k
  c1 = _mm256_srli_epi16(a16, 4);
4109
402k
  min_base_y256 = _mm256_set1_epi16(min_base_y);
4110
402k
  c3f = _mm256_set1_epi16(0x3f);
4111
402k
  dy256 = _mm256_set1_epi16(dy);
4112
402k
  c0123 =
4113
402k
      _mm256_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
4114
402k
  c1234 = _mm256_add_epi16(c0123, c1);
4115
4116
7.83M
  for (int r = 0; r < H; r++) {
4117
7.43M
    __m256i b, res, shift, j256, r6, ydx;
4118
7.43M
    __m128i resx, resy;
4119
7.43M
    __m128i resxy;
4120
7.43M
    int y = r + 1;
4121
7.43M
    ydx = _mm256_set1_epi16((int16_t)(y * dx));
4122
4123
7.43M
    int base_x = (-y * dx) >> frac_bits_x;
4124
21.0M
    for (int j = 0; j < W; j += 16) {
4125
13.6M
      j256 = _mm256_set1_epi16(j);
4126
13.6M
      int base_shift = 0;
4127
13.6M
      if ((base_x + j) < (min_base_x - 1)) {
4128
9.95M
        base_shift = (min_base_x - (base_x + j) - 1);
4129
9.95M
      }
4130
13.6M
      int base_min_diff = (min_base_x - base_x - j);
4131
13.6M
      if (base_min_diff > 16) {
4132
7.08M
        base_min_diff = 16;
4133
7.08M
      } else {
4134
6.54M
        if (base_min_diff < 0) base_min_diff = 0;
4135
6.54M
      }
4136
4137
13.6M
      if (base_shift < 16) {
4138
6.55M
        a0_x128 = _mm_loadu_si128((__m128i *)(above + base_x + base_shift + j));
4139
6.55M
        a1_x128 =
4140
6.55M
            _mm_loadu_si128((__m128i *)(above + base_x + base_shift + 1 + j));
4141
6.55M
        a0_x128 = _mm_shuffle_epi8(a0_x128, *(__m128i *)LoadMaskx[base_shift]);
4142
6.55M
        a1_x128 = _mm_shuffle_epi8(a1_x128, *(__m128i *)LoadMaskx[base_shift]);
4143
4144
6.55M
        a0_x = _mm256_cvtepu8_epi16(a0_x128);
4145
6.55M
        a1_x = _mm256_cvtepu8_epi16(a1_x128);
4146
4147
6.55M
        r6 = _mm256_slli_epi16(_mm256_add_epi16(c0123, j256), 6);
4148
6.55M
        shift = _mm256_srli_epi16(
4149
6.55M
            _mm256_and_si256(_mm256_sub_epi16(r6, ydx), c3f), 1);
4150
4151
6.55M
        diff = _mm256_sub_epi16(a1_x, a0_x);  // a[x+1] - a[x]
4152
6.55M
        a32 = _mm256_slli_epi16(a0_x, 5);     // a[x] * 32
4153
6.55M
        a32 = _mm256_add_epi16(a32, a16);     // a[x] * 32 + 16
4154
4155
6.55M
        b = _mm256_mullo_epi16(diff, shift);
4156
6.55M
        res = _mm256_add_epi16(a32, b);
4157
6.55M
        res = _mm256_srli_epi16(res, 5);  // 16 16-bit values
4158
6.55M
        resx = _mm256_castsi256_si128(_mm256_packus_epi16(
4159
6.55M
            res, _mm256_castsi128_si256(_mm256_extracti128_si256(res, 1))));
4160
7.08M
      } else {
4161
7.08M
        resx = _mm_setzero_si128();
4162
7.08M
      }
4163
4164
      // y calc
4165
13.6M
      if (base_x < min_base_x) {
4166
12.6M
        __m256i c256, y_c256, base_y_c256, mask256, mul16;
4167
12.6M
        r6 = _mm256_set1_epi16(r << 6);
4168
12.6M
        c256 = _mm256_add_epi16(j256, c1234);
4169
12.6M
        mul16 = _mm256_min_epu16(_mm256_mullo_epi16(c256, dy256),
4170
12.6M
                                 _mm256_srli_epi16(min_base_y256, 1));
4171
12.6M
        y_c256 = _mm256_sub_epi16(r6, mul16);
4172
4173
12.6M
        base_y_c256 = _mm256_srai_epi16(y_c256, frac_bits_y);
4174
12.6M
        mask256 = _mm256_cmpgt_epi16(min_base_y256, base_y_c256);
4175
4176
12.6M
        base_y_c256 = _mm256_blendv_epi8(base_y_c256, min_base_y256, mask256);
4177
12.6M
        int16_t min_y = (int16_t)_mm_extract_epi16(
4178
12.6M
            _mm256_extracti128_si256(base_y_c256, 1), 7);
4179
12.6M
        int16_t max_y =
4180
12.6M
            (int16_t)_mm_extract_epi16(_mm256_castsi256_si128(base_y_c256), 0);
4181
12.6M
        int16_t offset_diff = max_y - min_y;
4182
4183
12.6M
        if (offset_diff < 16) {
4184
11.9M
          __m256i min_y256 = _mm256_set1_epi16(min_y);
4185
4186
11.9M
          __m256i base_y_offset = _mm256_sub_epi16(base_y_c256, min_y256);
4187
11.9M
          __m128i base_y_offset128 =
4188
11.9M
              _mm_packs_epi16(_mm256_extracti128_si256(base_y_offset, 0),
4189
11.9M
                              _mm256_extracti128_si256(base_y_offset, 1));
4190
4191
11.9M
          __m128i a0_y128 = _mm_maskload_epi32(
4192
11.9M
              (int *)(left + min_y), *(__m128i *)LoadMaskz2[offset_diff / 4]);
4193
11.9M
          __m128i a1_y128 =
4194
11.9M
              _mm_maskload_epi32((int *)(left + min_y + 1),
4195
11.9M
                                 *(__m128i *)LoadMaskz2[offset_diff / 4]);
4196
11.9M
          a0_y128 = _mm_shuffle_epi8(a0_y128, base_y_offset128);
4197
11.9M
          a1_y128 = _mm_shuffle_epi8(a1_y128, base_y_offset128);
4198
11.9M
          a0_y = _mm256_cvtepu8_epi16(a0_y128);
4199
11.9M
          a1_y = _mm256_cvtepu8_epi16(a1_y128);
4200
11.9M
        } else {
4201
767k
          base_y_c256 = _mm256_andnot_si256(mask256, base_y_c256);
4202
767k
          _mm256_store_si256((__m256i *)base_y_c, base_y_c256);
4203
4204
767k
          a0_y = _mm256_setr_epi16(
4205
767k
              left[base_y_c[0]], left[base_y_c[1]], left[base_y_c[2]],
4206
767k
              left[base_y_c[3]], left[base_y_c[4]], left[base_y_c[5]],
4207
767k
              left[base_y_c[6]], left[base_y_c[7]], left[base_y_c[8]],
4208
767k
              left[base_y_c[9]], left[base_y_c[10]], left[base_y_c[11]],
4209
767k
              left[base_y_c[12]], left[base_y_c[13]], left[base_y_c[14]],
4210
767k
              left[base_y_c[15]]);
4211
767k
          base_y_c256 = _mm256_add_epi16(base_y_c256, c1);
4212
767k
          _mm256_store_si256((__m256i *)base_y_c, base_y_c256);
4213
4214
767k
          a1_y = _mm256_setr_epi16(
4215
767k
              left[base_y_c[0]], left[base_y_c[1]], left[base_y_c[2]],
4216
767k
              left[base_y_c[3]], left[base_y_c[4]], left[base_y_c[5]],
4217
767k
              left[base_y_c[6]], left[base_y_c[7]], left[base_y_c[8]],
4218
767k
              left[base_y_c[9]], left[base_y_c[10]], left[base_y_c[11]],
4219
767k
              left[base_y_c[12]], left[base_y_c[13]], left[base_y_c[14]],
4220
767k
              left[base_y_c[15]]);
4221
767k
        }
4222
12.6M
        shifty = _mm256_srli_epi16(_mm256_and_si256(y_c256, c3f), 1);
4223
4224
12.6M
        diff = _mm256_sub_epi16(a1_y, a0_y);  // a[x+1] - a[x]
4225
12.6M
        a32 = _mm256_slli_epi16(a0_y, 5);     // a[x] * 32
4226
12.6M
        a32 = _mm256_add_epi16(a32, a16);     // a[x] * 32 + 16
4227
4228
12.6M
        b = _mm256_mullo_epi16(diff, shifty);
4229
12.6M
        res = _mm256_add_epi16(a32, b);
4230
12.6M
        res = _mm256_srli_epi16(res, 5);  // 16 16-bit values
4231
12.6M
        resy = _mm256_castsi256_si128(_mm256_packus_epi16(
4232
12.6M
            res, _mm256_castsi128_si256(_mm256_extracti128_si256(res, 1))));
4233
12.6M
      } else {
4234
937k
        resy = _mm_setzero_si128();
4235
937k
      }
4236
13.6M
      resxy = _mm_blendv_epi8(resx, resy, *(__m128i *)BaseMask[base_min_diff]);
4237
13.6M
      _mm_storeu_si128((__m128i *)(dst + j), resxy);
4238
13.6M
    }  // for j
4239
7.43M
    dst += stride;
4240
7.43M
  }
4241
402k
}
4242
4243
// Directional prediction, zone 2: 90 < angle < 180
4244
void av1_dr_prediction_z2_avx2(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
4245
                               const uint8_t *above, const uint8_t *left,
4246
                               int upsample_above, int upsample_left, int dx,
4247
925k
                               int dy) {
4248
925k
  assert(dx > 0);
4249
925k
  assert(dy > 0);
4250
925k
  switch (bw) {
4251
270k
    case 4:
4252
270k
      dr_prediction_z2_Nx4_avx2(bh, dst, stride, above, left, upsample_above,
4253
270k
                                upsample_left, dx, dy);
4254
270k
      break;
4255
252k
    case 8:
4256
252k
      dr_prediction_z2_Nx8_avx2(bh, dst, stride, above, left, upsample_above,
4257
252k
                                upsample_left, dx, dy);
4258
252k
      break;
4259
402k
    default:
4260
402k
      dr_prediction_z2_HxW_avx2(bh, bw, dst, stride, above, left,
4261
402k
                                upsample_above, upsample_left, dx, dy);
4262
402k
      break;
4263
925k
  }
4264
925k
  return;
4265
925k
}
4266
4267
// z3 functions
4268
176k
static inline void transpose16x32_avx2(__m256i *x, __m256i *d) {
4269
176k
  __m256i w0, w1, w2, w3, w4, w5, w6, w7, w8, w9;
4270
176k
  __m256i w10, w11, w12, w13, w14, w15;
4271
4272
176k
  w0 = _mm256_unpacklo_epi8(x[0], x[1]);
4273
176k
  w1 = _mm256_unpacklo_epi8(x[2], x[3]);
4274
176k
  w2 = _mm256_unpacklo_epi8(x[4], x[5]);
4275
176k
  w3 = _mm256_unpacklo_epi8(x[6], x[7]);
4276
4277
176k
  w8 = _mm256_unpacklo_epi8(x[8], x[9]);
4278
176k
  w9 = _mm256_unpacklo_epi8(x[10], x[11]);
4279
176k
  w10 = _mm256_unpacklo_epi8(x[12], x[13]);
4280
176k
  w11 = _mm256_unpacklo_epi8(x[14], x[15]);
4281
4282
176k
  w4 = _mm256_unpacklo_epi16(w0, w1);
4283
176k
  w5 = _mm256_unpacklo_epi16(w2, w3);
4284
176k
  w12 = _mm256_unpacklo_epi16(w8, w9);
4285
176k
  w13 = _mm256_unpacklo_epi16(w10, w11);
4286
4287
176k
  w6 = _mm256_unpacklo_epi32(w4, w5);
4288
176k
  w7 = _mm256_unpackhi_epi32(w4, w5);
4289
176k
  w14 = _mm256_unpacklo_epi32(w12, w13);
4290
176k
  w15 = _mm256_unpackhi_epi32(w12, w13);
4291
4292
  // Store first 4-line result
4293
176k
  d[0] = _mm256_unpacklo_epi64(w6, w14);
4294
176k
  d[1] = _mm256_unpackhi_epi64(w6, w14);
4295
176k
  d[2] = _mm256_unpacklo_epi64(w7, w15);
4296
176k
  d[3] = _mm256_unpackhi_epi64(w7, w15);
4297
4298
176k
  w4 = _mm256_unpackhi_epi16(w0, w1);
4299
176k
  w5 = _mm256_unpackhi_epi16(w2, w3);
4300
176k
  w12 = _mm256_unpackhi_epi16(w8, w9);
4301
176k
  w13 = _mm256_unpackhi_epi16(w10, w11);
4302
4303
176k
  w6 = _mm256_unpacklo_epi32(w4, w5);
4304
176k
  w7 = _mm256_unpackhi_epi32(w4, w5);
4305
176k
  w14 = _mm256_unpacklo_epi32(w12, w13);
4306
176k
  w15 = _mm256_unpackhi_epi32(w12, w13);
4307
4308
  // Store second 4-line result
4309
176k
  d[4] = _mm256_unpacklo_epi64(w6, w14);
4310
176k
  d[5] = _mm256_unpackhi_epi64(w6, w14);
4311
176k
  d[6] = _mm256_unpacklo_epi64(w7, w15);
4312
176k
  d[7] = _mm256_unpackhi_epi64(w7, w15);
4313
4314
  // upper half
4315
176k
  w0 = _mm256_unpackhi_epi8(x[0], x[1]);
4316
176k
  w1 = _mm256_unpackhi_epi8(x[2], x[3]);
4317
176k
  w2 = _mm256_unpackhi_epi8(x[4], x[5]);
4318
176k
  w3 = _mm256_unpackhi_epi8(x[6], x[7]);
4319
4320
176k
  w8 = _mm256_unpackhi_epi8(x[8], x[9]);
4321
176k
  w9 = _mm256_unpackhi_epi8(x[10], x[11]);
4322
176k
  w10 = _mm256_unpackhi_epi8(x[12], x[13]);
4323
176k
  w11 = _mm256_unpackhi_epi8(x[14], x[15]);
4324
4325
176k
  w4 = _mm256_unpacklo_epi16(w0, w1);
4326
176k
  w5 = _mm256_unpacklo_epi16(w2, w3);
4327
176k
  w12 = _mm256_unpacklo_epi16(w8, w9);
4328
176k
  w13 = _mm256_unpacklo_epi16(w10, w11);
4329
4330
176k
  w6 = _mm256_unpacklo_epi32(w4, w5);
4331
176k
  w7 = _mm256_unpackhi_epi32(w4, w5);
4332
176k
  w14 = _mm256_unpacklo_epi32(w12, w13);
4333
176k
  w15 = _mm256_unpackhi_epi32(w12, w13);
4334
4335
  // Store first 4-line result
4336
176k
  d[8] = _mm256_unpacklo_epi64(w6, w14);
4337
176k
  d[9] = _mm256_unpackhi_epi64(w6, w14);
4338
176k
  d[10] = _mm256_unpacklo_epi64(w7, w15);
4339
176k
  d[11] = _mm256_unpackhi_epi64(w7, w15);
4340
4341
176k
  w4 = _mm256_unpackhi_epi16(w0, w1);
4342
176k
  w5 = _mm256_unpackhi_epi16(w2, w3);
4343
176k
  w12 = _mm256_unpackhi_epi16(w8, w9);
4344
176k
  w13 = _mm256_unpackhi_epi16(w10, w11);
4345
4346
176k
  w6 = _mm256_unpacklo_epi32(w4, w5);
4347
176k
  w7 = _mm256_unpackhi_epi32(w4, w5);
4348
176k
  w14 = _mm256_unpacklo_epi32(w12, w13);
4349
176k
  w15 = _mm256_unpackhi_epi32(w12, w13);
4350
4351
  // Store second 4-line result
4352
176k
  d[12] = _mm256_unpacklo_epi64(w6, w14);
4353
176k
  d[13] = _mm256_unpackhi_epi64(w6, w14);
4354
176k
  d[14] = _mm256_unpacklo_epi64(w7, w15);
4355
176k
  d[15] = _mm256_unpackhi_epi64(w7, w15);
4356
176k
}
4357
4358
static void dr_prediction_z3_4x4_avx2(uint8_t *dst, ptrdiff_t stride,
4359
                                      const uint8_t *left, int upsample_left,
4360
93.7k
                                      int dy) {
4361
93.7k
  __m128i dstvec[4], d[4];
4362
4363
93.7k
  dr_prediction_z1_HxW_internal_avx2(4, 4, dstvec, left, upsample_left, dy);
4364
93.7k
  transpose4x8_8x4_low_sse2(&dstvec[0], &dstvec[1], &dstvec[2], &dstvec[3],
4365
93.7k
                            &d[0], &d[1], &d[2], &d[3]);
4366
4367
93.7k
  *(int *)(dst + stride * 0) = _mm_cvtsi128_si32(d[0]);
4368
93.7k
  *(int *)(dst + stride * 1) = _mm_cvtsi128_si32(d[1]);
4369
93.7k
  *(int *)(dst + stride * 2) = _mm_cvtsi128_si32(d[2]);
4370
93.7k
  *(int *)(dst + stride * 3) = _mm_cvtsi128_si32(d[3]);
4371
93.7k
  return;
4372
93.7k
}
4373
4374
static void dr_prediction_z3_8x8_avx2(uint8_t *dst, ptrdiff_t stride,
4375
                                      const uint8_t *left, int upsample_left,
4376
91.0k
                                      int dy) {
4377
91.0k
  __m128i dstvec[8], d[8];
4378
4379
91.0k
  dr_prediction_z1_HxW_internal_avx2(8, 8, dstvec, left, upsample_left, dy);
4380
91.0k
  transpose8x8_sse2(&dstvec[0], &dstvec[1], &dstvec[2], &dstvec[3], &dstvec[4],
4381
91.0k
                    &dstvec[5], &dstvec[6], &dstvec[7], &d[0], &d[1], &d[2],
4382
91.0k
                    &d[3]);
4383
4384
91.0k
  _mm_storel_epi64((__m128i *)(dst + 0 * stride), d[0]);
4385
91.0k
  _mm_storel_epi64((__m128i *)(dst + 1 * stride), _mm_srli_si128(d[0], 8));
4386
91.0k
  _mm_storel_epi64((__m128i *)(dst + 2 * stride), d[1]);
4387
91.0k
  _mm_storel_epi64((__m128i *)(dst + 3 * stride), _mm_srli_si128(d[1], 8));
4388
91.0k
  _mm_storel_epi64((__m128i *)(dst + 4 * stride), d[2]);
4389
91.0k
  _mm_storel_epi64((__m128i *)(dst + 5 * stride), _mm_srli_si128(d[2], 8));
4390
91.0k
  _mm_storel_epi64((__m128i *)(dst + 6 * stride), d[3]);
4391
91.0k
  _mm_storel_epi64((__m128i *)(dst + 7 * stride), _mm_srli_si128(d[3], 8));
4392
91.0k
}
4393
4394
static void dr_prediction_z3_4x8_avx2(uint8_t *dst, ptrdiff_t stride,
4395
                                      const uint8_t *left, int upsample_left,
4396
24.6k
                                      int dy) {
4397
24.6k
  __m128i dstvec[4], d[8];
4398
4399
24.6k
  dr_prediction_z1_HxW_internal_avx2(8, 4, dstvec, left, upsample_left, dy);
4400
24.6k
  transpose4x8_8x4_sse2(&dstvec[0], &dstvec[1], &dstvec[2], &dstvec[3], &d[0],
4401
24.6k
                        &d[1], &d[2], &d[3], &d[4], &d[5], &d[6], &d[7]);
4402
221k
  for (int i = 0; i < 8; i++) {
4403
197k
    *(int *)(dst + stride * i) = _mm_cvtsi128_si32(d[i]);
4404
197k
  }
4405
24.6k
}
4406
4407
static void dr_prediction_z3_8x4_avx2(uint8_t *dst, ptrdiff_t stride,
4408
                                      const uint8_t *left, int upsample_left,
4409
38.4k
                                      int dy) {
4410
38.4k
  __m128i dstvec[8], d[4];
4411
4412
38.4k
  dr_prediction_z1_HxW_internal_avx2(4, 8, dstvec, left, upsample_left, dy);
4413
38.4k
  transpose8x8_low_sse2(&dstvec[0], &dstvec[1], &dstvec[2], &dstvec[3],
4414
38.4k
                        &dstvec[4], &dstvec[5], &dstvec[6], &dstvec[7], &d[0],
4415
38.4k
                        &d[1], &d[2], &d[3]);
4416
38.4k
  _mm_storel_epi64((__m128i *)(dst + 0 * stride), d[0]);
4417
38.4k
  _mm_storel_epi64((__m128i *)(dst + 1 * stride), d[1]);
4418
38.4k
  _mm_storel_epi64((__m128i *)(dst + 2 * stride), d[2]);
4419
38.4k
  _mm_storel_epi64((__m128i *)(dst + 3 * stride), d[3]);
4420
38.4k
}
4421
4422
static void dr_prediction_z3_8x16_avx2(uint8_t *dst, ptrdiff_t stride,
4423
                                       const uint8_t *left, int upsample_left,
4424
23.8k
                                       int dy) {
4425
23.8k
  __m128i dstvec[8], d[8];
4426
4427
23.8k
  dr_prediction_z1_HxW_internal_avx2(16, 8, dstvec, left, upsample_left, dy);
4428
23.8k
  transpose8x16_16x8_sse2(dstvec, dstvec + 1, dstvec + 2, dstvec + 3,
4429
23.8k
                          dstvec + 4, dstvec + 5, dstvec + 6, dstvec + 7, d,
4430
23.8k
                          d + 1, d + 2, d + 3, d + 4, d + 5, d + 6, d + 7);
4431
214k
  for (int i = 0; i < 8; i++) {
4432
190k
    _mm_storel_epi64((__m128i *)(dst + i * stride), d[i]);
4433
190k
    _mm_storel_epi64((__m128i *)(dst + (i + 8) * stride),
4434
190k
                     _mm_srli_si128(d[i], 8));
4435
190k
  }
4436
23.8k
}
4437
4438
static void dr_prediction_z3_16x8_avx2(uint8_t *dst, ptrdiff_t stride,
4439
                                       const uint8_t *left, int upsample_left,
4440
47.5k
                                       int dy) {
4441
47.5k
  __m128i dstvec[16], d[16];
4442
4443
47.5k
  dr_prediction_z1_HxW_internal_avx2(8, 16, dstvec, left, upsample_left, dy);
4444
47.5k
  transpose16x8_8x16_sse2(
4445
47.5k
      &dstvec[0], &dstvec[1], &dstvec[2], &dstvec[3], &dstvec[4], &dstvec[5],
4446
47.5k
      &dstvec[6], &dstvec[7], &dstvec[8], &dstvec[9], &dstvec[10], &dstvec[11],
4447
47.5k
      &dstvec[12], &dstvec[13], &dstvec[14], &dstvec[15], &d[0], &d[1], &d[2],
4448
47.5k
      &d[3], &d[4], &d[5], &d[6], &d[7]);
4449
4450
428k
  for (int i = 0; i < 8; i++) {
4451
380k
    _mm_storeu_si128((__m128i *)(dst + i * stride), d[i]);
4452
380k
  }
4453
47.5k
}
4454
4455
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
4456
static void dr_prediction_z3_4x16_avx2(uint8_t *dst, ptrdiff_t stride,
4457
                                       const uint8_t *left, int upsample_left,
4458
20.4k
                                       int dy) {
4459
20.4k
  __m128i dstvec[4], d[16];
4460
4461
20.4k
  dr_prediction_z1_HxW_internal_avx2(16, 4, dstvec, left, upsample_left, dy);
4462
20.4k
  transpose4x16_sse2(dstvec, d);
4463
346k
  for (int i = 0; i < 16; i++) {
4464
326k
    *(int *)(dst + stride * i) = _mm_cvtsi128_si32(d[i]);
4465
326k
  }
4466
20.4k
}
4467
4468
static void dr_prediction_z3_16x4_avx2(uint8_t *dst, ptrdiff_t stride,
4469
                                       const uint8_t *left, int upsample_left,
4470
55.1k
                                       int dy) {
4471
55.1k
  __m128i dstvec[16], d[8];
4472
4473
55.1k
  dr_prediction_z1_HxW_internal_avx2(4, 16, dstvec, left, upsample_left, dy);
4474
275k
  for (int i = 4; i < 8; i++) {
4475
220k
    d[i] = _mm_setzero_si128();
4476
220k
  }
4477
55.1k
  transpose16x8_8x16_sse2(
4478
55.1k
      &dstvec[0], &dstvec[1], &dstvec[2], &dstvec[3], &dstvec[4], &dstvec[5],
4479
55.1k
      &dstvec[6], &dstvec[7], &dstvec[8], &dstvec[9], &dstvec[10], &dstvec[11],
4480
55.1k
      &dstvec[12], &dstvec[13], &dstvec[14], &dstvec[15], &d[0], &d[1], &d[2],
4481
55.1k
      &d[3], &d[4], &d[5], &d[6], &d[7]);
4482
4483
275k
  for (int i = 0; i < 4; i++) {
4484
220k
    _mm_storeu_si128((__m128i *)(dst + i * stride), d[i]);
4485
220k
  }
4486
55.1k
}
4487
4488
static void dr_prediction_z3_8x32_avx2(uint8_t *dst, ptrdiff_t stride,
4489
                                       const uint8_t *left, int upsample_left,
4490
11.7k
                                       int dy) {
4491
11.7k
  __m256i dstvec[16], d[16];
4492
4493
11.7k
  dr_prediction_z1_32xN_internal_avx2(8, dstvec, left, upsample_left, dy);
4494
106k
  for (int i = 8; i < 16; i++) {
4495
94.2k
    dstvec[i] = _mm256_setzero_si256();
4496
94.2k
  }
4497
11.7k
  transpose16x32_avx2(dstvec, d);
4498
4499
200k
  for (int i = 0; i < 16; i++) {
4500
188k
    _mm_storel_epi64((__m128i *)(dst + i * stride),
4501
188k
                     _mm256_castsi256_si128(d[i]));
4502
188k
  }
4503
200k
  for (int i = 0; i < 16; i++) {
4504
188k
    _mm_storel_epi64((__m128i *)(dst + (i + 16) * stride),
4505
188k
                     _mm256_extracti128_si256(d[i], 1));
4506
188k
  }
4507
11.7k
}
4508
4509
static void dr_prediction_z3_32x8_avx2(uint8_t *dst, ptrdiff_t stride,
4510
                                       const uint8_t *left, int upsample_left,
4511
42.8k
                                       int dy) {
4512
42.8k
  __m128i dstvec[32], d[16];
4513
4514
42.8k
  dr_prediction_z1_HxW_internal_avx2(8, 32, dstvec, left, upsample_left, dy);
4515
4516
42.8k
  transpose16x8_8x16_sse2(
4517
42.8k
      &dstvec[0], &dstvec[1], &dstvec[2], &dstvec[3], &dstvec[4], &dstvec[5],
4518
42.8k
      &dstvec[6], &dstvec[7], &dstvec[8], &dstvec[9], &dstvec[10], &dstvec[11],
4519
42.8k
      &dstvec[12], &dstvec[13], &dstvec[14], &dstvec[15], &d[0], &d[1], &d[2],
4520
42.8k
      &d[3], &d[4], &d[5], &d[6], &d[7]);
4521
42.8k
  transpose16x8_8x16_sse2(
4522
42.8k
      &dstvec[0 + 16], &dstvec[1 + 16], &dstvec[2 + 16], &dstvec[3 + 16],
4523
42.8k
      &dstvec[4 + 16], &dstvec[5 + 16], &dstvec[6 + 16], &dstvec[7 + 16],
4524
42.8k
      &dstvec[8 + 16], &dstvec[9 + 16], &dstvec[10 + 16], &dstvec[11 + 16],
4525
42.8k
      &dstvec[12 + 16], &dstvec[13 + 16], &dstvec[14 + 16], &dstvec[15 + 16],
4526
42.8k
      &d[0 + 8], &d[1 + 8], &d[2 + 8], &d[3 + 8], &d[4 + 8], &d[5 + 8],
4527
42.8k
      &d[6 + 8], &d[7 + 8]);
4528
4529
385k
  for (int i = 0; i < 8; i++) {
4530
343k
    _mm_storeu_si128((__m128i *)(dst + i * stride), d[i]);
4531
343k
    _mm_storeu_si128((__m128i *)(dst + i * stride + 16), d[i + 8]);
4532
343k
  }
4533
42.8k
}
4534
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
4535
4536
static void dr_prediction_z3_16x16_avx2(uint8_t *dst, ptrdiff_t stride,
4537
                                        const uint8_t *left, int upsample_left,
4538
77.9k
                                        int dy) {
4539
77.9k
  __m128i dstvec[16], d[16];
4540
4541
77.9k
  dr_prediction_z1_HxW_internal_avx2(16, 16, dstvec, left, upsample_left, dy);
4542
77.9k
  transpose16x16_sse2(dstvec, d);
4543
4544
1.32M
  for (int i = 0; i < 16; i++) {
4545
1.24M
    _mm_storeu_si128((__m128i *)(dst + i * stride), d[i]);
4546
1.24M
  }
4547
77.9k
}
4548
4549
static void dr_prediction_z3_32x32_avx2(uint8_t *dst, ptrdiff_t stride,
4550
                                        const uint8_t *left, int upsample_left,
4551
73.4k
                                        int dy) {
4552
73.4k
  __m256i dstvec[32], d[32];
4553
4554
73.4k
  dr_prediction_z1_32xN_internal_avx2(32, dstvec, left, upsample_left, dy);
4555
73.4k
  transpose16x32_avx2(dstvec, d);
4556
73.4k
  transpose16x32_avx2(dstvec + 16, d + 16);
4557
1.24M
  for (int j = 0; j < 16; j++) {
4558
1.17M
    _mm_storeu_si128((__m128i *)(dst + j * stride),
4559
1.17M
                     _mm256_castsi256_si128(d[j]));
4560
1.17M
    _mm_storeu_si128((__m128i *)(dst + j * stride + 16),
4561
1.17M
                     _mm256_castsi256_si128(d[j + 16]));
4562
1.17M
  }
4563
1.24M
  for (int j = 0; j < 16; j++) {
4564
1.17M
    _mm_storeu_si128((__m128i *)(dst + (j + 16) * stride),
4565
1.17M
                     _mm256_extracti128_si256(d[j], 1));
4566
1.17M
    _mm_storeu_si128((__m128i *)(dst + (j + 16) * stride + 16),
4567
1.17M
                     _mm256_extracti128_si256(d[j + 16], 1));
4568
1.17M
  }
4569
73.4k
}
4570
4571
static void dr_prediction_z3_64x64_avx2(uint8_t *dst, ptrdiff_t stride,
4572
                                        const uint8_t *left, int upsample_left,
4573
23.4k
                                        int dy) {
4574
23.4k
  DECLARE_ALIGNED(16, uint8_t, dstT[64 * 64]);
4575
23.4k
  dr_prediction_z1_64xN_avx2(64, dstT, 64, left, upsample_left, dy);
4576
23.4k
  transpose(dstT, 64, dst, stride, 64, 64);
4577
23.4k
}
4578
4579
static void dr_prediction_z3_16x32_avx2(uint8_t *dst, ptrdiff_t stride,
4580
                                        const uint8_t *left, int upsample_left,
4581
17.7k
                                        int dy) {
4582
17.7k
  __m256i dstvec[16], d[16];
4583
4584
17.7k
  dr_prediction_z1_32xN_internal_avx2(16, dstvec, left, upsample_left, dy);
4585
17.7k
  transpose16x32_avx2(dstvec, d);
4586
  // store
4587
301k
  for (int j = 0; j < 16; j++) {
4588
283k
    _mm_storeu_si128((__m128i *)(dst + j * stride),
4589
283k
                     _mm256_castsi256_si128(d[j]));
4590
283k
    _mm_storeu_si128((__m128i *)(dst + (j + 16) * stride),
4591
283k
                     _mm256_extracti128_si256(d[j], 1));
4592
283k
  }
4593
17.7k
}
4594
4595
static void dr_prediction_z3_32x16_avx2(uint8_t *dst, ptrdiff_t stride,
4596
                                        const uint8_t *left, int upsample_left,
4597
15.5k
                                        int dy) {
4598
15.5k
  __m128i dstvec[32], d[16];
4599
4600
15.5k
  dr_prediction_z1_HxW_internal_avx2(16, 32, dstvec, left, upsample_left, dy);
4601
46.7k
  for (int i = 0; i < 32; i += 16) {
4602
31.1k
    transpose16x16_sse2((dstvec + i), d);
4603
530k
    for (int j = 0; j < 16; j++) {
4604
498k
      _mm_storeu_si128((__m128i *)(dst + j * stride + i), d[j]);
4605
498k
    }
4606
31.1k
  }
4607
15.5k
}
4608
4609
static void dr_prediction_z3_32x64_avx2(uint8_t *dst, ptrdiff_t stride,
4610
                                        const uint8_t *left, int upsample_left,
4611
1.50k
                                        int dy) {
4612
1.50k
  uint8_t dstT[64 * 32];
4613
1.50k
  dr_prediction_z1_64xN_avx2(32, dstT, 64, left, upsample_left, dy);
4614
1.50k
  transpose(dstT, 64, dst, stride, 32, 64);
4615
1.50k
}
4616
4617
static void dr_prediction_z3_64x32_avx2(uint8_t *dst, ptrdiff_t stride,
4618
                                        const uint8_t *left, int upsample_left,
4619
2.78k
                                        int dy) {
4620
2.78k
  uint8_t dstT[32 * 64];
4621
2.78k
  dr_prediction_z1_32xN_avx2(64, dstT, 32, left, upsample_left, dy);
4622
2.78k
  transpose(dstT, 32, dst, stride, 64, 32);
4623
2.78k
  return;
4624
2.78k
}
4625
4626
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
4627
static void dr_prediction_z3_16x64_avx2(uint8_t *dst, ptrdiff_t stride,
4628
                                        const uint8_t *left, int upsample_left,
4629
3.72k
                                        int dy) {
4630
3.72k
  uint8_t dstT[64 * 16];
4631
3.72k
  dr_prediction_z1_64xN_avx2(16, dstT, 64, left, upsample_left, dy);
4632
3.72k
  transpose(dstT, 64, dst, stride, 16, 64);
4633
3.72k
}
4634
4635
static void dr_prediction_z3_64x16_avx2(uint8_t *dst, ptrdiff_t stride,
4636
                                        const uint8_t *left, int upsample_left,
4637
13.0k
                                        int dy) {
4638
13.0k
  __m128i dstvec[64], d[16];
4639
4640
13.0k
  dr_prediction_z1_HxW_internal_avx2(16, 64, dstvec, left, upsample_left, dy);
4641
65.2k
  for (int i = 0; i < 64; i += 16) {
4642
52.2k
    transpose16x16_sse2((dstvec + i), d);
4643
887k
    for (int j = 0; j < 16; j++) {
4644
835k
      _mm_storeu_si128((__m128i *)(dst + j * stride + i), d[j]);
4645
835k
    }
4646
52.2k
  }
4647
13.0k
}
4648
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
4649
4650
void av1_dr_prediction_z3_avx2(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
4651
                               const uint8_t *above, const uint8_t *left,
4652
678k
                               int upsample_left, int dx, int dy) {
4653
678k
  (void)above;
4654
678k
  (void)dx;
4655
678k
  assert(dx == 1);
4656
678k
  assert(dy > 0);
4657
4658
678k
  if (bw == bh) {
4659
359k
    switch (bw) {
4660
93.7k
      case 4:
4661
93.7k
        dr_prediction_z3_4x4_avx2(dst, stride, left, upsample_left, dy);
4662
93.7k
        break;
4663
91.0k
      case 8:
4664
91.0k
        dr_prediction_z3_8x8_avx2(dst, stride, left, upsample_left, dy);
4665
91.0k
        break;
4666
77.9k
      case 16:
4667
77.9k
        dr_prediction_z3_16x16_avx2(dst, stride, left, upsample_left, dy);
4668
77.9k
        break;
4669
73.4k
      case 32:
4670
73.4k
        dr_prediction_z3_32x32_avx2(dst, stride, left, upsample_left, dy);
4671
73.4k
        break;
4672
23.4k
      case 64:
4673
23.4k
        dr_prediction_z3_64x64_avx2(dst, stride, left, upsample_left, dy);
4674
23.4k
        break;
4675
359k
    }
4676
359k
  } else {
4677
319k
    if (bw < bh) {
4678
103k
      if (bw + bw == bh) {
4679
67.7k
        switch (bw) {
4680
24.6k
          case 4:
4681
24.6k
            dr_prediction_z3_4x8_avx2(dst, stride, left, upsample_left, dy);
4682
24.6k
            break;
4683
23.8k
          case 8:
4684
23.8k
            dr_prediction_z3_8x16_avx2(dst, stride, left, upsample_left, dy);
4685
23.8k
            break;
4686
17.7k
          case 16:
4687
17.7k
            dr_prediction_z3_16x32_avx2(dst, stride, left, upsample_left, dy);
4688
17.7k
            break;
4689
1.50k
          case 32:
4690
1.50k
            dr_prediction_z3_32x64_avx2(dst, stride, left, upsample_left, dy);
4691
1.50k
            break;
4692
67.7k
        }
4693
67.7k
      } else {
4694
35.9k
        switch (bw) {
4695
0
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
4696
20.4k
          case 4:
4697
20.4k
            dr_prediction_z3_4x16_avx2(dst, stride, left, upsample_left, dy);
4698
20.4k
            break;
4699
11.7k
          case 8:
4700
11.7k
            dr_prediction_z3_8x32_avx2(dst, stride, left, upsample_left, dy);
4701
11.7k
            break;
4702
3.72k
          case 16:
4703
3.72k
            dr_prediction_z3_16x64_avx2(dst, stride, left, upsample_left, dy);
4704
3.72k
            break;
4705
35.9k
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
4706
35.9k
        }
4707
35.9k
      }
4708
215k
    } else {
4709
215k
      if (bh + bh == bw) {
4710
104k
        switch (bh) {
4711
38.4k
          case 4:
4712
38.4k
            dr_prediction_z3_8x4_avx2(dst, stride, left, upsample_left, dy);
4713
38.4k
            break;
4714
47.5k
          case 8:
4715
47.5k
            dr_prediction_z3_16x8_avx2(dst, stride, left, upsample_left, dy);
4716
47.5k
            break;
4717
15.5k
          case 16:
4718
15.5k
            dr_prediction_z3_32x16_avx2(dst, stride, left, upsample_left, dy);
4719
15.5k
            break;
4720
2.78k
          case 32:
4721
2.78k
            dr_prediction_z3_64x32_avx2(dst, stride, left, upsample_left, dy);
4722
2.78k
            break;
4723
104k
        }
4724
111k
      } else {
4725
111k
        switch (bh) {
4726
0
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
4727
55.1k
          case 4:
4728
55.1k
            dr_prediction_z3_16x4_avx2(dst, stride, left, upsample_left, dy);
4729
55.1k
            break;
4730
42.8k
          case 8:
4731
42.8k
            dr_prediction_z3_32x8_avx2(dst, stride, left, upsample_left, dy);
4732
42.8k
            break;
4733
13.0k
          case 16:
4734
13.0k
            dr_prediction_z3_64x16_avx2(dst, stride, left, upsample_left, dy);
4735
13.0k
            break;
4736
111k
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
4737
111k
        }
4738
111k
      }
4739
215k
    }
4740
319k
  }
4741
678k
}