1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker *
4*77c1e3ccSAndroid Build Coastguard Worker * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker */
11*77c1e3ccSAndroid Build Coastguard Worker
12*77c1e3ccSAndroid Build Coastguard Worker #include <arm_neon.h>
13*77c1e3ccSAndroid Build Coastguard Worker #include <assert.h>
14*77c1e3ccSAndroid Build Coastguard Worker #include <stdint.h>
15*77c1e3ccSAndroid Build Coastguard Worker
16*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
17*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_dsp_rtcd.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "config/av1_rtcd.h"
19*77c1e3ccSAndroid Build Coastguard Worker
20*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_integer.h"
21*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/arm/mem_neon.h"
22*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/arm/reinterpret_neon.h"
23*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/arm/sum_neon.h"
24*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/arm/transpose_neon.h"
25*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/intrapred_common.h"
26*77c1e3ccSAndroid Build Coastguard Worker
27*77c1e3ccSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
28*77c1e3ccSAndroid Build Coastguard Worker // DC 4x4
29*77c1e3ccSAndroid Build Coastguard Worker
dc_load_sum_4(const uint8_t * in)30*77c1e3ccSAndroid Build Coastguard Worker static inline uint16x8_t dc_load_sum_4(const uint8_t *in) {
31*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t a = load_u8_4x1(in);
32*77c1e3ccSAndroid Build Coastguard Worker const uint16x4_t p0 = vpaddl_u8(a);
33*77c1e3ccSAndroid Build Coastguard Worker const uint16x4_t p1 = vpadd_u16(p0, p0);
34*77c1e3ccSAndroid Build Coastguard Worker return vcombine_u16(p1, vdup_n_u16(0));
35*77c1e3ccSAndroid Build Coastguard Worker }
36*77c1e3ccSAndroid Build Coastguard Worker
dc_store_4xh(uint8_t * dst,ptrdiff_t stride,int h,uint8x8_t dc)37*77c1e3ccSAndroid Build Coastguard Worker static inline void dc_store_4xh(uint8_t *dst, ptrdiff_t stride, int h,
38*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t dc) {
39*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < h; ++i) {
40*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + i * stride, dc);
41*77c1e3ccSAndroid Build Coastguard Worker }
42*77c1e3ccSAndroid Build Coastguard Worker }
43*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_4x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)44*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
45*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
46*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_top = dc_load_sum_4(above);
47*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_left = dc_load_sum_4(left);
48*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum = vaddq_u16(sum_left, sum_top);
49*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum, 3);
50*77c1e3ccSAndroid Build Coastguard Worker dc_store_4xh(dst, stride, 4, vdup_lane_u8(dc0, 0));
51*77c1e3ccSAndroid Build Coastguard Worker }
52*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_left_predictor_4x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)53*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_left_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
54*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
55*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_left = dc_load_sum_4(left);
56*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum_left, 2);
57*77c1e3ccSAndroid Build Coastguard Worker (void)above;
58*77c1e3ccSAndroid Build Coastguard Worker dc_store_4xh(dst, stride, 4, vdup_lane_u8(dc0, 0));
59*77c1e3ccSAndroid Build Coastguard Worker }
60*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_top_predictor_4x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)61*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_top_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
62*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
63*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_top = dc_load_sum_4(above);
64*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum_top, 2);
65*77c1e3ccSAndroid Build Coastguard Worker (void)left;
66*77c1e3ccSAndroid Build Coastguard Worker dc_store_4xh(dst, stride, 4, vdup_lane_u8(dc0, 0));
67*77c1e3ccSAndroid Build Coastguard Worker }
68*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_128_predictor_4x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)69*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_128_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
70*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
71*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vdup_n_u8(0x80);
72*77c1e3ccSAndroid Build Coastguard Worker (void)above;
73*77c1e3ccSAndroid Build Coastguard Worker (void)left;
74*77c1e3ccSAndroid Build Coastguard Worker dc_store_4xh(dst, stride, 4, dc0);
75*77c1e3ccSAndroid Build Coastguard Worker }
76*77c1e3ccSAndroid Build Coastguard Worker
77*77c1e3ccSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
78*77c1e3ccSAndroid Build Coastguard Worker // DC 8x8
79*77c1e3ccSAndroid Build Coastguard Worker
dc_load_sum_8(const uint8_t * in)80*77c1e3ccSAndroid Build Coastguard Worker static inline uint16x8_t dc_load_sum_8(const uint8_t *in) {
81*77c1e3ccSAndroid Build Coastguard Worker // This isn't used in the case where we want to load both above and left
82*77c1e3ccSAndroid Build Coastguard Worker // vectors, since we want to avoid performing the reduction twice.
83*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t a = vld1_u8(in);
84*77c1e3ccSAndroid Build Coastguard Worker const uint16x4_t p0 = vpaddl_u8(a);
85*77c1e3ccSAndroid Build Coastguard Worker const uint16x4_t p1 = vpadd_u16(p0, p0);
86*77c1e3ccSAndroid Build Coastguard Worker const uint16x4_t p2 = vpadd_u16(p1, p1);
87*77c1e3ccSAndroid Build Coastguard Worker return vcombine_u16(p2, vdup_n_u16(0));
88*77c1e3ccSAndroid Build Coastguard Worker }
89*77c1e3ccSAndroid Build Coastguard Worker
horizontal_add_and_broadcast_u16x8(uint16x8_t a)90*77c1e3ccSAndroid Build Coastguard Worker static inline uint16x8_t horizontal_add_and_broadcast_u16x8(uint16x8_t a) {
91*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_AARCH64
92*77c1e3ccSAndroid Build Coastguard Worker // On AArch64 we could also use vdupq_n_u16(vaddvq_u16(a)) here to save an
93*77c1e3ccSAndroid Build Coastguard Worker // instruction, however the addv instruction is usually slightly more
94*77c1e3ccSAndroid Build Coastguard Worker // expensive than a pairwise addition, so the need for immediately
95*77c1e3ccSAndroid Build Coastguard Worker // broadcasting the result again seems to negate any benefit.
96*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t b = vpaddq_u16(a, a);
97*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t c = vpaddq_u16(b, b);
98*77c1e3ccSAndroid Build Coastguard Worker return vpaddq_u16(c, c);
99*77c1e3ccSAndroid Build Coastguard Worker #else
100*77c1e3ccSAndroid Build Coastguard Worker const uint16x4_t b = vadd_u16(vget_low_u16(a), vget_high_u16(a));
101*77c1e3ccSAndroid Build Coastguard Worker const uint16x4_t c = vpadd_u16(b, b);
102*77c1e3ccSAndroid Build Coastguard Worker const uint16x4_t d = vpadd_u16(c, c);
103*77c1e3ccSAndroid Build Coastguard Worker return vcombine_u16(d, d);
104*77c1e3ccSAndroid Build Coastguard Worker #endif
105*77c1e3ccSAndroid Build Coastguard Worker }
106*77c1e3ccSAndroid Build Coastguard Worker
dc_store_8xh(uint8_t * dst,ptrdiff_t stride,int h,uint8x8_t dc)107*77c1e3ccSAndroid Build Coastguard Worker static inline void dc_store_8xh(uint8_t *dst, ptrdiff_t stride, int h,
108*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t dc) {
109*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < h; ++i) {
110*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + i * stride, dc);
111*77c1e3ccSAndroid Build Coastguard Worker }
112*77c1e3ccSAndroid Build Coastguard Worker }
113*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_8x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)114*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
115*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
116*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t sum_top = vld1_u8(above);
117*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t sum_left = vld1_u8(left);
118*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum = vaddl_u8(sum_left, sum_top);
119*77c1e3ccSAndroid Build Coastguard Worker sum = horizontal_add_and_broadcast_u16x8(sum);
120*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum, 4);
121*77c1e3ccSAndroid Build Coastguard Worker dc_store_8xh(dst, stride, 8, vdup_lane_u8(dc0, 0));
122*77c1e3ccSAndroid Build Coastguard Worker }
123*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_left_predictor_8x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)124*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_left_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
125*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
126*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_left = dc_load_sum_8(left);
127*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum_left, 3);
128*77c1e3ccSAndroid Build Coastguard Worker (void)above;
129*77c1e3ccSAndroid Build Coastguard Worker dc_store_8xh(dst, stride, 8, vdup_lane_u8(dc0, 0));
130*77c1e3ccSAndroid Build Coastguard Worker }
131*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_top_predictor_8x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)132*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_top_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
133*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
134*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_top = dc_load_sum_8(above);
135*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum_top, 3);
136*77c1e3ccSAndroid Build Coastguard Worker (void)left;
137*77c1e3ccSAndroid Build Coastguard Worker dc_store_8xh(dst, stride, 8, vdup_lane_u8(dc0, 0));
138*77c1e3ccSAndroid Build Coastguard Worker }
139*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_128_predictor_8x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)140*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_128_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
141*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
142*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vdup_n_u8(0x80);
143*77c1e3ccSAndroid Build Coastguard Worker (void)above;
144*77c1e3ccSAndroid Build Coastguard Worker (void)left;
145*77c1e3ccSAndroid Build Coastguard Worker dc_store_8xh(dst, stride, 8, dc0);
146*77c1e3ccSAndroid Build Coastguard Worker }
147*77c1e3ccSAndroid Build Coastguard Worker
148*77c1e3ccSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
149*77c1e3ccSAndroid Build Coastguard Worker // DC 16x16
150*77c1e3ccSAndroid Build Coastguard Worker
dc_load_partial_sum_16(const uint8_t * in)151*77c1e3ccSAndroid Build Coastguard Worker static inline uint16x8_t dc_load_partial_sum_16(const uint8_t *in) {
152*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a = vld1q_u8(in);
153*77c1e3ccSAndroid Build Coastguard Worker // delay the remainder of the reduction until
154*77c1e3ccSAndroid Build Coastguard Worker // horizontal_add_and_broadcast_u16x8, since we want to do it once rather
155*77c1e3ccSAndroid Build Coastguard Worker // than twice in the case we are loading both above and left.
156*77c1e3ccSAndroid Build Coastguard Worker return vpaddlq_u8(a);
157*77c1e3ccSAndroid Build Coastguard Worker }
158*77c1e3ccSAndroid Build Coastguard Worker
dc_load_sum_16(const uint8_t * in)159*77c1e3ccSAndroid Build Coastguard Worker static inline uint16x8_t dc_load_sum_16(const uint8_t *in) {
160*77c1e3ccSAndroid Build Coastguard Worker return horizontal_add_and_broadcast_u16x8(dc_load_partial_sum_16(in));
161*77c1e3ccSAndroid Build Coastguard Worker }
162*77c1e3ccSAndroid Build Coastguard Worker
dc_store_16xh(uint8_t * dst,ptrdiff_t stride,int h,uint8x16_t dc)163*77c1e3ccSAndroid Build Coastguard Worker static inline void dc_store_16xh(uint8_t *dst, ptrdiff_t stride, int h,
164*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t dc) {
165*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < h; ++i) {
166*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride, dc);
167*77c1e3ccSAndroid Build Coastguard Worker }
168*77c1e3ccSAndroid Build Coastguard Worker }
169*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_16x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)170*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
171*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
172*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_top = dc_load_partial_sum_16(above);
173*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_left = dc_load_partial_sum_16(left);
174*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum = vaddq_u16(sum_left, sum_top);
175*77c1e3ccSAndroid Build Coastguard Worker sum = horizontal_add_and_broadcast_u16x8(sum);
176*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum, 5);
177*77c1e3ccSAndroid Build Coastguard Worker dc_store_16xh(dst, stride, 16, vdupq_lane_u8(dc0, 0));
178*77c1e3ccSAndroid Build Coastguard Worker }
179*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_left_predictor_16x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)180*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_left_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
181*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above,
182*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
183*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_left = dc_load_sum_16(left);
184*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum_left, 4);
185*77c1e3ccSAndroid Build Coastguard Worker (void)above;
186*77c1e3ccSAndroid Build Coastguard Worker dc_store_16xh(dst, stride, 16, vdupq_lane_u8(dc0, 0));
187*77c1e3ccSAndroid Build Coastguard Worker }
188*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_top_predictor_16x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)189*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_top_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
190*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above,
191*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
192*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_top = dc_load_sum_16(above);
193*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum_top, 4);
194*77c1e3ccSAndroid Build Coastguard Worker (void)left;
195*77c1e3ccSAndroid Build Coastguard Worker dc_store_16xh(dst, stride, 16, vdupq_lane_u8(dc0, 0));
196*77c1e3ccSAndroid Build Coastguard Worker }
197*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_128_predictor_16x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)198*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_128_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
199*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above,
200*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
201*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t dc0 = vdupq_n_u8(0x80);
202*77c1e3ccSAndroid Build Coastguard Worker (void)above;
203*77c1e3ccSAndroid Build Coastguard Worker (void)left;
204*77c1e3ccSAndroid Build Coastguard Worker dc_store_16xh(dst, stride, 16, dc0);
205*77c1e3ccSAndroid Build Coastguard Worker }
206*77c1e3ccSAndroid Build Coastguard Worker
207*77c1e3ccSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
208*77c1e3ccSAndroid Build Coastguard Worker // DC 32x32
209*77c1e3ccSAndroid Build Coastguard Worker
dc_load_partial_sum_32(const uint8_t * in)210*77c1e3ccSAndroid Build Coastguard Worker static inline uint16x8_t dc_load_partial_sum_32(const uint8_t *in) {
211*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a0 = vld1q_u8(in);
212*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a1 = vld1q_u8(in + 16);
213*77c1e3ccSAndroid Build Coastguard Worker // delay the remainder of the reduction until
214*77c1e3ccSAndroid Build Coastguard Worker // horizontal_add_and_broadcast_u16x8, since we want to do it once rather
215*77c1e3ccSAndroid Build Coastguard Worker // than twice in the case we are loading both above and left.
216*77c1e3ccSAndroid Build Coastguard Worker return vpadalq_u8(vpaddlq_u8(a0), a1);
217*77c1e3ccSAndroid Build Coastguard Worker }
218*77c1e3ccSAndroid Build Coastguard Worker
dc_load_sum_32(const uint8_t * in)219*77c1e3ccSAndroid Build Coastguard Worker static inline uint16x8_t dc_load_sum_32(const uint8_t *in) {
220*77c1e3ccSAndroid Build Coastguard Worker return horizontal_add_and_broadcast_u16x8(dc_load_partial_sum_32(in));
221*77c1e3ccSAndroid Build Coastguard Worker }
222*77c1e3ccSAndroid Build Coastguard Worker
dc_store_32xh(uint8_t * dst,ptrdiff_t stride,int h,uint8x16_t dc)223*77c1e3ccSAndroid Build Coastguard Worker static inline void dc_store_32xh(uint8_t *dst, ptrdiff_t stride, int h,
224*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t dc) {
225*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < h; ++i) {
226*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride, dc);
227*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride + 16, dc);
228*77c1e3ccSAndroid Build Coastguard Worker }
229*77c1e3ccSAndroid Build Coastguard Worker }
230*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_32x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)231*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
232*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
233*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_top = dc_load_partial_sum_32(above);
234*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_left = dc_load_partial_sum_32(left);
235*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum = vaddq_u16(sum_left, sum_top);
236*77c1e3ccSAndroid Build Coastguard Worker sum = horizontal_add_and_broadcast_u16x8(sum);
237*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum, 6);
238*77c1e3ccSAndroid Build Coastguard Worker dc_store_32xh(dst, stride, 32, vdupq_lane_u8(dc0, 0));
239*77c1e3ccSAndroid Build Coastguard Worker }
240*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_left_predictor_32x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)241*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_left_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
242*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above,
243*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
244*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_left = dc_load_sum_32(left);
245*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum_left, 5);
246*77c1e3ccSAndroid Build Coastguard Worker (void)above;
247*77c1e3ccSAndroid Build Coastguard Worker dc_store_32xh(dst, stride, 32, vdupq_lane_u8(dc0, 0));
248*77c1e3ccSAndroid Build Coastguard Worker }
249*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_top_predictor_32x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)250*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_top_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
251*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above,
252*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
253*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_top = dc_load_sum_32(above);
254*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum_top, 5);
255*77c1e3ccSAndroid Build Coastguard Worker (void)left;
256*77c1e3ccSAndroid Build Coastguard Worker dc_store_32xh(dst, stride, 32, vdupq_lane_u8(dc0, 0));
257*77c1e3ccSAndroid Build Coastguard Worker }
258*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_128_predictor_32x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)259*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_128_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
260*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above,
261*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
262*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t dc0 = vdupq_n_u8(0x80);
263*77c1e3ccSAndroid Build Coastguard Worker (void)above;
264*77c1e3ccSAndroid Build Coastguard Worker (void)left;
265*77c1e3ccSAndroid Build Coastguard Worker dc_store_32xh(dst, stride, 32, dc0);
266*77c1e3ccSAndroid Build Coastguard Worker }
267*77c1e3ccSAndroid Build Coastguard Worker
268*77c1e3ccSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
269*77c1e3ccSAndroid Build Coastguard Worker // DC 64x64
270*77c1e3ccSAndroid Build Coastguard Worker
dc_load_partial_sum_64(const uint8_t * in)271*77c1e3ccSAndroid Build Coastguard Worker static inline uint16x8_t dc_load_partial_sum_64(const uint8_t *in) {
272*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a0 = vld1q_u8(in);
273*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a1 = vld1q_u8(in + 16);
274*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a2 = vld1q_u8(in + 32);
275*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a3 = vld1q_u8(in + 48);
276*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t p01 = vpadalq_u8(vpaddlq_u8(a0), a1);
277*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t p23 = vpadalq_u8(vpaddlq_u8(a2), a3);
278*77c1e3ccSAndroid Build Coastguard Worker // delay the remainder of the reduction until
279*77c1e3ccSAndroid Build Coastguard Worker // horizontal_add_and_broadcast_u16x8, since we want to do it once rather
280*77c1e3ccSAndroid Build Coastguard Worker // than twice in the case we are loading both above and left.
281*77c1e3ccSAndroid Build Coastguard Worker return vaddq_u16(p01, p23);
282*77c1e3ccSAndroid Build Coastguard Worker }
283*77c1e3ccSAndroid Build Coastguard Worker
dc_load_sum_64(const uint8_t * in)284*77c1e3ccSAndroid Build Coastguard Worker static inline uint16x8_t dc_load_sum_64(const uint8_t *in) {
285*77c1e3ccSAndroid Build Coastguard Worker return horizontal_add_and_broadcast_u16x8(dc_load_partial_sum_64(in));
286*77c1e3ccSAndroid Build Coastguard Worker }
287*77c1e3ccSAndroid Build Coastguard Worker
dc_store_64xh(uint8_t * dst,ptrdiff_t stride,int h,uint8x16_t dc)288*77c1e3ccSAndroid Build Coastguard Worker static inline void dc_store_64xh(uint8_t *dst, ptrdiff_t stride, int h,
289*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t dc) {
290*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < h; ++i) {
291*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride, dc);
292*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride + 16, dc);
293*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride + 32, dc);
294*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride + 48, dc);
295*77c1e3ccSAndroid Build Coastguard Worker }
296*77c1e3ccSAndroid Build Coastguard Worker }
297*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_64x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)298*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_64x64_neon(uint8_t *dst, ptrdiff_t stride,
299*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
300*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_top = dc_load_partial_sum_64(above);
301*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_left = dc_load_partial_sum_64(left);
302*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum = vaddq_u16(sum_left, sum_top);
303*77c1e3ccSAndroid Build Coastguard Worker sum = horizontal_add_and_broadcast_u16x8(sum);
304*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum, 7);
305*77c1e3ccSAndroid Build Coastguard Worker dc_store_64xh(dst, stride, 64, vdupq_lane_u8(dc0, 0));
306*77c1e3ccSAndroid Build Coastguard Worker }
307*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_left_predictor_64x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)308*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_left_predictor_64x64_neon(uint8_t *dst, ptrdiff_t stride,
309*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above,
310*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
311*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_left = dc_load_sum_64(left);
312*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum_left, 6);
313*77c1e3ccSAndroid Build Coastguard Worker (void)above;
314*77c1e3ccSAndroid Build Coastguard Worker dc_store_64xh(dst, stride, 64, vdupq_lane_u8(dc0, 0));
315*77c1e3ccSAndroid Build Coastguard Worker }
316*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_top_predictor_64x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)317*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_top_predictor_64x64_neon(uint8_t *dst, ptrdiff_t stride,
318*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above,
319*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
320*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum_top = dc_load_sum_64(above);
321*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum_top, 6);
322*77c1e3ccSAndroid Build Coastguard Worker (void)left;
323*77c1e3ccSAndroid Build Coastguard Worker dc_store_64xh(dst, stride, 64, vdupq_lane_u8(dc0, 0));
324*77c1e3ccSAndroid Build Coastguard Worker }
325*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_128_predictor_64x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)326*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_128_predictor_64x64_neon(uint8_t *dst, ptrdiff_t stride,
327*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above,
328*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) {
329*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t dc0 = vdupq_n_u8(0x80);
330*77c1e3ccSAndroid Build Coastguard Worker (void)above;
331*77c1e3ccSAndroid Build Coastguard Worker (void)left;
332*77c1e3ccSAndroid Build Coastguard Worker dc_store_64xh(dst, stride, 64, dc0);
333*77c1e3ccSAndroid Build Coastguard Worker }
334*77c1e3ccSAndroid Build Coastguard Worker
335*77c1e3ccSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
336*77c1e3ccSAndroid Build Coastguard Worker // DC rectangular cases
337*77c1e3ccSAndroid Build Coastguard Worker
338*77c1e3ccSAndroid Build Coastguard Worker #define DC_MULTIPLIER_1X2 0x5556
339*77c1e3ccSAndroid Build Coastguard Worker #define DC_MULTIPLIER_1X4 0x3334
340*77c1e3ccSAndroid Build Coastguard Worker
341*77c1e3ccSAndroid Build Coastguard Worker #define DC_SHIFT2 16
342*77c1e3ccSAndroid Build Coastguard Worker
divide_using_multiply_shift(int num,int shift1,int multiplier,int shift2)343*77c1e3ccSAndroid Build Coastguard Worker static inline int divide_using_multiply_shift(int num, int shift1,
344*77c1e3ccSAndroid Build Coastguard Worker int multiplier, int shift2) {
345*77c1e3ccSAndroid Build Coastguard Worker const int interm = num >> shift1;
346*77c1e3ccSAndroid Build Coastguard Worker return interm * multiplier >> shift2;
347*77c1e3ccSAndroid Build Coastguard Worker }
348*77c1e3ccSAndroid Build Coastguard Worker
calculate_dc_from_sum(int bw,int bh,uint32_t sum,int shift1,int multiplier)349*77c1e3ccSAndroid Build Coastguard Worker static inline int calculate_dc_from_sum(int bw, int bh, uint32_t sum,
350*77c1e3ccSAndroid Build Coastguard Worker int shift1, int multiplier) {
351*77c1e3ccSAndroid Build Coastguard Worker const int expected_dc = divide_using_multiply_shift(
352*77c1e3ccSAndroid Build Coastguard Worker sum + ((bw + bh) >> 1), shift1, multiplier, DC_SHIFT2);
353*77c1e3ccSAndroid Build Coastguard Worker assert(expected_dc < (1 << 8));
354*77c1e3ccSAndroid Build Coastguard Worker return expected_dc;
355*77c1e3ccSAndroid Build Coastguard Worker }
356*77c1e3ccSAndroid Build Coastguard Worker
357*77c1e3ccSAndroid Build Coastguard Worker #undef DC_SHIFT2
358*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_4x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)359*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_4x8_neon(uint8_t *dst, ptrdiff_t stride,
360*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
361*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a = load_u8_4x1(above);
362*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t l = vld1_u8(left);
363*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(vaddl_u8(a, l));
364*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(4, 8, sum, 2, DC_MULTIPLIER_1X2);
365*77c1e3ccSAndroid Build Coastguard Worker dc_store_4xh(dst, stride, 8, vdup_n_u8(dc));
366*77c1e3ccSAndroid Build Coastguard Worker }
367*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_8x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)368*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_8x4_neon(uint8_t *dst, ptrdiff_t stride,
369*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
370*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a = vld1_u8(above);
371*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t l = load_u8_4x1(left);
372*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(vaddl_u8(a, l));
373*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(8, 4, sum, 2, DC_MULTIPLIER_1X2);
374*77c1e3ccSAndroid Build Coastguard Worker dc_store_8xh(dst, stride, 4, vdup_n_u8(dc));
375*77c1e3ccSAndroid Build Coastguard Worker }
376*77c1e3ccSAndroid Build Coastguard Worker
377*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_dc_predictor_4x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)378*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_4x16_neon(uint8_t *dst, ptrdiff_t stride,
379*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
380*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a = load_u8_4x1(above);
381*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t l = vld1q_u8(left);
382*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddw_u8(vpaddlq_u8(l), a);
383*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
384*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(4, 16, sum, 2, DC_MULTIPLIER_1X4);
385*77c1e3ccSAndroid Build Coastguard Worker dc_store_4xh(dst, stride, 16, vdup_n_u8(dc));
386*77c1e3ccSAndroid Build Coastguard Worker }
387*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_16x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)388*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_16x4_neon(uint8_t *dst, ptrdiff_t stride,
389*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
390*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a = vld1q_u8(above);
391*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t l = load_u8_4x1(left);
392*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddw_u8(vpaddlq_u8(a), l);
393*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
394*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(16, 4, sum, 2, DC_MULTIPLIER_1X4);
395*77c1e3ccSAndroid Build Coastguard Worker dc_store_16xh(dst, stride, 4, vdupq_n_u8(dc));
396*77c1e3ccSAndroid Build Coastguard Worker }
397*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
398*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_8x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)399*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_8x16_neon(uint8_t *dst, ptrdiff_t stride,
400*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
401*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a = vld1_u8(above);
402*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t l = vld1q_u8(left);
403*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddw_u8(vpaddlq_u8(l), a);
404*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
405*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(8, 16, sum, 3, DC_MULTIPLIER_1X2);
406*77c1e3ccSAndroid Build Coastguard Worker dc_store_8xh(dst, stride, 16, vdup_n_u8(dc));
407*77c1e3ccSAndroid Build Coastguard Worker }
408*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_16x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)409*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_16x8_neon(uint8_t *dst, ptrdiff_t stride,
410*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
411*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a = vld1q_u8(above);
412*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t l = vld1_u8(left);
413*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddw_u8(vpaddlq_u8(a), l);
414*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
415*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(16, 8, sum, 3, DC_MULTIPLIER_1X2);
416*77c1e3ccSAndroid Build Coastguard Worker dc_store_16xh(dst, stride, 8, vdupq_n_u8(dc));
417*77c1e3ccSAndroid Build Coastguard Worker }
418*77c1e3ccSAndroid Build Coastguard Worker
419*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_dc_predictor_8x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)420*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_8x32_neon(uint8_t *dst, ptrdiff_t stride,
421*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
422*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a = vld1_u8(above);
423*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_left = dc_load_partial_sum_32(left);
424*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddw_u8(sum_left, a);
425*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
426*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(8, 32, sum, 3, DC_MULTIPLIER_1X4);
427*77c1e3ccSAndroid Build Coastguard Worker dc_store_8xh(dst, stride, 32, vdup_n_u8(dc));
428*77c1e3ccSAndroid Build Coastguard Worker }
429*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_32x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)430*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_32x8_neon(uint8_t *dst, ptrdiff_t stride,
431*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
432*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_top = dc_load_partial_sum_32(above);
433*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t l = vld1_u8(left);
434*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddw_u8(sum_top, l);
435*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
436*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(32, 8, sum, 3, DC_MULTIPLIER_1X4);
437*77c1e3ccSAndroid Build Coastguard Worker dc_store_32xh(dst, stride, 8, vdupq_n_u8(dc));
438*77c1e3ccSAndroid Build Coastguard Worker }
439*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
440*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_16x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)441*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_16x32_neon(uint8_t *dst, ptrdiff_t stride,
442*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
443*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_above = dc_load_partial_sum_16(above);
444*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_left = dc_load_partial_sum_32(left);
445*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddq_u16(sum_left, sum_above);
446*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
447*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(16, 32, sum, 4, DC_MULTIPLIER_1X2);
448*77c1e3ccSAndroid Build Coastguard Worker dc_store_16xh(dst, stride, 32, vdupq_n_u8(dc));
449*77c1e3ccSAndroid Build Coastguard Worker }
450*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_32x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)451*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_32x16_neon(uint8_t *dst, ptrdiff_t stride,
452*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
453*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_above = dc_load_partial_sum_32(above);
454*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_left = dc_load_partial_sum_16(left);
455*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddq_u16(sum_left, sum_above);
456*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
457*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(32, 16, sum, 4, DC_MULTIPLIER_1X2);
458*77c1e3ccSAndroid Build Coastguard Worker dc_store_32xh(dst, stride, 16, vdupq_n_u8(dc));
459*77c1e3ccSAndroid Build Coastguard Worker }
460*77c1e3ccSAndroid Build Coastguard Worker
461*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_dc_predictor_16x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)462*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_16x64_neon(uint8_t *dst, ptrdiff_t stride,
463*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
464*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_above = dc_load_partial_sum_16(above);
465*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_left = dc_load_partial_sum_64(left);
466*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddq_u16(sum_left, sum_above);
467*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
468*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(16, 64, sum, 4, DC_MULTIPLIER_1X4);
469*77c1e3ccSAndroid Build Coastguard Worker dc_store_16xh(dst, stride, 64, vdupq_n_u8(dc));
470*77c1e3ccSAndroid Build Coastguard Worker }
471*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_64x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)472*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_64x16_neon(uint8_t *dst, ptrdiff_t stride,
473*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
474*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_above = dc_load_partial_sum_64(above);
475*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_left = dc_load_partial_sum_16(left);
476*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddq_u16(sum_above, sum_left);
477*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
478*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(64, 16, sum, 4, DC_MULTIPLIER_1X4);
479*77c1e3ccSAndroid Build Coastguard Worker dc_store_64xh(dst, stride, 16, vdupq_n_u8(dc));
480*77c1e3ccSAndroid Build Coastguard Worker }
481*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
482*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_32x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)483*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_32x64_neon(uint8_t *dst, ptrdiff_t stride,
484*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
485*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_above = dc_load_partial_sum_32(above);
486*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_left = dc_load_partial_sum_64(left);
487*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddq_u16(sum_above, sum_left);
488*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
489*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(32, 64, sum, 5, DC_MULTIPLIER_1X2);
490*77c1e3ccSAndroid Build Coastguard Worker dc_store_32xh(dst, stride, 64, vdupq_n_u8(dc));
491*77c1e3ccSAndroid Build Coastguard Worker }
492*77c1e3ccSAndroid Build Coastguard Worker
aom_dc_predictor_64x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)493*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_predictor_64x32_neon(uint8_t *dst, ptrdiff_t stride,
494*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
495*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_above = dc_load_partial_sum_64(above);
496*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_left = dc_load_partial_sum_32(left);
497*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t sum_al = vaddq_u16(sum_above, sum_left);
498*77c1e3ccSAndroid Build Coastguard Worker uint32_t sum = horizontal_add_u16x8(sum_al);
499*77c1e3ccSAndroid Build Coastguard Worker uint32_t dc = calculate_dc_from_sum(64, 32, sum, 5, DC_MULTIPLIER_1X2);
500*77c1e3ccSAndroid Build Coastguard Worker dc_store_64xh(dst, stride, 32, vdupq_n_u8(dc));
501*77c1e3ccSAndroid Build Coastguard Worker }
502*77c1e3ccSAndroid Build Coastguard Worker
503*77c1e3ccSAndroid Build Coastguard Worker #undef DC_MULTIPLIER_1X2
504*77c1e3ccSAndroid Build Coastguard Worker #undef DC_MULTIPLIER_1X4
505*77c1e3ccSAndroid Build Coastguard Worker
506*77c1e3ccSAndroid Build Coastguard Worker #define DC_PREDICTOR_128(w, h, q) \
507*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_128_predictor_##w##x##h##_neon(uint8_t *dst, ptrdiff_t stride, \
508*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, \
509*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
510*77c1e3ccSAndroid Build Coastguard Worker (void)above; \
511*77c1e3ccSAndroid Build Coastguard Worker (void)left; \
512*77c1e3ccSAndroid Build Coastguard Worker dc_store_##w##xh(dst, stride, (h), vdup##q##_n_u8(0x80)); \
513*77c1e3ccSAndroid Build Coastguard Worker }
514*77c1e3ccSAndroid Build Coastguard Worker
515*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
516*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(4, 16, )
517*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(8, 32, )
518*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(16, 4, q)
519*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(16, 64, q)
520*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(32, 8, q)
521*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(64, 16, q)
522*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
523*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(4, 8, )
524*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(8, 4, )
525*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(8, 16, )
526*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(16, 8, q)
527*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(16, 32, q)
528*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(32, 16, q)
529*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(32, 64, q)
530*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_128(64, 32, q)
531*77c1e3ccSAndroid Build Coastguard Worker
532*77c1e3ccSAndroid Build Coastguard Worker #undef DC_PREDICTOR_128
533*77c1e3ccSAndroid Build Coastguard Worker
534*77c1e3ccSAndroid Build Coastguard Worker #define DC_PREDICTOR_LEFT(w, h, shift, q) \
535*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_left_predictor_##w##x##h##_neon(uint8_t *dst, ptrdiff_t stride, \
536*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, \
537*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
538*77c1e3ccSAndroid Build Coastguard Worker (void)above; \
539*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum = dc_load_sum_##h(left); \
540*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum, (shift)); \
541*77c1e3ccSAndroid Build Coastguard Worker dc_store_##w##xh(dst, stride, (h), vdup##q##_lane_u8(dc0, 0)); \
542*77c1e3ccSAndroid Build Coastguard Worker }
543*77c1e3ccSAndroid Build Coastguard Worker
544*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(4, 8, 3, )
545*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(8, 4, 2, )
546*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(8, 16, 4, )
547*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(16, 8, 3, q)
548*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(16, 32, 5, q)
549*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(32, 16, 4, q)
550*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(32, 64, 6, q)
551*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(64, 32, 5, q)
552*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
553*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(4, 16, 4, )
554*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(16, 4, 2, q)
555*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(8, 32, 5, )
556*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(32, 8, 3, q)
557*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(16, 64, 6, q)
558*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_LEFT(64, 16, 4, q)
559*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
560*77c1e3ccSAndroid Build Coastguard Worker
561*77c1e3ccSAndroid Build Coastguard Worker #undef DC_PREDICTOR_LEFT
562*77c1e3ccSAndroid Build Coastguard Worker
563*77c1e3ccSAndroid Build Coastguard Worker #define DC_PREDICTOR_TOP(w, h, shift, q) \
564*77c1e3ccSAndroid Build Coastguard Worker void aom_dc_top_predictor_##w##x##h##_neon(uint8_t *dst, ptrdiff_t stride, \
565*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, \
566*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
567*77c1e3ccSAndroid Build Coastguard Worker (void)left; \
568*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t sum = dc_load_sum_##w(above); \
569*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t dc0 = vrshrn_n_u16(sum, (shift)); \
570*77c1e3ccSAndroid Build Coastguard Worker dc_store_##w##xh(dst, stride, (h), vdup##q##_lane_u8(dc0, 0)); \
571*77c1e3ccSAndroid Build Coastguard Worker }
572*77c1e3ccSAndroid Build Coastguard Worker
573*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
574*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(8, 32, 3, )
575*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(4, 16, 2, )
576*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(16, 4, 4, q)
577*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(16, 64, 4, q)
578*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(32, 8, 5, q)
579*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(64, 16, 6, q)
580*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
581*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(4, 8, 2, )
582*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(8, 4, 3, )
583*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(8, 16, 3, )
584*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(16, 8, 4, q)
585*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(16, 32, 4, q)
586*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(32, 16, 5, q)
587*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(32, 64, 5, q)
588*77c1e3ccSAndroid Build Coastguard Worker DC_PREDICTOR_TOP(64, 32, 6, q)
589*77c1e3ccSAndroid Build Coastguard Worker
590*77c1e3ccSAndroid Build Coastguard Worker #undef DC_PREDICTOR_TOP
591*77c1e3ccSAndroid Build Coastguard Worker
592*77c1e3ccSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
593*77c1e3ccSAndroid Build Coastguard Worker
v_store_4xh(uint8_t * dst,ptrdiff_t stride,int h,uint8x8_t d0)594*77c1e3ccSAndroid Build Coastguard Worker static inline void v_store_4xh(uint8_t *dst, ptrdiff_t stride, int h,
595*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t d0) {
596*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < h; ++i) {
597*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + i * stride, d0);
598*77c1e3ccSAndroid Build Coastguard Worker }
599*77c1e3ccSAndroid Build Coastguard Worker }
600*77c1e3ccSAndroid Build Coastguard Worker
v_store_8xh(uint8_t * dst,ptrdiff_t stride,int h,uint8x8_t d0)601*77c1e3ccSAndroid Build Coastguard Worker static inline void v_store_8xh(uint8_t *dst, ptrdiff_t stride, int h,
602*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t d0) {
603*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < h; ++i) {
604*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + i * stride, d0);
605*77c1e3ccSAndroid Build Coastguard Worker }
606*77c1e3ccSAndroid Build Coastguard Worker }
607*77c1e3ccSAndroid Build Coastguard Worker
v_store_16xh(uint8_t * dst,ptrdiff_t stride,int h,uint8x16_t d0)608*77c1e3ccSAndroid Build Coastguard Worker static inline void v_store_16xh(uint8_t *dst, ptrdiff_t stride, int h,
609*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d0) {
610*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < h; ++i) {
611*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride, d0);
612*77c1e3ccSAndroid Build Coastguard Worker }
613*77c1e3ccSAndroid Build Coastguard Worker }
614*77c1e3ccSAndroid Build Coastguard Worker
v_store_32xh(uint8_t * dst,ptrdiff_t stride,int h,uint8x16_t d0,uint8x16_t d1)615*77c1e3ccSAndroid Build Coastguard Worker static inline void v_store_32xh(uint8_t *dst, ptrdiff_t stride, int h,
616*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d0, uint8x16_t d1) {
617*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < h; ++i) {
618*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, d0);
619*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, d1);
620*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
621*77c1e3ccSAndroid Build Coastguard Worker }
622*77c1e3ccSAndroid Build Coastguard Worker }
623*77c1e3ccSAndroid Build Coastguard Worker
v_store_64xh(uint8_t * dst,ptrdiff_t stride,int h,uint8x16_t d0,uint8x16_t d1,uint8x16_t d2,uint8x16_t d3)624*77c1e3ccSAndroid Build Coastguard Worker static inline void v_store_64xh(uint8_t *dst, ptrdiff_t stride, int h,
625*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d0, uint8x16_t d1, uint8x16_t d2,
626*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d3) {
627*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < h; ++i) {
628*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, d0);
629*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, d1);
630*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, d2);
631*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, d3);
632*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
633*77c1e3ccSAndroid Build Coastguard Worker }
634*77c1e3ccSAndroid Build Coastguard Worker }
635*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_4x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)636*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
637*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
638*77c1e3ccSAndroid Build Coastguard Worker (void)left;
639*77c1e3ccSAndroid Build Coastguard Worker v_store_4xh(dst, stride, 4, load_u8_4x1(above));
640*77c1e3ccSAndroid Build Coastguard Worker }
641*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_8x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)642*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
643*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
644*77c1e3ccSAndroid Build Coastguard Worker (void)left;
645*77c1e3ccSAndroid Build Coastguard Worker v_store_8xh(dst, stride, 8, vld1_u8(above));
646*77c1e3ccSAndroid Build Coastguard Worker }
647*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_16x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)648*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
649*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
650*77c1e3ccSAndroid Build Coastguard Worker (void)left;
651*77c1e3ccSAndroid Build Coastguard Worker v_store_16xh(dst, stride, 16, vld1q_u8(above));
652*77c1e3ccSAndroid Build Coastguard Worker }
653*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_32x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)654*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
655*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
656*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(above);
657*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(above + 16);
658*77c1e3ccSAndroid Build Coastguard Worker (void)left;
659*77c1e3ccSAndroid Build Coastguard Worker v_store_32xh(dst, stride, 32, d0, d1);
660*77c1e3ccSAndroid Build Coastguard Worker }
661*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_4x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)662*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_4x8_neon(uint8_t *dst, ptrdiff_t stride,
663*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
664*77c1e3ccSAndroid Build Coastguard Worker (void)left;
665*77c1e3ccSAndroid Build Coastguard Worker v_store_4xh(dst, stride, 8, load_u8_4x1(above));
666*77c1e3ccSAndroid Build Coastguard Worker }
667*77c1e3ccSAndroid Build Coastguard Worker
668*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_v_predictor_4x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)669*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_4x16_neon(uint8_t *dst, ptrdiff_t stride,
670*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
671*77c1e3ccSAndroid Build Coastguard Worker (void)left;
672*77c1e3ccSAndroid Build Coastguard Worker v_store_4xh(dst, stride, 16, load_u8_4x1(above));
673*77c1e3ccSAndroid Build Coastguard Worker }
674*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
675*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_8x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)676*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_8x4_neon(uint8_t *dst, ptrdiff_t stride,
677*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
678*77c1e3ccSAndroid Build Coastguard Worker (void)left;
679*77c1e3ccSAndroid Build Coastguard Worker v_store_8xh(dst, stride, 4, vld1_u8(above));
680*77c1e3ccSAndroid Build Coastguard Worker }
681*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_8x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)682*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_8x16_neon(uint8_t *dst, ptrdiff_t stride,
683*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
684*77c1e3ccSAndroid Build Coastguard Worker (void)left;
685*77c1e3ccSAndroid Build Coastguard Worker v_store_8xh(dst, stride, 16, vld1_u8(above));
686*77c1e3ccSAndroid Build Coastguard Worker }
687*77c1e3ccSAndroid Build Coastguard Worker
688*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_v_predictor_8x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)689*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_8x32_neon(uint8_t *dst, ptrdiff_t stride,
690*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
691*77c1e3ccSAndroid Build Coastguard Worker (void)left;
692*77c1e3ccSAndroid Build Coastguard Worker v_store_8xh(dst, stride, 32, vld1_u8(above));
693*77c1e3ccSAndroid Build Coastguard Worker }
694*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_16x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)695*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_16x4_neon(uint8_t *dst, ptrdiff_t stride,
696*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
697*77c1e3ccSAndroid Build Coastguard Worker (void)left;
698*77c1e3ccSAndroid Build Coastguard Worker v_store_16xh(dst, stride, 4, vld1q_u8(above));
699*77c1e3ccSAndroid Build Coastguard Worker }
700*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
701*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_16x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)702*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_16x8_neon(uint8_t *dst, ptrdiff_t stride,
703*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
704*77c1e3ccSAndroid Build Coastguard Worker (void)left;
705*77c1e3ccSAndroid Build Coastguard Worker v_store_16xh(dst, stride, 8, vld1q_u8(above));
706*77c1e3ccSAndroid Build Coastguard Worker }
707*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_16x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)708*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_16x32_neon(uint8_t *dst, ptrdiff_t stride,
709*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
710*77c1e3ccSAndroid Build Coastguard Worker (void)left;
711*77c1e3ccSAndroid Build Coastguard Worker v_store_16xh(dst, stride, 32, vld1q_u8(above));
712*77c1e3ccSAndroid Build Coastguard Worker }
713*77c1e3ccSAndroid Build Coastguard Worker
714*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_v_predictor_16x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)715*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_16x64_neon(uint8_t *dst, ptrdiff_t stride,
716*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
717*77c1e3ccSAndroid Build Coastguard Worker (void)left;
718*77c1e3ccSAndroid Build Coastguard Worker v_store_16xh(dst, stride, 64, vld1q_u8(above));
719*77c1e3ccSAndroid Build Coastguard Worker }
720*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_32x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)721*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_32x8_neon(uint8_t *dst, ptrdiff_t stride,
722*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
723*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(above);
724*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(above + 16);
725*77c1e3ccSAndroid Build Coastguard Worker (void)left;
726*77c1e3ccSAndroid Build Coastguard Worker v_store_32xh(dst, stride, 8, d0, d1);
727*77c1e3ccSAndroid Build Coastguard Worker }
728*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
729*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_32x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)730*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_32x16_neon(uint8_t *dst, ptrdiff_t stride,
731*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
732*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(above);
733*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(above + 16);
734*77c1e3ccSAndroid Build Coastguard Worker (void)left;
735*77c1e3ccSAndroid Build Coastguard Worker v_store_32xh(dst, stride, 16, d0, d1);
736*77c1e3ccSAndroid Build Coastguard Worker }
737*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_32x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)738*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_32x64_neon(uint8_t *dst, ptrdiff_t stride,
739*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
740*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(above);
741*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(above + 16);
742*77c1e3ccSAndroid Build Coastguard Worker (void)left;
743*77c1e3ccSAndroid Build Coastguard Worker v_store_32xh(dst, stride, 64, d0, d1);
744*77c1e3ccSAndroid Build Coastguard Worker }
745*77c1e3ccSAndroid Build Coastguard Worker
746*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_v_predictor_64x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)747*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_64x16_neon(uint8_t *dst, ptrdiff_t stride,
748*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
749*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(above);
750*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(above + 16);
751*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d2 = vld1q_u8(above + 32);
752*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d3 = vld1q_u8(above + 48);
753*77c1e3ccSAndroid Build Coastguard Worker (void)left;
754*77c1e3ccSAndroid Build Coastguard Worker v_store_64xh(dst, stride, 16, d0, d1, d2, d3);
755*77c1e3ccSAndroid Build Coastguard Worker }
756*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
757*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_64x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)758*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_64x32_neon(uint8_t *dst, ptrdiff_t stride,
759*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
760*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(above);
761*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(above + 16);
762*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d2 = vld1q_u8(above + 32);
763*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d3 = vld1q_u8(above + 48);
764*77c1e3ccSAndroid Build Coastguard Worker (void)left;
765*77c1e3ccSAndroid Build Coastguard Worker v_store_64xh(dst, stride, 32, d0, d1, d2, d3);
766*77c1e3ccSAndroid Build Coastguard Worker }
767*77c1e3ccSAndroid Build Coastguard Worker
aom_v_predictor_64x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)768*77c1e3ccSAndroid Build Coastguard Worker void aom_v_predictor_64x64_neon(uint8_t *dst, ptrdiff_t stride,
769*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
770*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(above);
771*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(above + 16);
772*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d2 = vld1q_u8(above + 32);
773*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d3 = vld1q_u8(above + 48);
774*77c1e3ccSAndroid Build Coastguard Worker (void)left;
775*77c1e3ccSAndroid Build Coastguard Worker v_store_64xh(dst, stride, 64, d0, d1, d2, d3);
776*77c1e3ccSAndroid Build Coastguard Worker }
777*77c1e3ccSAndroid Build Coastguard Worker
778*77c1e3ccSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
779*77c1e3ccSAndroid Build Coastguard Worker
h_store_4x8(uint8_t * dst,ptrdiff_t stride,uint8x8_t d0)780*77c1e3ccSAndroid Build Coastguard Worker static inline void h_store_4x8(uint8_t *dst, ptrdiff_t stride, uint8x8_t d0) {
781*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 0 * stride, vdup_lane_u8(d0, 0));
782*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 1 * stride, vdup_lane_u8(d0, 1));
783*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 2 * stride, vdup_lane_u8(d0, 2));
784*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 3 * stride, vdup_lane_u8(d0, 3));
785*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 4 * stride, vdup_lane_u8(d0, 4));
786*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 5 * stride, vdup_lane_u8(d0, 5));
787*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 6 * stride, vdup_lane_u8(d0, 6));
788*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 7 * stride, vdup_lane_u8(d0, 7));
789*77c1e3ccSAndroid Build Coastguard Worker }
790*77c1e3ccSAndroid Build Coastguard Worker
h_store_8x8(uint8_t * dst,ptrdiff_t stride,uint8x8_t d0)791*77c1e3ccSAndroid Build Coastguard Worker static inline void h_store_8x8(uint8_t *dst, ptrdiff_t stride, uint8x8_t d0) {
792*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 0 * stride, vdup_lane_u8(d0, 0));
793*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 1 * stride, vdup_lane_u8(d0, 1));
794*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 2 * stride, vdup_lane_u8(d0, 2));
795*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 3 * stride, vdup_lane_u8(d0, 3));
796*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 4 * stride, vdup_lane_u8(d0, 4));
797*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 5 * stride, vdup_lane_u8(d0, 5));
798*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 6 * stride, vdup_lane_u8(d0, 6));
799*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 7 * stride, vdup_lane_u8(d0, 7));
800*77c1e3ccSAndroid Build Coastguard Worker }
801*77c1e3ccSAndroid Build Coastguard Worker
h_store_16x8(uint8_t * dst,ptrdiff_t stride,uint8x8_t d0)802*77c1e3ccSAndroid Build Coastguard Worker static inline void h_store_16x8(uint8_t *dst, ptrdiff_t stride, uint8x8_t d0) {
803*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0 * stride, vdupq_lane_u8(d0, 0));
804*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 1 * stride, vdupq_lane_u8(d0, 1));
805*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 2 * stride, vdupq_lane_u8(d0, 2));
806*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 3 * stride, vdupq_lane_u8(d0, 3));
807*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 4 * stride, vdupq_lane_u8(d0, 4));
808*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 5 * stride, vdupq_lane_u8(d0, 5));
809*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 6 * stride, vdupq_lane_u8(d0, 6));
810*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 7 * stride, vdupq_lane_u8(d0, 7));
811*77c1e3ccSAndroid Build Coastguard Worker }
812*77c1e3ccSAndroid Build Coastguard Worker
h_store_32x8(uint8_t * dst,ptrdiff_t stride,uint8x8_t d0)813*77c1e3ccSAndroid Build Coastguard Worker static inline void h_store_32x8(uint8_t *dst, ptrdiff_t stride, uint8x8_t d0) {
814*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 0));
815*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 0));
816*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
817*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 1));
818*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 1));
819*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
820*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 2));
821*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 2));
822*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
823*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 3));
824*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 3));
825*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
826*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 4));
827*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 4));
828*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
829*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 5));
830*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 5));
831*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
832*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 6));
833*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 6));
834*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
835*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 7));
836*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 7));
837*77c1e3ccSAndroid Build Coastguard Worker }
838*77c1e3ccSAndroid Build Coastguard Worker
h_store_64x8(uint8_t * dst,ptrdiff_t stride,uint8x8_t d0)839*77c1e3ccSAndroid Build Coastguard Worker static inline void h_store_64x8(uint8_t *dst, ptrdiff_t stride, uint8x8_t d0) {
840*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 0));
841*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 0));
842*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, vdupq_lane_u8(d0, 0));
843*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, vdupq_lane_u8(d0, 0));
844*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
845*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 1));
846*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 1));
847*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, vdupq_lane_u8(d0, 1));
848*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, vdupq_lane_u8(d0, 1));
849*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
850*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 2));
851*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 2));
852*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, vdupq_lane_u8(d0, 2));
853*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, vdupq_lane_u8(d0, 2));
854*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
855*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 3));
856*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 3));
857*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, vdupq_lane_u8(d0, 3));
858*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, vdupq_lane_u8(d0, 3));
859*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
860*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 4));
861*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 4));
862*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, vdupq_lane_u8(d0, 4));
863*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, vdupq_lane_u8(d0, 4));
864*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
865*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 5));
866*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 5));
867*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, vdupq_lane_u8(d0, 5));
868*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, vdupq_lane_u8(d0, 5));
869*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
870*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 6));
871*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 6));
872*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, vdupq_lane_u8(d0, 6));
873*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, vdupq_lane_u8(d0, 6));
874*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
875*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0, vdupq_lane_u8(d0, 7));
876*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, vdupq_lane_u8(d0, 7));
877*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, vdupq_lane_u8(d0, 7));
878*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, vdupq_lane_u8(d0, 7));
879*77c1e3ccSAndroid Build Coastguard Worker }
880*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_4x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)881*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
882*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
883*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t d0 = load_u8_4x1(left);
884*77c1e3ccSAndroid Build Coastguard Worker (void)above;
885*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 0 * stride, vdup_lane_u8(d0, 0));
886*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 1 * stride, vdup_lane_u8(d0, 1));
887*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 2 * stride, vdup_lane_u8(d0, 2));
888*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dst + 3 * stride, vdup_lane_u8(d0, 3));
889*77c1e3ccSAndroid Build Coastguard Worker }
890*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_8x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)891*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
892*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
893*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t d0 = vld1_u8(left);
894*77c1e3ccSAndroid Build Coastguard Worker (void)above;
895*77c1e3ccSAndroid Build Coastguard Worker h_store_8x8(dst, stride, d0);
896*77c1e3ccSAndroid Build Coastguard Worker }
897*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_16x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)898*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
899*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
900*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left);
901*77c1e3ccSAndroid Build Coastguard Worker (void)above;
902*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst, stride, vget_low_u8(d0));
903*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 8 * stride, stride, vget_high_u8(d0));
904*77c1e3ccSAndroid Build Coastguard Worker }
905*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_32x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)906*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
907*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
908*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left);
909*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(left + 16);
910*77c1e3ccSAndroid Build Coastguard Worker (void)above;
911*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 0 * stride, stride, vget_low_u8(d0));
912*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 8 * stride, stride, vget_high_u8(d0));
913*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 16 * stride, stride, vget_low_u8(d1));
914*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 24 * stride, stride, vget_high_u8(d1));
915*77c1e3ccSAndroid Build Coastguard Worker }
916*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_4x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)917*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_4x8_neon(uint8_t *dst, ptrdiff_t stride,
918*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
919*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t d0 = vld1_u8(left);
920*77c1e3ccSAndroid Build Coastguard Worker (void)above;
921*77c1e3ccSAndroid Build Coastguard Worker h_store_4x8(dst, stride, d0);
922*77c1e3ccSAndroid Build Coastguard Worker }
923*77c1e3ccSAndroid Build Coastguard Worker
924*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_h_predictor_4x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)925*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_4x16_neon(uint8_t *dst, ptrdiff_t stride,
926*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
927*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left);
928*77c1e3ccSAndroid Build Coastguard Worker (void)above;
929*77c1e3ccSAndroid Build Coastguard Worker h_store_4x8(dst + 0 * stride, stride, vget_low_u8(d0));
930*77c1e3ccSAndroid Build Coastguard Worker h_store_4x8(dst + 8 * stride, stride, vget_high_u8(d0));
931*77c1e3ccSAndroid Build Coastguard Worker }
932*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
933*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_8x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)934*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_8x4_neon(uint8_t *dst, ptrdiff_t stride,
935*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
936*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t d0 = load_u8_4x1(left);
937*77c1e3ccSAndroid Build Coastguard Worker (void)above;
938*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 0 * stride, vdup_lane_u8(d0, 0));
939*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 1 * stride, vdup_lane_u8(d0, 1));
940*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 2 * stride, vdup_lane_u8(d0, 2));
941*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + 3 * stride, vdup_lane_u8(d0, 3));
942*77c1e3ccSAndroid Build Coastguard Worker }
943*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_8x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)944*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_8x16_neon(uint8_t *dst, ptrdiff_t stride,
945*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
946*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left);
947*77c1e3ccSAndroid Build Coastguard Worker (void)above;
948*77c1e3ccSAndroid Build Coastguard Worker h_store_8x8(dst + 0 * stride, stride, vget_low_u8(d0));
949*77c1e3ccSAndroid Build Coastguard Worker h_store_8x8(dst + 8 * stride, stride, vget_high_u8(d0));
950*77c1e3ccSAndroid Build Coastguard Worker }
951*77c1e3ccSAndroid Build Coastguard Worker
952*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_h_predictor_8x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)953*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_8x32_neon(uint8_t *dst, ptrdiff_t stride,
954*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
955*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left);
956*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(left + 16);
957*77c1e3ccSAndroid Build Coastguard Worker (void)above;
958*77c1e3ccSAndroid Build Coastguard Worker h_store_8x8(dst + 0 * stride, stride, vget_low_u8(d0));
959*77c1e3ccSAndroid Build Coastguard Worker h_store_8x8(dst + 8 * stride, stride, vget_high_u8(d0));
960*77c1e3ccSAndroid Build Coastguard Worker h_store_8x8(dst + 16 * stride, stride, vget_low_u8(d1));
961*77c1e3ccSAndroid Build Coastguard Worker h_store_8x8(dst + 24 * stride, stride, vget_high_u8(d1));
962*77c1e3ccSAndroid Build Coastguard Worker }
963*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_16x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)964*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_16x4_neon(uint8_t *dst, ptrdiff_t stride,
965*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
966*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t d0 = load_u8_4x1(left);
967*77c1e3ccSAndroid Build Coastguard Worker (void)above;
968*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 0 * stride, vdupq_lane_u8(d0, 0));
969*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 1 * stride, vdupq_lane_u8(d0, 1));
970*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 2 * stride, vdupq_lane_u8(d0, 2));
971*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 3 * stride, vdupq_lane_u8(d0, 3));
972*77c1e3ccSAndroid Build Coastguard Worker }
973*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
974*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_16x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)975*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_16x8_neon(uint8_t *dst, ptrdiff_t stride,
976*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
977*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t d0 = vld1_u8(left);
978*77c1e3ccSAndroid Build Coastguard Worker (void)above;
979*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst, stride, d0);
980*77c1e3ccSAndroid Build Coastguard Worker }
981*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_16x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)982*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_16x32_neon(uint8_t *dst, ptrdiff_t stride,
983*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
984*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left);
985*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(left + 16);
986*77c1e3ccSAndroid Build Coastguard Worker (void)above;
987*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 0 * stride, stride, vget_low_u8(d0));
988*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 8 * stride, stride, vget_high_u8(d0));
989*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 16 * stride, stride, vget_low_u8(d1));
990*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 24 * stride, stride, vget_high_u8(d1));
991*77c1e3ccSAndroid Build Coastguard Worker }
992*77c1e3ccSAndroid Build Coastguard Worker
993*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_h_predictor_16x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)994*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_16x64_neon(uint8_t *dst, ptrdiff_t stride,
995*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
996*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left);
997*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(left + 16);
998*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d2 = vld1q_u8(left + 32);
999*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d3 = vld1q_u8(left + 48);
1000*77c1e3ccSAndroid Build Coastguard Worker (void)above;
1001*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 0 * stride, stride, vget_low_u8(d0));
1002*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 8 * stride, stride, vget_high_u8(d0));
1003*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 16 * stride, stride, vget_low_u8(d1));
1004*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 24 * stride, stride, vget_high_u8(d1));
1005*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 32 * stride, stride, vget_low_u8(d2));
1006*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 40 * stride, stride, vget_high_u8(d2));
1007*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 48 * stride, stride, vget_low_u8(d3));
1008*77c1e3ccSAndroid Build Coastguard Worker h_store_16x8(dst + 56 * stride, stride, vget_high_u8(d3));
1009*77c1e3ccSAndroid Build Coastguard Worker }
1010*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_32x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)1011*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_32x8_neon(uint8_t *dst, ptrdiff_t stride,
1012*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
1013*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t d0 = vld1_u8(left);
1014*77c1e3ccSAndroid Build Coastguard Worker (void)above;
1015*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst, stride, d0);
1016*77c1e3ccSAndroid Build Coastguard Worker }
1017*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
1018*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_32x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)1019*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_32x16_neon(uint8_t *dst, ptrdiff_t stride,
1020*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
1021*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left);
1022*77c1e3ccSAndroid Build Coastguard Worker (void)above;
1023*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 0 * stride, stride, vget_low_u8(d0));
1024*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 8 * stride, stride, vget_high_u8(d0));
1025*77c1e3ccSAndroid Build Coastguard Worker }
1026*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_32x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)1027*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_32x64_neon(uint8_t *dst, ptrdiff_t stride,
1028*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
1029*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left + 0);
1030*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d1 = vld1q_u8(left + 16);
1031*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d2 = vld1q_u8(left + 32);
1032*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d3 = vld1q_u8(left + 48);
1033*77c1e3ccSAndroid Build Coastguard Worker (void)above;
1034*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 0 * stride, stride, vget_low_u8(d0));
1035*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 8 * stride, stride, vget_high_u8(d0));
1036*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 16 * stride, stride, vget_low_u8(d1));
1037*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 24 * stride, stride, vget_high_u8(d1));
1038*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 32 * stride, stride, vget_low_u8(d2));
1039*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 40 * stride, stride, vget_high_u8(d2));
1040*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 48 * stride, stride, vget_low_u8(d3));
1041*77c1e3ccSAndroid Build Coastguard Worker h_store_32x8(dst + 56 * stride, stride, vget_high_u8(d3));
1042*77c1e3ccSAndroid Build Coastguard Worker }
1043*77c1e3ccSAndroid Build Coastguard Worker
1044*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
aom_h_predictor_64x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)1045*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_64x16_neon(uint8_t *dst, ptrdiff_t stride,
1046*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
1047*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left);
1048*77c1e3ccSAndroid Build Coastguard Worker (void)above;
1049*77c1e3ccSAndroid Build Coastguard Worker h_store_64x8(dst + 0 * stride, stride, vget_low_u8(d0));
1050*77c1e3ccSAndroid Build Coastguard Worker h_store_64x8(dst + 8 * stride, stride, vget_high_u8(d0));
1051*77c1e3ccSAndroid Build Coastguard Worker }
1052*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
1053*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_64x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)1054*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_64x32_neon(uint8_t *dst, ptrdiff_t stride,
1055*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
1056*77c1e3ccSAndroid Build Coastguard Worker (void)above;
1057*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 2; ++i) {
1058*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left);
1059*77c1e3ccSAndroid Build Coastguard Worker h_store_64x8(dst + 0 * stride, stride, vget_low_u8(d0));
1060*77c1e3ccSAndroid Build Coastguard Worker h_store_64x8(dst + 8 * stride, stride, vget_high_u8(d0));
1061*77c1e3ccSAndroid Build Coastguard Worker left += 16;
1062*77c1e3ccSAndroid Build Coastguard Worker dst += 16 * stride;
1063*77c1e3ccSAndroid Build Coastguard Worker }
1064*77c1e3ccSAndroid Build Coastguard Worker }
1065*77c1e3ccSAndroid Build Coastguard Worker
aom_h_predictor_64x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left)1066*77c1e3ccSAndroid Build Coastguard Worker void aom_h_predictor_64x64_neon(uint8_t *dst, ptrdiff_t stride,
1067*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left) {
1068*77c1e3ccSAndroid Build Coastguard Worker (void)above;
1069*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 4; ++i) {
1070*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t d0 = vld1q_u8(left);
1071*77c1e3ccSAndroid Build Coastguard Worker h_store_64x8(dst + 0 * stride, stride, vget_low_u8(d0));
1072*77c1e3ccSAndroid Build Coastguard Worker h_store_64x8(dst + 8 * stride, stride, vget_high_u8(d0));
1073*77c1e3ccSAndroid Build Coastguard Worker left += 16;
1074*77c1e3ccSAndroid Build Coastguard Worker dst += 16 * stride;
1075*77c1e3ccSAndroid Build Coastguard Worker }
1076*77c1e3ccSAndroid Build Coastguard Worker }
1077*77c1e3ccSAndroid Build Coastguard Worker
1078*77c1e3ccSAndroid Build Coastguard Worker /* ---------------------P R E D I C T I O N Z 1--------------------------- */
1079*77c1e3ccSAndroid Build Coastguard Worker
1080*77c1e3ccSAndroid Build Coastguard Worker // Low bit depth functions
1081*77c1e3ccSAndroid Build Coastguard Worker static DECLARE_ALIGNED(32, const uint8_t, BaseMask[33][32]) = {
1082*77c1e3ccSAndroid Build Coastguard Worker { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1083*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1084*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1085*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1086*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1087*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1088*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1089*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1090*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1091*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1092*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1093*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1094*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1095*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1096*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1097*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1098*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0,
1099*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1100*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0,
1101*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1102*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,
1103*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1104*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1105*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1106*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1107*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1108*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1109*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1110*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1111*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1112*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1113*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1114*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1115*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0,
1116*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1117*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1118*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0,
1119*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1120*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1121*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0,
1122*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1123*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1124*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0,
1125*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1126*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1127*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0,
1128*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1129*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1130*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
1131*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1132*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1133*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0,
1134*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1135*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1136*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,
1137*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1138*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1139*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1140*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1141*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1142*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1143*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1144*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1145*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1146*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0 },
1147*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1148*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1149*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0 },
1150*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1151*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1152*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0 },
1153*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1154*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1155*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0 },
1156*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1157*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1158*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0 },
1159*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1160*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1161*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0 },
1162*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1163*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1164*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0 },
1165*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1166*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1167*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0 },
1168*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1169*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1170*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
1171*77c1e3ccSAndroid Build Coastguard Worker };
1172*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z1_HxW_internal_neon_64(int H,int W,uint8x8_t * dst,const uint8_t * above,int upsample_above,int dx)1173*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE void dr_prediction_z1_HxW_internal_neon_64(
1174*77c1e3ccSAndroid Build Coastguard Worker int H, int W, uint8x8_t *dst, const uint8_t *above, int upsample_above,
1175*77c1e3ccSAndroid Build Coastguard Worker int dx) {
1176*77c1e3ccSAndroid Build Coastguard Worker const int frac_bits = 6 - upsample_above;
1177*77c1e3ccSAndroid Build Coastguard Worker const int max_base_x = ((W + H) - 1) << upsample_above;
1178*77c1e3ccSAndroid Build Coastguard Worker
1179*77c1e3ccSAndroid Build Coastguard Worker assert(dx > 0);
1180*77c1e3ccSAndroid Build Coastguard Worker // pre-filter above pixels
1181*77c1e3ccSAndroid Build Coastguard Worker // store in temp buffers:
1182*77c1e3ccSAndroid Build Coastguard Worker // above[x] * 32 + 16
1183*77c1e3ccSAndroid Build Coastguard Worker // above[x+1] - above[x]
1184*77c1e3ccSAndroid Build Coastguard Worker // final pixels will be calculated as:
1185*77c1e3ccSAndroid Build Coastguard Worker // (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1186*77c1e3ccSAndroid Build Coastguard Worker
1187*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t a_mbase_x = vdup_n_u8(above[max_base_x]);
1188*77c1e3ccSAndroid Build Coastguard Worker
1189*77c1e3ccSAndroid Build Coastguard Worker int x = dx;
1190*77c1e3ccSAndroid Build Coastguard Worker for (int r = 0; r < W; r++) {
1191*77c1e3ccSAndroid Build Coastguard Worker int base = x >> frac_bits;
1192*77c1e3ccSAndroid Build Coastguard Worker int base_max_diff = (max_base_x - base) >> upsample_above;
1193*77c1e3ccSAndroid Build Coastguard Worker if (base_max_diff <= 0) {
1194*77c1e3ccSAndroid Build Coastguard Worker for (int i = r; i < W; ++i) {
1195*77c1e3ccSAndroid Build Coastguard Worker dst[i] = a_mbase_x; // save 4 values
1196*77c1e3ccSAndroid Build Coastguard Worker }
1197*77c1e3ccSAndroid Build Coastguard Worker return;
1198*77c1e3ccSAndroid Build Coastguard Worker }
1199*77c1e3ccSAndroid Build Coastguard Worker
1200*77c1e3ccSAndroid Build Coastguard Worker if (base_max_diff > H) base_max_diff = H;
1201*77c1e3ccSAndroid Build Coastguard Worker
1202*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t a01_128;
1203*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t shift;
1204*77c1e3ccSAndroid Build Coastguard Worker if (upsample_above) {
1205*77c1e3ccSAndroid Build Coastguard Worker a01_128 = vld2_u8(above + base);
1206*77c1e3ccSAndroid Build Coastguard Worker shift = vdupq_n_u16(((x << upsample_above) & 0x3f) >> 1);
1207*77c1e3ccSAndroid Build Coastguard Worker } else {
1208*77c1e3ccSAndroid Build Coastguard Worker a01_128.val[0] = vld1_u8(above + base);
1209*77c1e3ccSAndroid Build Coastguard Worker a01_128.val[1] = vld1_u8(above + base + 1);
1210*77c1e3ccSAndroid Build Coastguard Worker shift = vdupq_n_u16((x & 0x3f) >> 1);
1211*77c1e3ccSAndroid Build Coastguard Worker }
1212*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff = vsubl_u8(a01_128.val[1], a01_128.val[0]);
1213*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32 = vmlal_u8(vdupq_n_u16(16), a01_128.val[0], vdup_n_u8(32));
1214*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res = vmlaq_u16(a32, diff, shift);
1215*77c1e3ccSAndroid Build Coastguard Worker
1216*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t mask = vld1_u8(BaseMask[base_max_diff]);
1217*77c1e3ccSAndroid Build Coastguard Worker dst[r] = vbsl_u8(mask, vshrn_n_u16(res, 5), a_mbase_x);
1218*77c1e3ccSAndroid Build Coastguard Worker
1219*77c1e3ccSAndroid Build Coastguard Worker x += dx;
1220*77c1e3ccSAndroid Build Coastguard Worker }
1221*77c1e3ccSAndroid Build Coastguard Worker }
1222*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z1_4xN_neon(int N,uint8_t * dst,ptrdiff_t stride,const uint8_t * above,int upsample_above,int dx)1223*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z1_4xN_neon(int N, uint8_t *dst, ptrdiff_t stride,
1224*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, int upsample_above,
1225*77c1e3ccSAndroid Build Coastguard Worker int dx) {
1226*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t dstvec[16];
1227*77c1e3ccSAndroid Build Coastguard Worker
1228*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon_64(4, N, dstvec, above, upsample_above,
1229*77c1e3ccSAndroid Build Coastguard Worker dx);
1230*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < N; i++) {
1231*77c1e3ccSAndroid Build Coastguard Worker vst1_lane_u32((uint32_t *)(dst + stride * i),
1232*77c1e3ccSAndroid Build Coastguard Worker vreinterpret_u32_u8(dstvec[i]), 0);
1233*77c1e3ccSAndroid Build Coastguard Worker }
1234*77c1e3ccSAndroid Build Coastguard Worker }
1235*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z1_8xN_neon(int N,uint8_t * dst,ptrdiff_t stride,const uint8_t * above,int upsample_above,int dx)1236*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z1_8xN_neon(int N, uint8_t *dst, ptrdiff_t stride,
1237*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, int upsample_above,
1238*77c1e3ccSAndroid Build Coastguard Worker int dx) {
1239*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t dstvec[32];
1240*77c1e3ccSAndroid Build Coastguard Worker
1241*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon_64(8, N, dstvec, above, upsample_above,
1242*77c1e3ccSAndroid Build Coastguard Worker dx);
1243*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < N; i++) {
1244*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + stride * i, dstvec[i]);
1245*77c1e3ccSAndroid Build Coastguard Worker }
1246*77c1e3ccSAndroid Build Coastguard Worker }
1247*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z1_HxW_internal_neon(int H,int W,uint8x16_t * dst,const uint8_t * above,int upsample_above,int dx)1248*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE void dr_prediction_z1_HxW_internal_neon(
1249*77c1e3ccSAndroid Build Coastguard Worker int H, int W, uint8x16_t *dst, const uint8_t *above, int upsample_above,
1250*77c1e3ccSAndroid Build Coastguard Worker int dx) {
1251*77c1e3ccSAndroid Build Coastguard Worker const int frac_bits = 6 - upsample_above;
1252*77c1e3ccSAndroid Build Coastguard Worker const int max_base_x = ((W + H) - 1) << upsample_above;
1253*77c1e3ccSAndroid Build Coastguard Worker
1254*77c1e3ccSAndroid Build Coastguard Worker assert(dx > 0);
1255*77c1e3ccSAndroid Build Coastguard Worker // pre-filter above pixels
1256*77c1e3ccSAndroid Build Coastguard Worker // store in temp buffers:
1257*77c1e3ccSAndroid Build Coastguard Worker // above[x] * 32 + 16
1258*77c1e3ccSAndroid Build Coastguard Worker // above[x+1] - above[x]
1259*77c1e3ccSAndroid Build Coastguard Worker // final pixels will be calculated as:
1260*77c1e3ccSAndroid Build Coastguard Worker // (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1261*77c1e3ccSAndroid Build Coastguard Worker
1262*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a_mbase_x = vdupq_n_u8(above[max_base_x]);
1263*77c1e3ccSAndroid Build Coastguard Worker
1264*77c1e3ccSAndroid Build Coastguard Worker int x = dx;
1265*77c1e3ccSAndroid Build Coastguard Worker for (int r = 0; r < W; r++) {
1266*77c1e3ccSAndroid Build Coastguard Worker int base = x >> frac_bits;
1267*77c1e3ccSAndroid Build Coastguard Worker int base_max_diff = (max_base_x - base) >> upsample_above;
1268*77c1e3ccSAndroid Build Coastguard Worker if (base_max_diff <= 0) {
1269*77c1e3ccSAndroid Build Coastguard Worker for (int i = r; i < W; ++i) {
1270*77c1e3ccSAndroid Build Coastguard Worker dst[i] = a_mbase_x; // save 4 values
1271*77c1e3ccSAndroid Build Coastguard Worker }
1272*77c1e3ccSAndroid Build Coastguard Worker return;
1273*77c1e3ccSAndroid Build Coastguard Worker }
1274*77c1e3ccSAndroid Build Coastguard Worker
1275*77c1e3ccSAndroid Build Coastguard Worker if (base_max_diff > H) base_max_diff = H;
1276*77c1e3ccSAndroid Build Coastguard Worker
1277*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t shift;
1278*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a0_128, a1_128;
1279*77c1e3ccSAndroid Build Coastguard Worker if (upsample_above) {
1280*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t v_tmp_a0_128 = vld2_u8(above + base);
1281*77c1e3ccSAndroid Build Coastguard Worker a0_128 = vcombine_u8(v_tmp_a0_128.val[0], v_tmp_a0_128.val[1]);
1282*77c1e3ccSAndroid Build Coastguard Worker a1_128 = vextq_u8(a0_128, vdupq_n_u8(0), 8);
1283*77c1e3ccSAndroid Build Coastguard Worker shift = vdupq_n_u16(x & 0x1f);
1284*77c1e3ccSAndroid Build Coastguard Worker } else {
1285*77c1e3ccSAndroid Build Coastguard Worker a0_128 = vld1q_u8(above + base);
1286*77c1e3ccSAndroid Build Coastguard Worker a1_128 = vld1q_u8(above + base + 1);
1287*77c1e3ccSAndroid Build Coastguard Worker shift = vdupq_n_u16((x & 0x3f) >> 1);
1288*77c1e3ccSAndroid Build Coastguard Worker }
1289*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff_lo = vsubl_u8(vget_low_u8(a1_128), vget_low_u8(a0_128));
1290*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff_hi = vsubl_u8(vget_high_u8(a1_128), vget_high_u8(a0_128));
1291*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32_lo =
1292*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(vdupq_n_u16(16), vget_low_u8(a0_128), vdup_n_u8(32));
1293*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32_hi =
1294*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(vdupq_n_u16(16), vget_high_u8(a0_128), vdup_n_u8(32));
1295*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res_lo = vmlaq_u16(a32_lo, diff_lo, shift);
1296*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res_hi = vmlaq_u16(a32_hi, diff_hi, shift);
1297*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t v_temp =
1298*77c1e3ccSAndroid Build Coastguard Worker vcombine_u8(vshrn_n_u16(res_lo, 5), vshrn_n_u16(res_hi, 5));
1299*77c1e3ccSAndroid Build Coastguard Worker
1300*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t mask = vld1q_u8(BaseMask[base_max_diff]);
1301*77c1e3ccSAndroid Build Coastguard Worker dst[r] = vbslq_u8(mask, v_temp, a_mbase_x);
1302*77c1e3ccSAndroid Build Coastguard Worker
1303*77c1e3ccSAndroid Build Coastguard Worker x += dx;
1304*77c1e3ccSAndroid Build Coastguard Worker }
1305*77c1e3ccSAndroid Build Coastguard Worker }
1306*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z1_16xN_neon(int N,uint8_t * dst,ptrdiff_t stride,const uint8_t * above,int upsample_above,int dx)1307*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z1_16xN_neon(int N, uint8_t *dst, ptrdiff_t stride,
1308*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, int upsample_above,
1309*77c1e3ccSAndroid Build Coastguard Worker int dx) {
1310*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t dstvec[64];
1311*77c1e3ccSAndroid Build Coastguard Worker
1312*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon(16, N, dstvec, above, upsample_above, dx);
1313*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < N; i++) {
1314*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + stride * i, dstvec[i]);
1315*77c1e3ccSAndroid Build Coastguard Worker }
1316*77c1e3ccSAndroid Build Coastguard Worker }
1317*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z1_32xN_internal_neon(int N,uint8x16x2_t * dstvec,const uint8_t * above,int dx)1318*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE void dr_prediction_z1_32xN_internal_neon(
1319*77c1e3ccSAndroid Build Coastguard Worker int N, uint8x16x2_t *dstvec, const uint8_t *above, int dx) {
1320*77c1e3ccSAndroid Build Coastguard Worker const int frac_bits = 6;
1321*77c1e3ccSAndroid Build Coastguard Worker const int max_base_x = ((32 + N) - 1);
1322*77c1e3ccSAndroid Build Coastguard Worker
1323*77c1e3ccSAndroid Build Coastguard Worker // pre-filter above pixels
1324*77c1e3ccSAndroid Build Coastguard Worker // store in temp buffers:
1325*77c1e3ccSAndroid Build Coastguard Worker // above[x] * 32 + 16
1326*77c1e3ccSAndroid Build Coastguard Worker // above[x+1] - above[x]
1327*77c1e3ccSAndroid Build Coastguard Worker // final pixels will be calculated as:
1328*77c1e3ccSAndroid Build Coastguard Worker // (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1329*77c1e3ccSAndroid Build Coastguard Worker
1330*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a_mbase_x = vdupq_n_u8(above[max_base_x]);
1331*77c1e3ccSAndroid Build Coastguard Worker
1332*77c1e3ccSAndroid Build Coastguard Worker int x = dx;
1333*77c1e3ccSAndroid Build Coastguard Worker for (int r = 0; r < N; r++) {
1334*77c1e3ccSAndroid Build Coastguard Worker int base = x >> frac_bits;
1335*77c1e3ccSAndroid Build Coastguard Worker int base_max_diff = (max_base_x - base);
1336*77c1e3ccSAndroid Build Coastguard Worker if (base_max_diff <= 0) {
1337*77c1e3ccSAndroid Build Coastguard Worker for (int i = r; i < N; ++i) {
1338*77c1e3ccSAndroid Build Coastguard Worker dstvec[i].val[0] = a_mbase_x; // save 32 values
1339*77c1e3ccSAndroid Build Coastguard Worker dstvec[i].val[1] = a_mbase_x;
1340*77c1e3ccSAndroid Build Coastguard Worker }
1341*77c1e3ccSAndroid Build Coastguard Worker return;
1342*77c1e3ccSAndroid Build Coastguard Worker }
1343*77c1e3ccSAndroid Build Coastguard Worker if (base_max_diff > 32) base_max_diff = 32;
1344*77c1e3ccSAndroid Build Coastguard Worker
1345*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t shift = vdupq_n_u16((x & 0x3f) >> 1);
1346*77c1e3ccSAndroid Build Coastguard Worker
1347*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t res16[2];
1348*77c1e3ccSAndroid Build Coastguard Worker for (int j = 0, jj = 0; j < 32; j += 16, jj++) {
1349*77c1e3ccSAndroid Build Coastguard Worker int mdiff = base_max_diff - j;
1350*77c1e3ccSAndroid Build Coastguard Worker if (mdiff <= 0) {
1351*77c1e3ccSAndroid Build Coastguard Worker res16[jj] = a_mbase_x;
1352*77c1e3ccSAndroid Build Coastguard Worker } else {
1353*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a0_128 = vld1q_u8(above + base + j);
1354*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a1_128 = vld1q_u8(above + base + j + 1);
1355*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff_lo = vsubl_u8(vget_low_u8(a1_128), vget_low_u8(a0_128));
1356*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff_hi =
1357*77c1e3ccSAndroid Build Coastguard Worker vsubl_u8(vget_high_u8(a1_128), vget_high_u8(a0_128));
1358*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32_lo =
1359*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(vdupq_n_u16(16), vget_low_u8(a0_128), vdup_n_u8(32));
1360*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32_hi =
1361*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(vdupq_n_u16(16), vget_high_u8(a0_128), vdup_n_u8(32));
1362*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res_lo = vmlaq_u16(a32_lo, diff_lo, shift);
1363*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res_hi = vmlaq_u16(a32_hi, diff_hi, shift);
1364*77c1e3ccSAndroid Build Coastguard Worker
1365*77c1e3ccSAndroid Build Coastguard Worker res16[jj] = vcombine_u8(vshrn_n_u16(res_lo, 5), vshrn_n_u16(res_hi, 5));
1366*77c1e3ccSAndroid Build Coastguard Worker }
1367*77c1e3ccSAndroid Build Coastguard Worker }
1368*77c1e3ccSAndroid Build Coastguard Worker
1369*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t mask_lo = vld1q_u8(BaseMask[base_max_diff]);
1370*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t mask_hi = vld1q_u8(BaseMask[base_max_diff] + 16);
1371*77c1e3ccSAndroid Build Coastguard Worker dstvec[r].val[0] = vbslq_u8(mask_lo, res16[0], a_mbase_x);
1372*77c1e3ccSAndroid Build Coastguard Worker dstvec[r].val[1] = vbslq_u8(mask_hi, res16[1], a_mbase_x);
1373*77c1e3ccSAndroid Build Coastguard Worker x += dx;
1374*77c1e3ccSAndroid Build Coastguard Worker }
1375*77c1e3ccSAndroid Build Coastguard Worker }
1376*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z1_32xN_neon(int N,uint8_t * dst,ptrdiff_t stride,const uint8_t * above,int dx)1377*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z1_32xN_neon(int N, uint8_t *dst, ptrdiff_t stride,
1378*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, int dx) {
1379*77c1e3ccSAndroid Build Coastguard Worker uint8x16x2_t dstvec[64];
1380*77c1e3ccSAndroid Build Coastguard Worker
1381*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_32xN_internal_neon(N, dstvec, above, dx);
1382*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < N; i++) {
1383*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + stride * i, dstvec[i].val[0]);
1384*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + stride * i + 16, dstvec[i].val[1]);
1385*77c1e3ccSAndroid Build Coastguard Worker }
1386*77c1e3ccSAndroid Build Coastguard Worker }
1387*77c1e3ccSAndroid Build Coastguard Worker
1388*77c1e3ccSAndroid Build Coastguard Worker // clang-format off
1389*77c1e3ccSAndroid Build Coastguard Worker static const uint8_t kLoadMaxShuffles[] = {
1390*77c1e3ccSAndroid Build Coastguard Worker 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
1391*77c1e3ccSAndroid Build Coastguard Worker 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
1392*77c1e3ccSAndroid Build Coastguard Worker 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
1393*77c1e3ccSAndroid Build Coastguard Worker 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
1394*77c1e3ccSAndroid Build Coastguard Worker 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
1395*77c1e3ccSAndroid Build Coastguard Worker 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
1396*77c1e3ccSAndroid Build Coastguard Worker 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
1397*77c1e3ccSAndroid Build Coastguard Worker 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15,
1398*77c1e3ccSAndroid Build Coastguard Worker 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15,
1399*77c1e3ccSAndroid Build Coastguard Worker 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15,
1400*77c1e3ccSAndroid Build Coastguard Worker 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15,
1401*77c1e3ccSAndroid Build Coastguard Worker 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15,
1402*77c1e3ccSAndroid Build Coastguard Worker 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15,
1403*77c1e3ccSAndroid Build Coastguard Worker 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15,
1404*77c1e3ccSAndroid Build Coastguard Worker 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15,
1405*77c1e3ccSAndroid Build Coastguard Worker 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1406*77c1e3ccSAndroid Build Coastguard Worker };
1407*77c1e3ccSAndroid Build Coastguard Worker // clang-format on
1408*77c1e3ccSAndroid Build Coastguard Worker
z1_load_masked_neon(const uint8_t * ptr,int shuffle_idx)1409*77c1e3ccSAndroid Build Coastguard Worker static inline uint8x16_t z1_load_masked_neon(const uint8_t *ptr,
1410*77c1e3ccSAndroid Build Coastguard Worker int shuffle_idx) {
1411*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t shuffle = vld1q_u8(&kLoadMaxShuffles[16 * shuffle_idx]);
1412*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t src = vld1q_u8(ptr);
1413*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_AARCH64
1414*77c1e3ccSAndroid Build Coastguard Worker return vqtbl1q_u8(src, shuffle);
1415*77c1e3ccSAndroid Build Coastguard Worker #else
1416*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t src2 = { { vget_low_u8(src), vget_high_u8(src) } };
1417*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t lo = vtbl2_u8(src2, vget_low_u8(shuffle));
1418*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t hi = vtbl2_u8(src2, vget_high_u8(shuffle));
1419*77c1e3ccSAndroid Build Coastguard Worker return vcombine_u8(lo, hi);
1420*77c1e3ccSAndroid Build Coastguard Worker #endif
1421*77c1e3ccSAndroid Build Coastguard Worker }
1422*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z1_64xN_neon(int N,uint8_t * dst,ptrdiff_t stride,const uint8_t * above,int dx)1423*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z1_64xN_neon(int N, uint8_t *dst, ptrdiff_t stride,
1424*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, int dx) {
1425*77c1e3ccSAndroid Build Coastguard Worker const int frac_bits = 6;
1426*77c1e3ccSAndroid Build Coastguard Worker const int max_base_x = ((64 + N) - 1);
1427*77c1e3ccSAndroid Build Coastguard Worker
1428*77c1e3ccSAndroid Build Coastguard Worker // pre-filter above pixels
1429*77c1e3ccSAndroid Build Coastguard Worker // store in temp buffers:
1430*77c1e3ccSAndroid Build Coastguard Worker // above[x] * 32 + 16
1431*77c1e3ccSAndroid Build Coastguard Worker // above[x+1] - above[x]
1432*77c1e3ccSAndroid Build Coastguard Worker // final pixels will be calculated as:
1433*77c1e3ccSAndroid Build Coastguard Worker // (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1434*77c1e3ccSAndroid Build Coastguard Worker
1435*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a_mbase_x = vdupq_n_u8(above[max_base_x]);
1436*77c1e3ccSAndroid Build Coastguard Worker
1437*77c1e3ccSAndroid Build Coastguard Worker int x = dx;
1438*77c1e3ccSAndroid Build Coastguard Worker for (int r = 0; r < N; r++, dst += stride) {
1439*77c1e3ccSAndroid Build Coastguard Worker int base = x >> frac_bits;
1440*77c1e3ccSAndroid Build Coastguard Worker if (base >= max_base_x) {
1441*77c1e3ccSAndroid Build Coastguard Worker for (int i = r; i < N; ++i) {
1442*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst, a_mbase_x);
1443*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, a_mbase_x);
1444*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, a_mbase_x);
1445*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, a_mbase_x);
1446*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
1447*77c1e3ccSAndroid Build Coastguard Worker }
1448*77c1e3ccSAndroid Build Coastguard Worker return;
1449*77c1e3ccSAndroid Build Coastguard Worker }
1450*77c1e3ccSAndroid Build Coastguard Worker
1451*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t shift = vdupq_n_u16((x & 0x3f) >> 1);
1452*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t base_inc128 =
1453*77c1e3ccSAndroid Build Coastguard Worker vaddq_u8(vdupq_n_u8(base), vcombine_u8(vcreate_u8(0x0706050403020100),
1454*77c1e3ccSAndroid Build Coastguard Worker vcreate_u8(0x0F0E0D0C0B0A0908)));
1455*77c1e3ccSAndroid Build Coastguard Worker
1456*77c1e3ccSAndroid Build Coastguard Worker for (int j = 0; j < 64; j += 16) {
1457*77c1e3ccSAndroid Build Coastguard Worker if (base + j >= max_base_x) {
1458*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + j, a_mbase_x);
1459*77c1e3ccSAndroid Build Coastguard Worker } else {
1460*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a0_128;
1461*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a1_128;
1462*77c1e3ccSAndroid Build Coastguard Worker if (base + j + 15 >= max_base_x) {
1463*77c1e3ccSAndroid Build Coastguard Worker int shuffle_idx = max_base_x - base - j;
1464*77c1e3ccSAndroid Build Coastguard Worker a0_128 = z1_load_masked_neon(above + (max_base_x - 15), shuffle_idx);
1465*77c1e3ccSAndroid Build Coastguard Worker } else {
1466*77c1e3ccSAndroid Build Coastguard Worker a0_128 = vld1q_u8(above + base + j);
1467*77c1e3ccSAndroid Build Coastguard Worker }
1468*77c1e3ccSAndroid Build Coastguard Worker if (base + j + 16 >= max_base_x) {
1469*77c1e3ccSAndroid Build Coastguard Worker int shuffle_idx = max_base_x - base - j - 1;
1470*77c1e3ccSAndroid Build Coastguard Worker a1_128 = z1_load_masked_neon(above + (max_base_x - 15), shuffle_idx);
1471*77c1e3ccSAndroid Build Coastguard Worker } else {
1472*77c1e3ccSAndroid Build Coastguard Worker a1_128 = vld1q_u8(above + base + j + 1);
1473*77c1e3ccSAndroid Build Coastguard Worker }
1474*77c1e3ccSAndroid Build Coastguard Worker
1475*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff_lo = vsubl_u8(vget_low_u8(a1_128), vget_low_u8(a0_128));
1476*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff_hi =
1477*77c1e3ccSAndroid Build Coastguard Worker vsubl_u8(vget_high_u8(a1_128), vget_high_u8(a0_128));
1478*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32_lo =
1479*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(vdupq_n_u16(16), vget_low_u8(a0_128), vdup_n_u8(32));
1480*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32_hi =
1481*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(vdupq_n_u16(16), vget_high_u8(a0_128), vdup_n_u8(32));
1482*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res_lo = vmlaq_u16(a32_lo, diff_lo, shift);
1483*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res_hi = vmlaq_u16(a32_hi, diff_hi, shift);
1484*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + j,
1485*77c1e3ccSAndroid Build Coastguard Worker vcombine_u8(vshrn_n_u16(res_lo, 5), vshrn_n_u16(res_hi, 5)));
1486*77c1e3ccSAndroid Build Coastguard Worker
1487*77c1e3ccSAndroid Build Coastguard Worker base_inc128 = vaddq_u8(base_inc128, vdupq_n_u8(16));
1488*77c1e3ccSAndroid Build Coastguard Worker }
1489*77c1e3ccSAndroid Build Coastguard Worker }
1490*77c1e3ccSAndroid Build Coastguard Worker x += dx;
1491*77c1e3ccSAndroid Build Coastguard Worker }
1492*77c1e3ccSAndroid Build Coastguard Worker }
1493*77c1e3ccSAndroid Build Coastguard Worker
1494*77c1e3ccSAndroid Build Coastguard Worker // Directional prediction, zone 1: 0 < angle < 90
av1_dr_prediction_z1_neon(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left,int upsample_above,int dx,int dy)1495*77c1e3ccSAndroid Build Coastguard Worker void av1_dr_prediction_z1_neon(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
1496*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left,
1497*77c1e3ccSAndroid Build Coastguard Worker int upsample_above, int dx, int dy) {
1498*77c1e3ccSAndroid Build Coastguard Worker (void)left;
1499*77c1e3ccSAndroid Build Coastguard Worker (void)dy;
1500*77c1e3ccSAndroid Build Coastguard Worker
1501*77c1e3ccSAndroid Build Coastguard Worker switch (bw) {
1502*77c1e3ccSAndroid Build Coastguard Worker case 4:
1503*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_4xN_neon(bh, dst, stride, above, upsample_above, dx);
1504*77c1e3ccSAndroid Build Coastguard Worker break;
1505*77c1e3ccSAndroid Build Coastguard Worker case 8:
1506*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_8xN_neon(bh, dst, stride, above, upsample_above, dx);
1507*77c1e3ccSAndroid Build Coastguard Worker break;
1508*77c1e3ccSAndroid Build Coastguard Worker case 16:
1509*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_16xN_neon(bh, dst, stride, above, upsample_above, dx);
1510*77c1e3ccSAndroid Build Coastguard Worker break;
1511*77c1e3ccSAndroid Build Coastguard Worker case 32: dr_prediction_z1_32xN_neon(bh, dst, stride, above, dx); break;
1512*77c1e3ccSAndroid Build Coastguard Worker case 64: dr_prediction_z1_64xN_neon(bh, dst, stride, above, dx); break;
1513*77c1e3ccSAndroid Build Coastguard Worker default: break;
1514*77c1e3ccSAndroid Build Coastguard Worker }
1515*77c1e3ccSAndroid Build Coastguard Worker }
1516*77c1e3ccSAndroid Build Coastguard Worker
1517*77c1e3ccSAndroid Build Coastguard Worker /* ---------------------P R E D I C T I O N Z 2--------------------------- */
1518*77c1e3ccSAndroid Build Coastguard Worker
1519*77c1e3ccSAndroid Build Coastguard Worker // TODO(aomedia:349428506): enable this for armv7 after SIGBUS is fixed.
1520*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_AARCH64
1521*77c1e3ccSAndroid Build Coastguard Worker #if !AOM_ARCH_AARCH64
1522*77c1e3ccSAndroid Build Coastguard Worker static DECLARE_ALIGNED(16, const uint8_t, LoadMaskz2[4][16]) = {
1523*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
1524*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0 },
1525*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,
1526*77c1e3ccSAndroid Build Coastguard Worker 0, 0, 0 },
1527*77c1e3ccSAndroid Build Coastguard Worker { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1528*77c1e3ccSAndroid Build Coastguard Worker 0xff, 0xff, 0xff, 0xff }
1529*77c1e3ccSAndroid Build Coastguard Worker };
1530*77c1e3ccSAndroid Build Coastguard Worker #endif // !AOM_ARCH_AARCH64
1531*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z2_Nx4_above_neon(const uint8_t * above,int upsample_above,int dx,int base_x,int y,uint8x8_t * a0_x,uint8x8_t * a1_x,uint16x4_t * shift0)1532*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE void dr_prediction_z2_Nx4_above_neon(
1533*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, int upsample_above, int dx, int base_x, int y,
1534*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t *a0_x, uint8x8_t *a1_x, uint16x4_t *shift0) {
1535*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t r6 = vcreate_u16(0x00C0008000400000);
1536*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t ydx = vdup_n_u16(y * dx);
1537*77c1e3ccSAndroid Build Coastguard Worker if (upsample_above) {
1538*77c1e3ccSAndroid Build Coastguard Worker // Cannot use LD2 here since we only want to load eight bytes, but LD2 can
1539*77c1e3ccSAndroid Build Coastguard Worker // only load either 16 or 32.
1540*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t v_tmp = vld1_u8(above + base_x);
1541*77c1e3ccSAndroid Build Coastguard Worker *a0_x = vuzp_u8(v_tmp, vdup_n_u8(0)).val[0];
1542*77c1e3ccSAndroid Build Coastguard Worker *a1_x = vuzp_u8(v_tmp, vdup_n_u8(0)).val[1];
1543*77c1e3ccSAndroid Build Coastguard Worker *shift0 = vand_u16(vsub_u16(r6, ydx), vdup_n_u16(0x1f));
1544*77c1e3ccSAndroid Build Coastguard Worker } else {
1545*77c1e3ccSAndroid Build Coastguard Worker *a0_x = load_unaligned_u8_4x1(above + base_x);
1546*77c1e3ccSAndroid Build Coastguard Worker *a1_x = load_unaligned_u8_4x1(above + base_x + 1);
1547*77c1e3ccSAndroid Build Coastguard Worker *shift0 = vand_u16(vhsub_u16(r6, ydx), vdup_n_u16(0x1f));
1548*77c1e3ccSAndroid Build Coastguard Worker }
1549*77c1e3ccSAndroid Build Coastguard Worker }
1550*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z2_Nx4_left_neon(uint8x16x2_t left_vals,int upsample_left,int dy,int r,int min_base_y,int frac_bits_y,uint16x4_t * a0_y,uint16x4_t * a1_y,uint16x4_t * shift1)1551*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE void dr_prediction_z2_Nx4_left_neon(
1552*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_AARCH64
1553*77c1e3ccSAndroid Build Coastguard Worker uint8x16x2_t left_vals,
1554*77c1e3ccSAndroid Build Coastguard Worker #else
1555*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left,
1556*77c1e3ccSAndroid Build Coastguard Worker #endif
1557*77c1e3ccSAndroid Build Coastguard Worker int upsample_left, int dy, int r, int min_base_y, int frac_bits_y,
1558*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t *a0_y, uint16x4_t *a1_y, uint16x4_t *shift1) {
1559*77c1e3ccSAndroid Build Coastguard Worker int16x4_t dy64 = vdup_n_s16(dy);
1560*77c1e3ccSAndroid Build Coastguard Worker int16x4_t v_1234 = vcreate_s16(0x0004000300020001);
1561*77c1e3ccSAndroid Build Coastguard Worker int16x4_t v_frac_bits_y = vdup_n_s16(-frac_bits_y);
1562*77c1e3ccSAndroid Build Coastguard Worker int16x4_t min_base_y64 = vdup_n_s16(min_base_y);
1563*77c1e3ccSAndroid Build Coastguard Worker int16x4_t v_r6 = vdup_n_s16(r << 6);
1564*77c1e3ccSAndroid Build Coastguard Worker int16x4_t y_c64 = vmls_s16(v_r6, v_1234, dy64);
1565*77c1e3ccSAndroid Build Coastguard Worker int16x4_t base_y_c64 = vshl_s16(y_c64, v_frac_bits_y);
1566*77c1e3ccSAndroid Build Coastguard Worker
1567*77c1e3ccSAndroid Build Coastguard Worker // Values in base_y_c64 range from -2 through 14 inclusive.
1568*77c1e3ccSAndroid Build Coastguard Worker base_y_c64 = vmax_s16(base_y_c64, min_base_y64);
1569*77c1e3ccSAndroid Build Coastguard Worker
1570*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_AARCH64
1571*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t left_idx0 =
1572*77c1e3ccSAndroid Build Coastguard Worker vreinterpret_u8_s16(vadd_s16(base_y_c64, vdup_n_s16(2))); // [0, 16]
1573*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t left_idx1 =
1574*77c1e3ccSAndroid Build Coastguard Worker vreinterpret_u8_s16(vadd_s16(base_y_c64, vdup_n_s16(3))); // [1, 17]
1575*77c1e3ccSAndroid Build Coastguard Worker
1576*77c1e3ccSAndroid Build Coastguard Worker *a0_y = vreinterpret_u16_u8(vqtbl2_u8(left_vals, left_idx0));
1577*77c1e3ccSAndroid Build Coastguard Worker *a1_y = vreinterpret_u16_u8(vqtbl2_u8(left_vals, left_idx1));
1578*77c1e3ccSAndroid Build Coastguard Worker #else // !AOM_ARCH_AARCH64
1579*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(32, int16_t, base_y_c[4]);
1580*77c1e3ccSAndroid Build Coastguard Worker
1581*77c1e3ccSAndroid Build Coastguard Worker vst1_s16(base_y_c, base_y_c64);
1582*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a0_y_u8 = vdup_n_u8(0);
1583*77c1e3ccSAndroid Build Coastguard Worker a0_y_u8 = vld1_lane_u8(left + base_y_c[0], a0_y_u8, 0);
1584*77c1e3ccSAndroid Build Coastguard Worker a0_y_u8 = vld1_lane_u8(left + base_y_c[1], a0_y_u8, 2);
1585*77c1e3ccSAndroid Build Coastguard Worker a0_y_u8 = vld1_lane_u8(left + base_y_c[2], a0_y_u8, 4);
1586*77c1e3ccSAndroid Build Coastguard Worker a0_y_u8 = vld1_lane_u8(left + base_y_c[3], a0_y_u8, 6);
1587*77c1e3ccSAndroid Build Coastguard Worker
1588*77c1e3ccSAndroid Build Coastguard Worker base_y_c64 = vadd_s16(base_y_c64, vdup_n_s16(1));
1589*77c1e3ccSAndroid Build Coastguard Worker vst1_s16(base_y_c, base_y_c64);
1590*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a1_y_u8 = vdup_n_u8(0);
1591*77c1e3ccSAndroid Build Coastguard Worker a1_y_u8 = vld1_lane_u8(left + base_y_c[0], a1_y_u8, 0);
1592*77c1e3ccSAndroid Build Coastguard Worker a1_y_u8 = vld1_lane_u8(left + base_y_c[1], a1_y_u8, 2);
1593*77c1e3ccSAndroid Build Coastguard Worker a1_y_u8 = vld1_lane_u8(left + base_y_c[2], a1_y_u8, 4);
1594*77c1e3ccSAndroid Build Coastguard Worker a1_y_u8 = vld1_lane_u8(left + base_y_c[3], a1_y_u8, 6);
1595*77c1e3ccSAndroid Build Coastguard Worker
1596*77c1e3ccSAndroid Build Coastguard Worker *a0_y = vreinterpret_u16_u8(a0_y_u8);
1597*77c1e3ccSAndroid Build Coastguard Worker *a1_y = vreinterpret_u16_u8(a1_y_u8);
1598*77c1e3ccSAndroid Build Coastguard Worker #endif // AOM_ARCH_AARCH64
1599*77c1e3ccSAndroid Build Coastguard Worker
1600*77c1e3ccSAndroid Build Coastguard Worker if (upsample_left) {
1601*77c1e3ccSAndroid Build Coastguard Worker *shift1 = vand_u16(vreinterpret_u16_s16(y_c64), vdup_n_u16(0x1f));
1602*77c1e3ccSAndroid Build Coastguard Worker } else {
1603*77c1e3ccSAndroid Build Coastguard Worker *shift1 =
1604*77c1e3ccSAndroid Build Coastguard Worker vand_u16(vshr_n_u16(vreinterpret_u16_s16(y_c64), 1), vdup_n_u16(0x1f));
1605*77c1e3ccSAndroid Build Coastguard Worker }
1606*77c1e3ccSAndroid Build Coastguard Worker }
1607*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z2_Nx8_above_neon(const uint8_t * above,int upsample_above,int dx,int base_x,int y)1608*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE uint8x8_t dr_prediction_z2_Nx8_above_neon(
1609*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, int upsample_above, int dx, int base_x, int y) {
1610*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t c1234 = vcombine_u16(vcreate_u16(0x0004000300020001),
1611*77c1e3ccSAndroid Build Coastguard Worker vcreate_u16(0x0008000700060005));
1612*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t ydx = vdupq_n_u16(y * dx);
1613*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t r6 = vshlq_n_u16(vextq_u16(c1234, vdupq_n_u16(0), 2), 6);
1614*77c1e3ccSAndroid Build Coastguard Worker
1615*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t shift0;
1616*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a0_x0;
1617*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a1_x0;
1618*77c1e3ccSAndroid Build Coastguard Worker if (upsample_above) {
1619*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t v_tmp = vld2_u8(above + base_x);
1620*77c1e3ccSAndroid Build Coastguard Worker a0_x0 = v_tmp.val[0];
1621*77c1e3ccSAndroid Build Coastguard Worker a1_x0 = v_tmp.val[1];
1622*77c1e3ccSAndroid Build Coastguard Worker shift0 = vandq_u16(vsubq_u16(r6, ydx), vdupq_n_u16(0x1f));
1623*77c1e3ccSAndroid Build Coastguard Worker } else {
1624*77c1e3ccSAndroid Build Coastguard Worker a0_x0 = vld1_u8(above + base_x);
1625*77c1e3ccSAndroid Build Coastguard Worker a1_x0 = vld1_u8(above + base_x + 1);
1626*77c1e3ccSAndroid Build Coastguard Worker shift0 = vandq_u16(vhsubq_u16(r6, ydx), vdupq_n_u16(0x1f));
1627*77c1e3ccSAndroid Build Coastguard Worker }
1628*77c1e3ccSAndroid Build Coastguard Worker
1629*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff0 = vsubl_u8(a1_x0, a0_x0); // a[x+1] - a[x]
1630*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32 =
1631*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(vdupq_n_u16(16), a0_x0, vdup_n_u8(32)); // a[x] * 32 + 16
1632*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res = vmlaq_u16(a32, diff0, shift0);
1633*77c1e3ccSAndroid Build Coastguard Worker return vshrn_n_u16(res, 5);
1634*77c1e3ccSAndroid Build Coastguard Worker }
1635*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z2_Nx8_left_neon(uint8x16x3_t left_vals,int upsample_left,int dy,int r,int min_base_y,int frac_bits_y)1636*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE uint8x8_t dr_prediction_z2_Nx8_left_neon(
1637*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_AARCH64
1638*77c1e3ccSAndroid Build Coastguard Worker uint8x16x3_t left_vals,
1639*77c1e3ccSAndroid Build Coastguard Worker #else
1640*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left,
1641*77c1e3ccSAndroid Build Coastguard Worker #endif
1642*77c1e3ccSAndroid Build Coastguard Worker int upsample_left, int dy, int r, int min_base_y, int frac_bits_y) {
1643*77c1e3ccSAndroid Build Coastguard Worker int16x8_t v_r6 = vdupq_n_s16(r << 6);
1644*77c1e3ccSAndroid Build Coastguard Worker int16x8_t dy128 = vdupq_n_s16(dy);
1645*77c1e3ccSAndroid Build Coastguard Worker int16x8_t v_frac_bits_y = vdupq_n_s16(-frac_bits_y);
1646*77c1e3ccSAndroid Build Coastguard Worker int16x8_t min_base_y128 = vdupq_n_s16(min_base_y);
1647*77c1e3ccSAndroid Build Coastguard Worker
1648*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t c1234 = vcombine_u16(vcreate_u16(0x0004000300020001),
1649*77c1e3ccSAndroid Build Coastguard Worker vcreate_u16(0x0008000700060005));
1650*77c1e3ccSAndroid Build Coastguard Worker int16x8_t y_c128 = vmlsq_s16(v_r6, vreinterpretq_s16_u16(c1234), dy128);
1651*77c1e3ccSAndroid Build Coastguard Worker int16x8_t base_y_c128 = vshlq_s16(y_c128, v_frac_bits_y);
1652*77c1e3ccSAndroid Build Coastguard Worker
1653*77c1e3ccSAndroid Build Coastguard Worker // Values in base_y_c128 range from -2 through 31 inclusive.
1654*77c1e3ccSAndroid Build Coastguard Worker base_y_c128 = vmaxq_s16(base_y_c128, min_base_y128);
1655*77c1e3ccSAndroid Build Coastguard Worker
1656*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_AARCH64
1657*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t left_idx0 =
1658*77c1e3ccSAndroid Build Coastguard Worker vreinterpretq_u8_s16(vaddq_s16(base_y_c128, vdupq_n_s16(2))); // [0, 33]
1659*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t left_idx1 =
1660*77c1e3ccSAndroid Build Coastguard Worker vreinterpretq_u8_s16(vaddq_s16(base_y_c128, vdupq_n_s16(3))); // [1, 34]
1661*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t left_idx01 = vuzp1q_u8(left_idx0, left_idx1);
1662*77c1e3ccSAndroid Build Coastguard Worker
1663*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a01_x = vqtbl3q_u8(left_vals, left_idx01);
1664*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a0_x1 = vget_low_u8(a01_x);
1665*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a1_x1 = vget_high_u8(a01_x);
1666*77c1e3ccSAndroid Build Coastguard Worker #else // !AOM_ARCH_AARCH64
1667*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a0_x1 = load_u8_gather_s16_x8(left, base_y_c128);
1668*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a1_x1 = load_u8_gather_s16_x8(left + 1, base_y_c128);
1669*77c1e3ccSAndroid Build Coastguard Worker #endif // AOM_ARCH_AARCH64
1670*77c1e3ccSAndroid Build Coastguard Worker
1671*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t shift1;
1672*77c1e3ccSAndroid Build Coastguard Worker if (upsample_left) {
1673*77c1e3ccSAndroid Build Coastguard Worker shift1 = vandq_u16(vreinterpretq_u16_s16(y_c128), vdupq_n_u16(0x1f));
1674*77c1e3ccSAndroid Build Coastguard Worker } else {
1675*77c1e3ccSAndroid Build Coastguard Worker shift1 = vshrq_n_u16(
1676*77c1e3ccSAndroid Build Coastguard Worker vandq_u16(vreinterpretq_u16_s16(y_c128), vdupq_n_u16(0x3f)), 1);
1677*77c1e3ccSAndroid Build Coastguard Worker }
1678*77c1e3ccSAndroid Build Coastguard Worker
1679*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff1 = vsubl_u8(a1_x1, a0_x1);
1680*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32 = vmlal_u8(vdupq_n_u16(16), a0_x1, vdup_n_u8(32));
1681*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res = vmlaq_u16(a32, diff1, shift1);
1682*77c1e3ccSAndroid Build Coastguard Worker return vshrn_n_u16(res, 5);
1683*77c1e3ccSAndroid Build Coastguard Worker }
1684*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z2_NxW_above_neon(const uint8_t * above,int dx,int base_x,int y,int j)1685*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE uint8x16_t dr_prediction_z2_NxW_above_neon(
1686*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, int dx, int base_x, int y, int j) {
1687*77c1e3ccSAndroid Build Coastguard Worker uint16x8x2_t c0123 = { { vcombine_u16(vcreate_u16(0x0003000200010000),
1688*77c1e3ccSAndroid Build Coastguard Worker vcreate_u16(0x0007000600050004)),
1689*77c1e3ccSAndroid Build Coastguard Worker vcombine_u16(vcreate_u16(0x000B000A00090008),
1690*77c1e3ccSAndroid Build Coastguard Worker vcreate_u16(0x000F000E000D000C)) } };
1691*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t j256 = vdupq_n_u16(j);
1692*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t ydx = vdupq_n_u16((uint16_t)(y * dx));
1693*77c1e3ccSAndroid Build Coastguard Worker
1694*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a0_x128 = vld1q_u8(above + base_x + j);
1695*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t a1_x128 = vld1q_u8(above + base_x + j + 1);
1696*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res6_0 = vshlq_n_u16(vaddq_u16(c0123.val[0], j256), 6);
1697*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res6_1 = vshlq_n_u16(vaddq_u16(c0123.val[1], j256), 6);
1698*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t shift0 =
1699*77c1e3ccSAndroid Build Coastguard Worker vshrq_n_u16(vandq_u16(vsubq_u16(res6_0, ydx), vdupq_n_u16(0x3f)), 1);
1700*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t shift1 =
1701*77c1e3ccSAndroid Build Coastguard Worker vshrq_n_u16(vandq_u16(vsubq_u16(res6_1, ydx), vdupq_n_u16(0x3f)), 1);
1702*77c1e3ccSAndroid Build Coastguard Worker // a[x+1] - a[x]
1703*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff0 = vsubl_u8(vget_low_u8(a1_x128), vget_low_u8(a0_x128));
1704*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff1 = vsubl_u8(vget_high_u8(a1_x128), vget_high_u8(a0_x128));
1705*77c1e3ccSAndroid Build Coastguard Worker // a[x] * 32 + 16
1706*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32_0 =
1707*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(vdupq_n_u16(16), vget_low_u8(a0_x128), vdup_n_u8(32));
1708*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32_1 =
1709*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(vdupq_n_u16(16), vget_high_u8(a0_x128), vdup_n_u8(32));
1710*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res0 = vmlaq_u16(a32_0, diff0, shift0);
1711*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res1 = vmlaq_u16(a32_1, diff1, shift1);
1712*77c1e3ccSAndroid Build Coastguard Worker return vcombine_u8(vshrn_n_u16(res0, 5), vshrn_n_u16(res1, 5));
1713*77c1e3ccSAndroid Build Coastguard Worker }
1714*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z2_NxW_left_neon(uint8x16x4_t left_vals0,uint8x16x4_t left_vals1,int dy,int r,int j)1715*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE uint8x16_t dr_prediction_z2_NxW_left_neon(
1716*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_AARCH64
1717*77c1e3ccSAndroid Build Coastguard Worker uint8x16x4_t left_vals0, uint8x16x4_t left_vals1,
1718*77c1e3ccSAndroid Build Coastguard Worker #else
1719*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left,
1720*77c1e3ccSAndroid Build Coastguard Worker #endif
1721*77c1e3ccSAndroid Build Coastguard Worker int dy, int r, int j) {
1722*77c1e3ccSAndroid Build Coastguard Worker // here upsample_above and upsample_left are 0 by design of
1723*77c1e3ccSAndroid Build Coastguard Worker // av1_use_intra_edge_upsample
1724*77c1e3ccSAndroid Build Coastguard Worker const int min_base_y = -1;
1725*77c1e3ccSAndroid Build Coastguard Worker
1726*77c1e3ccSAndroid Build Coastguard Worker int16x8_t min_base_y256 = vdupq_n_s16(min_base_y);
1727*77c1e3ccSAndroid Build Coastguard Worker int16x8_t half_min_base_y256 = vdupq_n_s16(min_base_y >> 1);
1728*77c1e3ccSAndroid Build Coastguard Worker int16x8_t dy256 = vdupq_n_s16(dy);
1729*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t j256 = vdupq_n_u16(j);
1730*77c1e3ccSAndroid Build Coastguard Worker
1731*77c1e3ccSAndroid Build Coastguard Worker uint16x8x2_t c0123 = { { vcombine_u16(vcreate_u16(0x0003000200010000),
1732*77c1e3ccSAndroid Build Coastguard Worker vcreate_u16(0x0007000600050004)),
1733*77c1e3ccSAndroid Build Coastguard Worker vcombine_u16(vcreate_u16(0x000B000A00090008),
1734*77c1e3ccSAndroid Build Coastguard Worker vcreate_u16(0x000F000E000D000C)) } };
1735*77c1e3ccSAndroid Build Coastguard Worker uint16x8x2_t c1234 = { { vaddq_u16(c0123.val[0], vdupq_n_u16(1)),
1736*77c1e3ccSAndroid Build Coastguard Worker vaddq_u16(c0123.val[1], vdupq_n_u16(1)) } };
1737*77c1e3ccSAndroid Build Coastguard Worker
1738*77c1e3ccSAndroid Build Coastguard Worker int16x8_t v_r6 = vdupq_n_s16(r << 6);
1739*77c1e3ccSAndroid Build Coastguard Worker
1740*77c1e3ccSAndroid Build Coastguard Worker int16x8_t c256_0 = vreinterpretq_s16_u16(vaddq_u16(j256, c1234.val[0]));
1741*77c1e3ccSAndroid Build Coastguard Worker int16x8_t c256_1 = vreinterpretq_s16_u16(vaddq_u16(j256, c1234.val[1]));
1742*77c1e3ccSAndroid Build Coastguard Worker int16x8_t mul16_lo = vreinterpretq_s16_u16(
1743*77c1e3ccSAndroid Build Coastguard Worker vminq_u16(vreinterpretq_u16_s16(vmulq_s16(c256_0, dy256)),
1744*77c1e3ccSAndroid Build Coastguard Worker vreinterpretq_u16_s16(half_min_base_y256)));
1745*77c1e3ccSAndroid Build Coastguard Worker int16x8_t mul16_hi = vreinterpretq_s16_u16(
1746*77c1e3ccSAndroid Build Coastguard Worker vminq_u16(vreinterpretq_u16_s16(vmulq_s16(c256_1, dy256)),
1747*77c1e3ccSAndroid Build Coastguard Worker vreinterpretq_u16_s16(half_min_base_y256)));
1748*77c1e3ccSAndroid Build Coastguard Worker int16x8_t y_c256_lo = vsubq_s16(v_r6, mul16_lo);
1749*77c1e3ccSAndroid Build Coastguard Worker int16x8_t y_c256_hi = vsubq_s16(v_r6, mul16_hi);
1750*77c1e3ccSAndroid Build Coastguard Worker
1751*77c1e3ccSAndroid Build Coastguard Worker int16x8_t base_y_c256_lo = vshrq_n_s16(y_c256_lo, 6);
1752*77c1e3ccSAndroid Build Coastguard Worker int16x8_t base_y_c256_hi = vshrq_n_s16(y_c256_hi, 6);
1753*77c1e3ccSAndroid Build Coastguard Worker
1754*77c1e3ccSAndroid Build Coastguard Worker base_y_c256_lo = vmaxq_s16(min_base_y256, base_y_c256_lo);
1755*77c1e3ccSAndroid Build Coastguard Worker base_y_c256_hi = vmaxq_s16(min_base_y256, base_y_c256_hi);
1756*77c1e3ccSAndroid Build Coastguard Worker
1757*77c1e3ccSAndroid Build Coastguard Worker #if !AOM_ARCH_AARCH64
1758*77c1e3ccSAndroid Build Coastguard Worker int16_t min_y = vgetq_lane_s16(base_y_c256_hi, 7);
1759*77c1e3ccSAndroid Build Coastguard Worker int16_t max_y = vgetq_lane_s16(base_y_c256_lo, 0);
1760*77c1e3ccSAndroid Build Coastguard Worker int16_t offset_diff = max_y - min_y;
1761*77c1e3ccSAndroid Build Coastguard Worker
1762*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a0_y0;
1763*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a0_y1;
1764*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a1_y0;
1765*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a1_y1;
1766*77c1e3ccSAndroid Build Coastguard Worker if (offset_diff < 16) {
1767*77c1e3ccSAndroid Build Coastguard Worker // Avoid gathers where the data we want is close together in memory.
1768*77c1e3ccSAndroid Build Coastguard Worker // We don't need this for AArch64 since we can already use TBL to cover the
1769*77c1e3ccSAndroid Build Coastguard Worker // full range of possible values.
1770*77c1e3ccSAndroid Build Coastguard Worker assert(offset_diff >= 0);
1771*77c1e3ccSAndroid Build Coastguard Worker int16x8_t min_y256 = vdupq_lane_s16(vget_high_s16(base_y_c256_hi), 3);
1772*77c1e3ccSAndroid Build Coastguard Worker
1773*77c1e3ccSAndroid Build Coastguard Worker int16x8x2_t base_y_offset;
1774*77c1e3ccSAndroid Build Coastguard Worker base_y_offset.val[0] = vsubq_s16(base_y_c256_lo, min_y256);
1775*77c1e3ccSAndroid Build Coastguard Worker base_y_offset.val[1] = vsubq_s16(base_y_c256_hi, min_y256);
1776*77c1e3ccSAndroid Build Coastguard Worker
1777*77c1e3ccSAndroid Build Coastguard Worker int8x16_t base_y_offset128 = vcombine_s8(vqmovn_s16(base_y_offset.val[0]),
1778*77c1e3ccSAndroid Build Coastguard Worker vqmovn_s16(base_y_offset.val[1]));
1779*77c1e3ccSAndroid Build Coastguard Worker
1780*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t v_loadmaskz2 = vld1q_u8(LoadMaskz2[offset_diff / 4]);
1781*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a0_y128 = vld1q_u8(left + min_y);
1782*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a1_y128 = vld1q_u8(left + min_y + 1);
1783*77c1e3ccSAndroid Build Coastguard Worker a0_y128 = vandq_u8(a0_y128, v_loadmaskz2);
1784*77c1e3ccSAndroid Build Coastguard Worker a1_y128 = vandq_u8(a1_y128, v_loadmaskz2);
1785*77c1e3ccSAndroid Build Coastguard Worker
1786*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t v_index_low = vget_low_u8(vreinterpretq_u8_s8(base_y_offset128));
1787*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t v_index_high =
1788*77c1e3ccSAndroid Build Coastguard Worker vget_high_u8(vreinterpretq_u8_s8(base_y_offset128));
1789*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t v_tmp, v_res;
1790*77c1e3ccSAndroid Build Coastguard Worker v_tmp.val[0] = vget_low_u8(a0_y128);
1791*77c1e3ccSAndroid Build Coastguard Worker v_tmp.val[1] = vget_high_u8(a0_y128);
1792*77c1e3ccSAndroid Build Coastguard Worker v_res.val[0] = vtbl2_u8(v_tmp, v_index_low);
1793*77c1e3ccSAndroid Build Coastguard Worker v_res.val[1] = vtbl2_u8(v_tmp, v_index_high);
1794*77c1e3ccSAndroid Build Coastguard Worker a0_y128 = vcombine_u8(v_res.val[0], v_res.val[1]);
1795*77c1e3ccSAndroid Build Coastguard Worker v_tmp.val[0] = vget_low_u8(a1_y128);
1796*77c1e3ccSAndroid Build Coastguard Worker v_tmp.val[1] = vget_high_u8(a1_y128);
1797*77c1e3ccSAndroid Build Coastguard Worker v_res.val[0] = vtbl2_u8(v_tmp, v_index_low);
1798*77c1e3ccSAndroid Build Coastguard Worker v_res.val[1] = vtbl2_u8(v_tmp, v_index_high);
1799*77c1e3ccSAndroid Build Coastguard Worker a1_y128 = vcombine_u8(v_res.val[0], v_res.val[1]);
1800*77c1e3ccSAndroid Build Coastguard Worker
1801*77c1e3ccSAndroid Build Coastguard Worker a0_y0 = vget_low_u8(a0_y128);
1802*77c1e3ccSAndroid Build Coastguard Worker a0_y1 = vget_high_u8(a0_y128);
1803*77c1e3ccSAndroid Build Coastguard Worker a1_y0 = vget_low_u8(a1_y128);
1804*77c1e3ccSAndroid Build Coastguard Worker a1_y1 = vget_high_u8(a1_y128);
1805*77c1e3ccSAndroid Build Coastguard Worker } else {
1806*77c1e3ccSAndroid Build Coastguard Worker a0_y0 = load_u8_gather_s16_x8(left, base_y_c256_lo);
1807*77c1e3ccSAndroid Build Coastguard Worker a0_y1 = load_u8_gather_s16_x8(left, base_y_c256_hi);
1808*77c1e3ccSAndroid Build Coastguard Worker a1_y0 = load_u8_gather_s16_x8(left + 1, base_y_c256_lo);
1809*77c1e3ccSAndroid Build Coastguard Worker a1_y1 = load_u8_gather_s16_x8(left + 1, base_y_c256_hi);
1810*77c1e3ccSAndroid Build Coastguard Worker }
1811*77c1e3ccSAndroid Build Coastguard Worker #else
1812*77c1e3ccSAndroid Build Coastguard Worker // Values in left_idx{0,1} range from 0 through 63 inclusive.
1813*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t left_idx0 =
1814*77c1e3ccSAndroid Build Coastguard Worker vreinterpretq_u8_s16(vaddq_s16(base_y_c256_lo, vdupq_n_s16(1)));
1815*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t left_idx1 =
1816*77c1e3ccSAndroid Build Coastguard Worker vreinterpretq_u8_s16(vaddq_s16(base_y_c256_hi, vdupq_n_s16(1)));
1817*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t left_idx01 = vuzp1q_u8(left_idx0, left_idx1);
1818*77c1e3ccSAndroid Build Coastguard Worker
1819*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a0_y01 = vqtbl4q_u8(left_vals0, left_idx01);
1820*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t a1_y01 = vqtbl4q_u8(left_vals1, left_idx01);
1821*77c1e3ccSAndroid Build Coastguard Worker
1822*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a0_y0 = vget_low_u8(a0_y01);
1823*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a0_y1 = vget_high_u8(a0_y01);
1824*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a1_y0 = vget_low_u8(a1_y01);
1825*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a1_y1 = vget_high_u8(a1_y01);
1826*77c1e3ccSAndroid Build Coastguard Worker #endif // !AOM_ARCH_AARCH64
1827*77c1e3ccSAndroid Build Coastguard Worker
1828*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t shifty_lo = vshrq_n_u16(
1829*77c1e3ccSAndroid Build Coastguard Worker vandq_u16(vreinterpretq_u16_s16(y_c256_lo), vdupq_n_u16(0x3f)), 1);
1830*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t shifty_hi = vshrq_n_u16(
1831*77c1e3ccSAndroid Build Coastguard Worker vandq_u16(vreinterpretq_u16_s16(y_c256_hi), vdupq_n_u16(0x3f)), 1);
1832*77c1e3ccSAndroid Build Coastguard Worker
1833*77c1e3ccSAndroid Build Coastguard Worker // a[x+1] - a[x]
1834*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff_lo = vsubl_u8(a1_y0, a0_y0);
1835*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff_hi = vsubl_u8(a1_y1, a0_y1);
1836*77c1e3ccSAndroid Build Coastguard Worker // a[x] * 32 + 16
1837*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32_lo = vmlal_u8(vdupq_n_u16(16), a0_y0, vdup_n_u8(32));
1838*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32_hi = vmlal_u8(vdupq_n_u16(16), a0_y1, vdup_n_u8(32));
1839*77c1e3ccSAndroid Build Coastguard Worker
1840*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res0 = vmlaq_u16(a32_lo, diff_lo, shifty_lo);
1841*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res1 = vmlaq_u16(a32_hi, diff_hi, shifty_hi);
1842*77c1e3ccSAndroid Build Coastguard Worker
1843*77c1e3ccSAndroid Build Coastguard Worker return vcombine_u8(vshrn_n_u16(res0, 5), vshrn_n_u16(res1, 5));
1844*77c1e3ccSAndroid Build Coastguard Worker }
1845*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z2_Nx4_neon(int N,uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left,int upsample_above,int upsample_left,int dx,int dy)1846*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z2_Nx4_neon(int N, uint8_t *dst, ptrdiff_t stride,
1847*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left,
1848*77c1e3ccSAndroid Build Coastguard Worker int upsample_above, int upsample_left,
1849*77c1e3ccSAndroid Build Coastguard Worker int dx, int dy) {
1850*77c1e3ccSAndroid Build Coastguard Worker const int min_base_x = -(1 << upsample_above);
1851*77c1e3ccSAndroid Build Coastguard Worker const int min_base_y = -(1 << upsample_left);
1852*77c1e3ccSAndroid Build Coastguard Worker const int frac_bits_x = 6 - upsample_above;
1853*77c1e3ccSAndroid Build Coastguard Worker const int frac_bits_y = 6 - upsample_left;
1854*77c1e3ccSAndroid Build Coastguard Worker
1855*77c1e3ccSAndroid Build Coastguard Worker assert(dx > 0);
1856*77c1e3ccSAndroid Build Coastguard Worker // pre-filter above pixels
1857*77c1e3ccSAndroid Build Coastguard Worker // store in temp buffers:
1858*77c1e3ccSAndroid Build Coastguard Worker // above[x] * 32 + 16
1859*77c1e3ccSAndroid Build Coastguard Worker // above[x+1] - above[x]
1860*77c1e3ccSAndroid Build Coastguard Worker // final pixels will be calculated as:
1861*77c1e3ccSAndroid Build Coastguard Worker // (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1862*77c1e3ccSAndroid Build Coastguard Worker
1863*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_AARCH64
1864*77c1e3ccSAndroid Build Coastguard Worker // Use ext rather than loading left + 14 directly to avoid over-read.
1865*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_m2 = vld1q_u8(left - 2);
1866*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_0 = vld1q_u8(left);
1867*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_14 = vextq_u8(left_0, left_0, 14);
1868*77c1e3ccSAndroid Build Coastguard Worker const uint8x16x2_t left_vals = { { left_m2, left_14 } };
1869*77c1e3ccSAndroid Build Coastguard Worker #define LEFT left_vals
1870*77c1e3ccSAndroid Build Coastguard Worker #else // !AOM_ARCH_AARCH64
1871*77c1e3ccSAndroid Build Coastguard Worker #define LEFT left
1872*77c1e3ccSAndroid Build Coastguard Worker #endif // AOM_ARCH_AARCH64
1873*77c1e3ccSAndroid Build Coastguard Worker
1874*77c1e3ccSAndroid Build Coastguard Worker for (int r = 0; r < N; r++) {
1875*77c1e3ccSAndroid Build Coastguard Worker int y = r + 1;
1876*77c1e3ccSAndroid Build Coastguard Worker int base_x = (-y * dx) >> frac_bits_x;
1877*77c1e3ccSAndroid Build Coastguard Worker const int base_min_diff =
1878*77c1e3ccSAndroid Build Coastguard Worker (min_base_x - ((-y * dx) >> frac_bits_x) + upsample_above) >>
1879*77c1e3ccSAndroid Build Coastguard Worker upsample_above;
1880*77c1e3ccSAndroid Build Coastguard Worker
1881*77c1e3ccSAndroid Build Coastguard Worker if (base_min_diff <= 0) {
1882*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a0_x_u8, a1_x_u8;
1883*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t shift0;
1884*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z2_Nx4_above_neon(above, upsample_above, dx, base_x, y,
1885*77c1e3ccSAndroid Build Coastguard Worker &a0_x_u8, &a1_x_u8, &shift0);
1886*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a0_x = a0_x_u8;
1887*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a1_x = a1_x_u8;
1888*77c1e3ccSAndroid Build Coastguard Worker
1889*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff = vsubl_u8(a1_x, a0_x); // a[x+1] - a[x]
1890*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32 =
1891*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(vdupq_n_u16(16), a0_x, vdup_n_u8(32)); // a[x] * 32 + 16
1892*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res =
1893*77c1e3ccSAndroid Build Coastguard Worker vmlaq_u16(a32, diff, vcombine_u16(shift0, vdup_n_u16(0)));
1894*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t resx = vshrn_n_u16(res, 5);
1895*77c1e3ccSAndroid Build Coastguard Worker vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(resx), 0);
1896*77c1e3ccSAndroid Build Coastguard Worker } else if (base_min_diff < 4) {
1897*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t a0_x_u8, a1_x_u8;
1898*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t shift0;
1899*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z2_Nx4_above_neon(above, upsample_above, dx, base_x, y,
1900*77c1e3ccSAndroid Build Coastguard Worker &a0_x_u8, &a1_x_u8, &shift0);
1901*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a0_x = vmovl_u8(a0_x_u8);
1902*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a1_x = vmovl_u8(a1_x_u8);
1903*77c1e3ccSAndroid Build Coastguard Worker
1904*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t a0_y;
1905*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t a1_y;
1906*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t shift1;
1907*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z2_Nx4_left_neon(LEFT, upsample_left, dy, r, min_base_y,
1908*77c1e3ccSAndroid Build Coastguard Worker frac_bits_y, &a0_y, &a1_y, &shift1);
1909*77c1e3ccSAndroid Build Coastguard Worker a0_x = vcombine_u16(vget_low_u16(a0_x), a0_y);
1910*77c1e3ccSAndroid Build Coastguard Worker a1_x = vcombine_u16(vget_low_u16(a1_x), a1_y);
1911*77c1e3ccSAndroid Build Coastguard Worker
1912*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t shift = vcombine_u16(shift0, shift1);
1913*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t diff = vsubq_u16(a1_x, a0_x); // a[x+1] - a[x]
1914*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t a32 =
1915*77c1e3ccSAndroid Build Coastguard Worker vmlaq_n_u16(vdupq_n_u16(16), a0_x, 32); // a[x] * 32 + 16
1916*77c1e3ccSAndroid Build Coastguard Worker uint16x8_t res = vmlaq_u16(a32, diff, shift);
1917*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t resx = vshrn_n_u16(res, 5);
1918*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t resy = vext_u8(resx, vdup_n_u8(0), 4);
1919*77c1e3ccSAndroid Build Coastguard Worker
1920*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t mask = vld1_u8(BaseMask[base_min_diff]);
1921*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t v_resxy = vbsl_u8(mask, resy, resx);
1922*77c1e3ccSAndroid Build Coastguard Worker vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(v_resxy), 0);
1923*77c1e3ccSAndroid Build Coastguard Worker } else {
1924*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t a0_y, a1_y;
1925*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t shift1;
1926*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z2_Nx4_left_neon(LEFT, upsample_left, dy, r, min_base_y,
1927*77c1e3ccSAndroid Build Coastguard Worker frac_bits_y, &a0_y, &a1_y, &shift1);
1928*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t diff = vsub_u16(a1_y, a0_y); // a[x+1] - a[x]
1929*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t a32 = vmla_n_u16(vdup_n_u16(16), a0_y, 32); // a[x] * 32 + 16
1930*77c1e3ccSAndroid Build Coastguard Worker uint16x4_t res = vmla_u16(a32, diff, shift1);
1931*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t resy = vshrn_n_u16(vcombine_u16(res, vdup_n_u16(0)), 5);
1932*77c1e3ccSAndroid Build Coastguard Worker
1933*77c1e3ccSAndroid Build Coastguard Worker vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(resy), 0);
1934*77c1e3ccSAndroid Build Coastguard Worker }
1935*77c1e3ccSAndroid Build Coastguard Worker
1936*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
1937*77c1e3ccSAndroid Build Coastguard Worker }
1938*77c1e3ccSAndroid Build Coastguard Worker #undef LEFT
1939*77c1e3ccSAndroid Build Coastguard Worker }
1940*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z2_Nx8_neon(int N,uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left,int upsample_above,int upsample_left,int dx,int dy)1941*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z2_Nx8_neon(int N, uint8_t *dst, ptrdiff_t stride,
1942*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left,
1943*77c1e3ccSAndroid Build Coastguard Worker int upsample_above, int upsample_left,
1944*77c1e3ccSAndroid Build Coastguard Worker int dx, int dy) {
1945*77c1e3ccSAndroid Build Coastguard Worker const int min_base_x = -(1 << upsample_above);
1946*77c1e3ccSAndroid Build Coastguard Worker const int min_base_y = -(1 << upsample_left);
1947*77c1e3ccSAndroid Build Coastguard Worker const int frac_bits_x = 6 - upsample_above;
1948*77c1e3ccSAndroid Build Coastguard Worker const int frac_bits_y = 6 - upsample_left;
1949*77c1e3ccSAndroid Build Coastguard Worker
1950*77c1e3ccSAndroid Build Coastguard Worker // pre-filter above pixels
1951*77c1e3ccSAndroid Build Coastguard Worker // store in temp buffers:
1952*77c1e3ccSAndroid Build Coastguard Worker // above[x] * 32 + 16
1953*77c1e3ccSAndroid Build Coastguard Worker // above[x+1] - above[x]
1954*77c1e3ccSAndroid Build Coastguard Worker // final pixels will be calculated as:
1955*77c1e3ccSAndroid Build Coastguard Worker // (above[x] * 32 + 16 + (above[x+1] - above[x]) * shift) >> 5
1956*77c1e3ccSAndroid Build Coastguard Worker
1957*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_AARCH64
1958*77c1e3ccSAndroid Build Coastguard Worker // Use ext rather than loading left + 30 directly to avoid over-read.
1959*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_m2 = vld1q_u8(left - 2);
1960*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_0 = vld1q_u8(left + 0);
1961*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_16 = vld1q_u8(left + 16);
1962*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_14 = vextq_u8(left_0, left_16, 14);
1963*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_30 = vextq_u8(left_16, left_16, 14);
1964*77c1e3ccSAndroid Build Coastguard Worker const uint8x16x3_t left_vals = { { left_m2, left_14, left_30 } };
1965*77c1e3ccSAndroid Build Coastguard Worker #define LEFT left_vals
1966*77c1e3ccSAndroid Build Coastguard Worker #else // !AOM_ARCH_AARCH64
1967*77c1e3ccSAndroid Build Coastguard Worker #define LEFT left
1968*77c1e3ccSAndroid Build Coastguard Worker #endif // AOM_ARCH_AARCH64
1969*77c1e3ccSAndroid Build Coastguard Worker
1970*77c1e3ccSAndroid Build Coastguard Worker for (int r = 0; r < N; r++) {
1971*77c1e3ccSAndroid Build Coastguard Worker int y = r + 1;
1972*77c1e3ccSAndroid Build Coastguard Worker int base_x = (-y * dx) >> frac_bits_x;
1973*77c1e3ccSAndroid Build Coastguard Worker int base_min_diff =
1974*77c1e3ccSAndroid Build Coastguard Worker (min_base_x - base_x + upsample_above) >> upsample_above;
1975*77c1e3ccSAndroid Build Coastguard Worker
1976*77c1e3ccSAndroid Build Coastguard Worker if (base_min_diff <= 0) {
1977*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t resx =
1978*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z2_Nx8_above_neon(above, upsample_above, dx, base_x, y);
1979*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst, resx);
1980*77c1e3ccSAndroid Build Coastguard Worker } else if (base_min_diff < 8) {
1981*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t resx =
1982*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z2_Nx8_above_neon(above, upsample_above, dx, base_x, y);
1983*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t resy = dr_prediction_z2_Nx8_left_neon(
1984*77c1e3ccSAndroid Build Coastguard Worker LEFT, upsample_left, dy, r, min_base_y, frac_bits_y);
1985*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t mask = vld1_u8(BaseMask[base_min_diff]);
1986*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t resxy = vbsl_u8(mask, resy, resx);
1987*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst, resxy);
1988*77c1e3ccSAndroid Build Coastguard Worker } else {
1989*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t resy = dr_prediction_z2_Nx8_left_neon(
1990*77c1e3ccSAndroid Build Coastguard Worker LEFT, upsample_left, dy, r, min_base_y, frac_bits_y);
1991*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst, resy);
1992*77c1e3ccSAndroid Build Coastguard Worker }
1993*77c1e3ccSAndroid Build Coastguard Worker
1994*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
1995*77c1e3ccSAndroid Build Coastguard Worker }
1996*77c1e3ccSAndroid Build Coastguard Worker #undef LEFT
1997*77c1e3ccSAndroid Build Coastguard Worker }
1998*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z2_HxW_neon(int H,int W,uint8_t * dst,ptrdiff_t stride,const uint8_t * above,const uint8_t * left,int dx,int dy)1999*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z2_HxW_neon(int H, int W, uint8_t *dst,
2000*77c1e3ccSAndroid Build Coastguard Worker ptrdiff_t stride, const uint8_t *above,
2001*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int dx, int dy) {
2002*77c1e3ccSAndroid Build Coastguard Worker // here upsample_above and upsample_left are 0 by design of
2003*77c1e3ccSAndroid Build Coastguard Worker // av1_use_intra_edge_upsample
2004*77c1e3ccSAndroid Build Coastguard Worker const int min_base_x = -1;
2005*77c1e3ccSAndroid Build Coastguard Worker
2006*77c1e3ccSAndroid Build Coastguard Worker #if AOM_ARCH_AARCH64
2007*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_m1 = vld1q_u8(left - 1);
2008*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_0 = vld1q_u8(left + 0);
2009*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_16 = vld1q_u8(left + 16);
2010*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_32 = vld1q_u8(left + 32);
2011*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_48 = vld1q_u8(left + 48);
2012*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_15 = vextq_u8(left_0, left_16, 15);
2013*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_31 = vextq_u8(left_16, left_32, 15);
2014*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_47 = vextq_u8(left_32, left_48, 15);
2015*77c1e3ccSAndroid Build Coastguard Worker const uint8x16x4_t left_vals0 = { { left_m1, left_15, left_31, left_47 } };
2016*77c1e3ccSAndroid Build Coastguard Worker const uint8x16x4_t left_vals1 = { { left_0, left_16, left_32, left_48 } };
2017*77c1e3ccSAndroid Build Coastguard Worker #define LEFT left_vals0, left_vals1
2018*77c1e3ccSAndroid Build Coastguard Worker #else // !AOM_ARCH_AARCH64
2019*77c1e3ccSAndroid Build Coastguard Worker #define LEFT left
2020*77c1e3ccSAndroid Build Coastguard Worker #endif // AOM_ARCH_AARCH64
2021*77c1e3ccSAndroid Build Coastguard Worker
2022*77c1e3ccSAndroid Build Coastguard Worker for (int r = 0; r < H; r++) {
2023*77c1e3ccSAndroid Build Coastguard Worker int y = r + 1;
2024*77c1e3ccSAndroid Build Coastguard Worker int base_x = (-y * dx) >> 6;
2025*77c1e3ccSAndroid Build Coastguard Worker for (int j = 0; j < W; j += 16) {
2026*77c1e3ccSAndroid Build Coastguard Worker const int base_min_diff = min_base_x - base_x - j;
2027*77c1e3ccSAndroid Build Coastguard Worker
2028*77c1e3ccSAndroid Build Coastguard Worker if (base_min_diff <= 0) {
2029*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t resx =
2030*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z2_NxW_above_neon(above, dx, base_x, y, j);
2031*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + j, resx);
2032*77c1e3ccSAndroid Build Coastguard Worker } else if (base_min_diff < 16) {
2033*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t resx =
2034*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z2_NxW_above_neon(above, dx, base_x, y, j);
2035*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t resy = dr_prediction_z2_NxW_left_neon(LEFT, dy, r, j);
2036*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t mask = vld1q_u8(BaseMask[base_min_diff]);
2037*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t resxy = vbslq_u8(mask, resy, resx);
2038*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + j, resxy);
2039*77c1e3ccSAndroid Build Coastguard Worker } else {
2040*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t resy = dr_prediction_z2_NxW_left_neon(LEFT, dy, r, j);
2041*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + j, resy);
2042*77c1e3ccSAndroid Build Coastguard Worker }
2043*77c1e3ccSAndroid Build Coastguard Worker } // for j
2044*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
2045*77c1e3ccSAndroid Build Coastguard Worker }
2046*77c1e3ccSAndroid Build Coastguard Worker #undef LEFT
2047*77c1e3ccSAndroid Build Coastguard Worker }
2048*77c1e3ccSAndroid Build Coastguard Worker
2049*77c1e3ccSAndroid Build Coastguard Worker // Directional prediction, zone 2: 90 < angle < 180
av1_dr_prediction_z2_neon(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left,int upsample_above,int upsample_left,int dx,int dy)2050*77c1e3ccSAndroid Build Coastguard Worker void av1_dr_prediction_z2_neon(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
2051*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left,
2052*77c1e3ccSAndroid Build Coastguard Worker int upsample_above, int upsample_left, int dx,
2053*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2054*77c1e3ccSAndroid Build Coastguard Worker assert(dx > 0);
2055*77c1e3ccSAndroid Build Coastguard Worker assert(dy > 0);
2056*77c1e3ccSAndroid Build Coastguard Worker
2057*77c1e3ccSAndroid Build Coastguard Worker switch (bw) {
2058*77c1e3ccSAndroid Build Coastguard Worker case 4:
2059*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z2_Nx4_neon(bh, dst, stride, above, left, upsample_above,
2060*77c1e3ccSAndroid Build Coastguard Worker upsample_left, dx, dy);
2061*77c1e3ccSAndroid Build Coastguard Worker break;
2062*77c1e3ccSAndroid Build Coastguard Worker case 8:
2063*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z2_Nx8_neon(bh, dst, stride, above, left, upsample_above,
2064*77c1e3ccSAndroid Build Coastguard Worker upsample_left, dx, dy);
2065*77c1e3ccSAndroid Build Coastguard Worker break;
2066*77c1e3ccSAndroid Build Coastguard Worker default:
2067*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z2_HxW_neon(bh, bw, dst, stride, above, left, dx, dy);
2068*77c1e3ccSAndroid Build Coastguard Worker break;
2069*77c1e3ccSAndroid Build Coastguard Worker }
2070*77c1e3ccSAndroid Build Coastguard Worker }
2071*77c1e3ccSAndroid Build Coastguard Worker #endif // AOM_ARCH_AARCH64
2072*77c1e3ccSAndroid Build Coastguard Worker
2073*77c1e3ccSAndroid Build Coastguard Worker /* ---------------------P R E D I C T I O N Z 3--------------------------- */
2074*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
z3_transpose_arrays_u8_16x4(const uint8x16_t * x,uint8x16x2_t * d)2075*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE void z3_transpose_arrays_u8_16x4(const uint8x16_t *x,
2076*77c1e3ccSAndroid Build Coastguard Worker uint8x16x2_t *d) {
2077*77c1e3ccSAndroid Build Coastguard Worker uint8x16x2_t w0 = vzipq_u8(x[0], x[1]);
2078*77c1e3ccSAndroid Build Coastguard Worker uint8x16x2_t w1 = vzipq_u8(x[2], x[3]);
2079*77c1e3ccSAndroid Build Coastguard Worker
2080*77c1e3ccSAndroid Build Coastguard Worker d[0] = aom_reinterpretq_u8_u16_x2(vzipq_u16(vreinterpretq_u16_u8(w0.val[0]),
2081*77c1e3ccSAndroid Build Coastguard Worker vreinterpretq_u16_u8(w1.val[0])));
2082*77c1e3ccSAndroid Build Coastguard Worker d[1] = aom_reinterpretq_u8_u16_x2(vzipq_u16(vreinterpretq_u16_u8(w0.val[1]),
2083*77c1e3ccSAndroid Build Coastguard Worker vreinterpretq_u16_u8(w1.val[1])));
2084*77c1e3ccSAndroid Build Coastguard Worker }
2085*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2086*77c1e3ccSAndroid Build Coastguard Worker
z3_transpose_arrays_u8_4x4(const uint8x8_t * x,uint8x8x2_t * d)2087*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE void z3_transpose_arrays_u8_4x4(const uint8x8_t *x,
2088*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t *d) {
2089*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t w0 = vzip_u8(x[0], x[1]);
2090*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t w1 = vzip_u8(x[2], x[3]);
2091*77c1e3ccSAndroid Build Coastguard Worker
2092*77c1e3ccSAndroid Build Coastguard Worker *d = aom_reinterpret_u8_u16_x2(
2093*77c1e3ccSAndroid Build Coastguard Worker vzip_u16(vreinterpret_u16_u8(w0.val[0]), vreinterpret_u16_u8(w1.val[0])));
2094*77c1e3ccSAndroid Build Coastguard Worker }
2095*77c1e3ccSAndroid Build Coastguard Worker
z3_transpose_arrays_u8_8x4(const uint8x8_t * x,uint8x8x2_t * d)2096*77c1e3ccSAndroid Build Coastguard Worker static AOM_FORCE_INLINE void z3_transpose_arrays_u8_8x4(const uint8x8_t *x,
2097*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t *d) {
2098*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t w0 = vzip_u8(x[0], x[1]);
2099*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t w1 = vzip_u8(x[2], x[3]);
2100*77c1e3ccSAndroid Build Coastguard Worker
2101*77c1e3ccSAndroid Build Coastguard Worker d[0] = aom_reinterpret_u8_u16_x2(
2102*77c1e3ccSAndroid Build Coastguard Worker vzip_u16(vreinterpret_u16_u8(w0.val[0]), vreinterpret_u16_u8(w1.val[0])));
2103*77c1e3ccSAndroid Build Coastguard Worker d[1] = aom_reinterpret_u8_u16_x2(
2104*77c1e3ccSAndroid Build Coastguard Worker vzip_u16(vreinterpret_u16_u8(w0.val[1]), vreinterpret_u16_u8(w1.val[1])));
2105*77c1e3ccSAndroid Build Coastguard Worker }
2106*77c1e3ccSAndroid Build Coastguard Worker
z3_transpose_arrays_u8_16x16(const uint8_t * src,ptrdiff_t pitchSrc,uint8_t * dst,ptrdiff_t pitchDst)2107*77c1e3ccSAndroid Build Coastguard Worker static void z3_transpose_arrays_u8_16x16(const uint8_t *src, ptrdiff_t pitchSrc,
2108*77c1e3ccSAndroid Build Coastguard Worker uint8_t *dst, ptrdiff_t pitchDst) {
2109*77c1e3ccSAndroid Build Coastguard Worker // The same as the normal transposes in transpose_neon.h, but with a stride
2110*77c1e3ccSAndroid Build Coastguard Worker // between consecutive vectors of elements.
2111*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t r[16];
2112*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d[16];
2113*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 16; i++) {
2114*77c1e3ccSAndroid Build Coastguard Worker r[i] = vld1q_u8(src + i * pitchSrc);
2115*77c1e3ccSAndroid Build Coastguard Worker }
2116*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_16x16(r, d);
2117*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 16; i++) {
2118*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * pitchDst, d[i]);
2119*77c1e3ccSAndroid Build Coastguard Worker }
2120*77c1e3ccSAndroid Build Coastguard Worker }
2121*77c1e3ccSAndroid Build Coastguard Worker
z3_transpose_arrays_u8_16nx16n(const uint8_t * src,ptrdiff_t pitchSrc,uint8_t * dst,ptrdiff_t pitchDst,int width,int height)2122*77c1e3ccSAndroid Build Coastguard Worker static void z3_transpose_arrays_u8_16nx16n(const uint8_t *src,
2123*77c1e3ccSAndroid Build Coastguard Worker ptrdiff_t pitchSrc, uint8_t *dst,
2124*77c1e3ccSAndroid Build Coastguard Worker ptrdiff_t pitchDst, int width,
2125*77c1e3ccSAndroid Build Coastguard Worker int height) {
2126*77c1e3ccSAndroid Build Coastguard Worker for (int j = 0; j < height; j += 16) {
2127*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < width; i += 16) {
2128*77c1e3ccSAndroid Build Coastguard Worker z3_transpose_arrays_u8_16x16(src + i * pitchSrc + j, pitchSrc,
2129*77c1e3ccSAndroid Build Coastguard Worker dst + j * pitchDst + i, pitchDst);
2130*77c1e3ccSAndroid Build Coastguard Worker }
2131*77c1e3ccSAndroid Build Coastguard Worker }
2132*77c1e3ccSAndroid Build Coastguard Worker }
2133*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_4x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2134*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_4x4_neon(uint8_t *dst, ptrdiff_t stride,
2135*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2136*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2137*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t dstvec[4];
2138*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t dest;
2139*77c1e3ccSAndroid Build Coastguard Worker
2140*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon_64(4, 4, dstvec, left, upsample_left, dy);
2141*77c1e3ccSAndroid Build Coastguard Worker z3_transpose_arrays_u8_4x4(dstvec, &dest);
2142*77c1e3ccSAndroid Build Coastguard Worker store_u8x4_strided_x2(dst + stride * 0, stride, dest.val[0]);
2143*77c1e3ccSAndroid Build Coastguard Worker store_u8x4_strided_x2(dst + stride * 2, stride, dest.val[1]);
2144*77c1e3ccSAndroid Build Coastguard Worker }
2145*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_8x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2146*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_8x8_neon(uint8_t *dst, ptrdiff_t stride,
2147*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2148*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2149*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t dstvec[8];
2150*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t d[8];
2151*77c1e3ccSAndroid Build Coastguard Worker
2152*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon_64(8, 8, dstvec, left, upsample_left, dy);
2153*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_8x8(dstvec, d);
2154*77c1e3ccSAndroid Build Coastguard Worker store_u8_8x8(dst, stride, d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]);
2155*77c1e3ccSAndroid Build Coastguard Worker }
2156*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_4x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2157*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_4x8_neon(uint8_t *dst, ptrdiff_t stride,
2158*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2159*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2160*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t dstvec[4];
2161*77c1e3ccSAndroid Build Coastguard Worker uint8x8x2_t d[2];
2162*77c1e3ccSAndroid Build Coastguard Worker
2163*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon_64(8, 4, dstvec, left, upsample_left, dy);
2164*77c1e3ccSAndroid Build Coastguard Worker z3_transpose_arrays_u8_8x4(dstvec, d);
2165*77c1e3ccSAndroid Build Coastguard Worker store_u8x4_strided_x2(dst + stride * 0, stride, d[0].val[0]);
2166*77c1e3ccSAndroid Build Coastguard Worker store_u8x4_strided_x2(dst + stride * 2, stride, d[0].val[1]);
2167*77c1e3ccSAndroid Build Coastguard Worker store_u8x4_strided_x2(dst + stride * 4, stride, d[1].val[0]);
2168*77c1e3ccSAndroid Build Coastguard Worker store_u8x4_strided_x2(dst + stride * 6, stride, d[1].val[1]);
2169*77c1e3ccSAndroid Build Coastguard Worker }
2170*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_8x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2171*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_8x4_neon(uint8_t *dst, ptrdiff_t stride,
2172*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2173*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2174*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t dstvec[8];
2175*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t d[8];
2176*77c1e3ccSAndroid Build Coastguard Worker
2177*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon_64(4, 8, dstvec, left, upsample_left, dy);
2178*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_8x8(dstvec, d);
2179*77c1e3ccSAndroid Build Coastguard Worker store_u8_8x4(dst, stride, d[0], d[1], d[2], d[3]);
2180*77c1e3ccSAndroid Build Coastguard Worker }
2181*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_8x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2182*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_8x16_neon(uint8_t *dst, ptrdiff_t stride,
2183*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2184*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2185*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t dstvec[8];
2186*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t d[16];
2187*77c1e3ccSAndroid Build Coastguard Worker
2188*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon(16, 8, dstvec, left, upsample_left, dy);
2189*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_16x8(dstvec, d);
2190*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 16; i++) {
2191*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + i * stride, d[i]);
2192*77c1e3ccSAndroid Build Coastguard Worker }
2193*77c1e3ccSAndroid Build Coastguard Worker }
2194*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_16x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2195*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_16x8_neon(uint8_t *dst, ptrdiff_t stride,
2196*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2197*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2198*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t dstvec[16];
2199*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d[8];
2200*77c1e3ccSAndroid Build Coastguard Worker
2201*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon_64(8, 16, dstvec, left, upsample_left, dy);
2202*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_8x16(dstvec, d);
2203*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 8; i++) {
2204*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride, d[i]);
2205*77c1e3ccSAndroid Build Coastguard Worker }
2206*77c1e3ccSAndroid Build Coastguard Worker }
2207*77c1e3ccSAndroid Build Coastguard Worker
2208*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
dr_prediction_z3_4x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2209*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_4x16_neon(uint8_t *dst, ptrdiff_t stride,
2210*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2211*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2212*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t dstvec[4];
2213*77c1e3ccSAndroid Build Coastguard Worker uint8x16x2_t d[2];
2214*77c1e3ccSAndroid Build Coastguard Worker
2215*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon(16, 4, dstvec, left, upsample_left, dy);
2216*77c1e3ccSAndroid Build Coastguard Worker z3_transpose_arrays_u8_16x4(dstvec, d);
2217*77c1e3ccSAndroid Build Coastguard Worker store_u8x4_strided_x4(dst + stride * 0, stride, d[0].val[0]);
2218*77c1e3ccSAndroid Build Coastguard Worker store_u8x4_strided_x4(dst + stride * 4, stride, d[0].val[1]);
2219*77c1e3ccSAndroid Build Coastguard Worker store_u8x4_strided_x4(dst + stride * 8, stride, d[1].val[0]);
2220*77c1e3ccSAndroid Build Coastguard Worker store_u8x4_strided_x4(dst + stride * 12, stride, d[1].val[1]);
2221*77c1e3ccSAndroid Build Coastguard Worker }
2222*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_16x4_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2223*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_16x4_neon(uint8_t *dst, ptrdiff_t stride,
2224*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2225*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2226*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t dstvec[16];
2227*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d[8];
2228*77c1e3ccSAndroid Build Coastguard Worker
2229*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon_64(4, 16, dstvec, left, upsample_left, dy);
2230*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_8x16(dstvec, d);
2231*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 4; i++) {
2232*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride, d[i]);
2233*77c1e3ccSAndroid Build Coastguard Worker }
2234*77c1e3ccSAndroid Build Coastguard Worker }
2235*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_8x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2236*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_8x32_neon(uint8_t *dst, ptrdiff_t stride,
2237*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2238*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2239*77c1e3ccSAndroid Build Coastguard Worker (void)upsample_left;
2240*77c1e3ccSAndroid Build Coastguard Worker uint8x16x2_t dstvec[16];
2241*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d[32];
2242*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t v_zero = vdupq_n_u8(0);
2243*77c1e3ccSAndroid Build Coastguard Worker
2244*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_32xN_internal_neon(8, dstvec, left, dy);
2245*77c1e3ccSAndroid Build Coastguard Worker for (int i = 8; i < 16; i++) {
2246*77c1e3ccSAndroid Build Coastguard Worker dstvec[i].val[0] = v_zero;
2247*77c1e3ccSAndroid Build Coastguard Worker dstvec[i].val[1] = v_zero;
2248*77c1e3ccSAndroid Build Coastguard Worker }
2249*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_32x16(dstvec, d);
2250*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 32; i++) {
2251*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst + i * stride, vget_low_u8(d[i]));
2252*77c1e3ccSAndroid Build Coastguard Worker }
2253*77c1e3ccSAndroid Build Coastguard Worker }
2254*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_32x8_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2255*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_32x8_neon(uint8_t *dst, ptrdiff_t stride,
2256*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2257*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2258*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t dstvec[32];
2259*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d[16];
2260*77c1e3ccSAndroid Build Coastguard Worker
2261*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon_64(8, 32, dstvec, left, upsample_left, dy);
2262*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_8x16(dstvec, d);
2263*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_8x16(dstvec + 16, d + 8);
2264*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 8; i++) {
2265*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride, d[i]);
2266*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride + 16, d[i + 8]);
2267*77c1e3ccSAndroid Build Coastguard Worker }
2268*77c1e3ccSAndroid Build Coastguard Worker }
2269*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2270*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_16x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2271*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_16x16_neon(uint8_t *dst, ptrdiff_t stride,
2272*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2273*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2274*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t dstvec[16];
2275*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d[16];
2276*77c1e3ccSAndroid Build Coastguard Worker
2277*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon(16, 16, dstvec, left, upsample_left, dy);
2278*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_16x16(dstvec, d);
2279*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 16; i++) {
2280*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride, d[i]);
2281*77c1e3ccSAndroid Build Coastguard Worker }
2282*77c1e3ccSAndroid Build Coastguard Worker }
2283*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_32x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2284*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_32x32_neon(uint8_t *dst, ptrdiff_t stride,
2285*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2286*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2287*77c1e3ccSAndroid Build Coastguard Worker (void)upsample_left;
2288*77c1e3ccSAndroid Build Coastguard Worker uint8x16x2_t dstvec[32];
2289*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d[64];
2290*77c1e3ccSAndroid Build Coastguard Worker
2291*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_32xN_internal_neon(32, dstvec, left, dy);
2292*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_32x16(dstvec, d);
2293*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_32x16(dstvec + 16, d + 32);
2294*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 32; i++) {
2295*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride, d[i]);
2296*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + i * stride + 16, d[i + 32]);
2297*77c1e3ccSAndroid Build Coastguard Worker }
2298*77c1e3ccSAndroid Build Coastguard Worker }
2299*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_64x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2300*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_64x64_neon(uint8_t *dst, ptrdiff_t stride,
2301*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2302*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2303*77c1e3ccSAndroid Build Coastguard Worker (void)upsample_left;
2304*77c1e3ccSAndroid Build Coastguard Worker DECLARE_ALIGNED(16, uint8_t, dstT[64 * 64]);
2305*77c1e3ccSAndroid Build Coastguard Worker
2306*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_64xN_neon(64, dstT, 64, left, dy);
2307*77c1e3ccSAndroid Build Coastguard Worker z3_transpose_arrays_u8_16nx16n(dstT, 64, dst, stride, 64, 64);
2308*77c1e3ccSAndroid Build Coastguard Worker }
2309*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_16x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2310*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_16x32_neon(uint8_t *dst, ptrdiff_t stride,
2311*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2312*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2313*77c1e3ccSAndroid Build Coastguard Worker (void)upsample_left;
2314*77c1e3ccSAndroid Build Coastguard Worker uint8x16x2_t dstvec[16];
2315*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d[32];
2316*77c1e3ccSAndroid Build Coastguard Worker
2317*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_32xN_internal_neon(16, dstvec, left, dy);
2318*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_32x16(dstvec, d);
2319*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 16; i++) {
2320*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 2 * i * stride, d[2 * i + 0]);
2321*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + (2 * i + 1) * stride, d[2 * i + 1]);
2322*77c1e3ccSAndroid Build Coastguard Worker }
2323*77c1e3ccSAndroid Build Coastguard Worker }
2324*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_32x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2325*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_32x16_neon(uint8_t *dst, ptrdiff_t stride,
2326*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2327*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2328*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t dstvec[32];
2329*77c1e3ccSAndroid Build Coastguard Worker
2330*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon(16, 32, dstvec, left, upsample_left, dy);
2331*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 32; i += 16) {
2332*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d[16];
2333*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_16x16(dstvec + i, d);
2334*77c1e3ccSAndroid Build Coastguard Worker for (int j = 0; j < 16; j++) {
2335*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + j * stride + i, d[j]);
2336*77c1e3ccSAndroid Build Coastguard Worker }
2337*77c1e3ccSAndroid Build Coastguard Worker }
2338*77c1e3ccSAndroid Build Coastguard Worker }
2339*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_32x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2340*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_32x64_neon(uint8_t *dst, ptrdiff_t stride,
2341*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2342*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2343*77c1e3ccSAndroid Build Coastguard Worker (void)upsample_left;
2344*77c1e3ccSAndroid Build Coastguard Worker uint8_t dstT[64 * 32];
2345*77c1e3ccSAndroid Build Coastguard Worker
2346*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_64xN_neon(32, dstT, 64, left, dy);
2347*77c1e3ccSAndroid Build Coastguard Worker z3_transpose_arrays_u8_16nx16n(dstT, 64, dst, stride, 32, 64);
2348*77c1e3ccSAndroid Build Coastguard Worker }
2349*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_64x32_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2350*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_64x32_neon(uint8_t *dst, ptrdiff_t stride,
2351*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2352*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2353*77c1e3ccSAndroid Build Coastguard Worker (void)upsample_left;
2354*77c1e3ccSAndroid Build Coastguard Worker uint8_t dstT[32 * 64];
2355*77c1e3ccSAndroid Build Coastguard Worker
2356*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_32xN_neon(64, dstT, 32, left, dy);
2357*77c1e3ccSAndroid Build Coastguard Worker z3_transpose_arrays_u8_16nx16n(dstT, 32, dst, stride, 64, 32);
2358*77c1e3ccSAndroid Build Coastguard Worker }
2359*77c1e3ccSAndroid Build Coastguard Worker
2360*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
dr_prediction_z3_16x64_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2361*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_16x64_neon(uint8_t *dst, ptrdiff_t stride,
2362*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2363*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2364*77c1e3ccSAndroid Build Coastguard Worker (void)upsample_left;
2365*77c1e3ccSAndroid Build Coastguard Worker uint8_t dstT[64 * 16];
2366*77c1e3ccSAndroid Build Coastguard Worker
2367*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_64xN_neon(16, dstT, 64, left, dy);
2368*77c1e3ccSAndroid Build Coastguard Worker z3_transpose_arrays_u8_16nx16n(dstT, 64, dst, stride, 16, 64);
2369*77c1e3ccSAndroid Build Coastguard Worker }
2370*77c1e3ccSAndroid Build Coastguard Worker
dr_prediction_z3_64x16_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * left,int upsample_left,int dy)2371*77c1e3ccSAndroid Build Coastguard Worker static void dr_prediction_z3_64x16_neon(uint8_t *dst, ptrdiff_t stride,
2372*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2373*77c1e3ccSAndroid Build Coastguard Worker int dy) {
2374*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t dstvec[64];
2375*77c1e3ccSAndroid Build Coastguard Worker
2376*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z1_HxW_internal_neon(16, 64, dstvec, left, upsample_left, dy);
2377*77c1e3ccSAndroid Build Coastguard Worker for (int i = 0; i < 64; i += 16) {
2378*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t d[16];
2379*77c1e3ccSAndroid Build Coastguard Worker transpose_arrays_u8_16x16(dstvec + i, d);
2380*77c1e3ccSAndroid Build Coastguard Worker for (int j = 0; j < 16; ++j) {
2381*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + j * stride + i, d[j]);
2382*77c1e3ccSAndroid Build Coastguard Worker }
2383*77c1e3ccSAndroid Build Coastguard Worker }
2384*77c1e3ccSAndroid Build Coastguard Worker }
2385*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2386*77c1e3ccSAndroid Build Coastguard Worker
2387*77c1e3ccSAndroid Build Coastguard Worker typedef void (*dr_prediction_z3_fn)(uint8_t *dst, ptrdiff_t stride,
2388*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left, int upsample_left,
2389*77c1e3ccSAndroid Build Coastguard Worker int dy);
2390*77c1e3ccSAndroid Build Coastguard Worker
2391*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY && !CONFIG_AV1_DECODER
2392*77c1e3ccSAndroid Build Coastguard Worker static const dr_prediction_z3_fn dr_prediction_z3_arr[7][7] = {
2393*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, NULL, NULL, NULL, NULL, NULL },
2394*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, NULL, NULL, NULL, NULL, NULL },
2395*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, dr_prediction_z3_4x4_neon, dr_prediction_z3_4x8_neon, NULL,
2396*77c1e3ccSAndroid Build Coastguard Worker NULL, NULL },
2397*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, dr_prediction_z3_8x4_neon, dr_prediction_z3_8x8_neon,
2398*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z3_8x16_neon, NULL, NULL },
2399*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, NULL, dr_prediction_z3_16x8_neon, dr_prediction_z3_16x16_neon,
2400*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z3_16x32_neon, NULL },
2401*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, NULL, NULL, dr_prediction_z3_32x16_neon,
2402*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z3_32x32_neon, dr_prediction_z3_32x64_neon },
2403*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, NULL, NULL, NULL, dr_prediction_z3_64x32_neon,
2404*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z3_64x64_neon },
2405*77c1e3ccSAndroid Build Coastguard Worker };
2406*77c1e3ccSAndroid Build Coastguard Worker #else
2407*77c1e3ccSAndroid Build Coastguard Worker static const dr_prediction_z3_fn dr_prediction_z3_arr[7][7] = {
2408*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, NULL, NULL, NULL, NULL, NULL },
2409*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, NULL, NULL, NULL, NULL, NULL },
2410*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, dr_prediction_z3_4x4_neon, dr_prediction_z3_4x8_neon,
2411*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z3_4x16_neon, NULL, NULL },
2412*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, dr_prediction_z3_8x4_neon, dr_prediction_z3_8x8_neon,
2413*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z3_8x16_neon, dr_prediction_z3_8x32_neon, NULL },
2414*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, dr_prediction_z3_16x4_neon, dr_prediction_z3_16x8_neon,
2415*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z3_16x16_neon, dr_prediction_z3_16x32_neon,
2416*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z3_16x64_neon },
2417*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, NULL, dr_prediction_z3_32x8_neon, dr_prediction_z3_32x16_neon,
2418*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z3_32x32_neon, dr_prediction_z3_32x64_neon },
2419*77c1e3ccSAndroid Build Coastguard Worker { NULL, NULL, NULL, NULL, dr_prediction_z3_64x16_neon,
2420*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z3_64x32_neon, dr_prediction_z3_64x64_neon },
2421*77c1e3ccSAndroid Build Coastguard Worker };
2422*77c1e3ccSAndroid Build Coastguard Worker #endif // CONFIG_REALTIME_ONLY && !CONFIG_AV1_DECODER
2423*77c1e3ccSAndroid Build Coastguard Worker
av1_dr_prediction_z3_neon(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left,int upsample_left,int dx,int dy)2424*77c1e3ccSAndroid Build Coastguard Worker void av1_dr_prediction_z3_neon(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
2425*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, const uint8_t *left,
2426*77c1e3ccSAndroid Build Coastguard Worker int upsample_left, int dx, int dy) {
2427*77c1e3ccSAndroid Build Coastguard Worker (void)above;
2428*77c1e3ccSAndroid Build Coastguard Worker (void)dx;
2429*77c1e3ccSAndroid Build Coastguard Worker assert(dx == 1);
2430*77c1e3ccSAndroid Build Coastguard Worker assert(dy > 0);
2431*77c1e3ccSAndroid Build Coastguard Worker
2432*77c1e3ccSAndroid Build Coastguard Worker dr_prediction_z3_fn f = dr_prediction_z3_arr[get_msb(bw)][get_msb(bh)];
2433*77c1e3ccSAndroid Build Coastguard Worker assert(f != NULL);
2434*77c1e3ccSAndroid Build Coastguard Worker f(dst, stride, left, upsample_left, dy);
2435*77c1e3ccSAndroid Build Coastguard Worker }
2436*77c1e3ccSAndroid Build Coastguard Worker
2437*77c1e3ccSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
2438*77c1e3ccSAndroid Build Coastguard Worker // SMOOTH_PRED
2439*77c1e3ccSAndroid Build Coastguard Worker
2440*77c1e3ccSAndroid Build Coastguard Worker // 256 - v = vneg_s8(v)
negate_s8(const uint8x8_t v)2441*77c1e3ccSAndroid Build Coastguard Worker static inline uint8x8_t negate_s8(const uint8x8_t v) {
2442*77c1e3ccSAndroid Build Coastguard Worker return vreinterpret_u8_s8(vneg_s8(vreinterpret_s8_u8(v)));
2443*77c1e3ccSAndroid Build Coastguard Worker }
2444*77c1e3ccSAndroid Build Coastguard Worker
smooth_4xh_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * const top_row,const uint8_t * const left_column,const int height)2445*77c1e3ccSAndroid Build Coastguard Worker static void smooth_4xh_neon(uint8_t *dst, ptrdiff_t stride,
2446*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const top_row,
2447*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const left_column,
2448*77c1e3ccSAndroid Build Coastguard Worker const int height) {
2449*77c1e3ccSAndroid Build Coastguard Worker const uint8_t top_right = top_row[3];
2450*77c1e3ccSAndroid Build Coastguard Worker const uint8_t bottom_left = left_column[height - 1];
2451*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const weights_y = smooth_weights + height - 4;
2452*77c1e3ccSAndroid Build Coastguard Worker
2453*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t top_v = load_u8_4x1(top_row);
2454*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t top_right_v = vdup_n_u8(top_right);
2455*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t bottom_left_v = vdup_n_u8(bottom_left);
2456*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t weights_x_v = load_u8_4x1(smooth_weights);
2457*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t scaled_weights_x = negate_s8(weights_x_v);
2458*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_tr = vmull_u8(scaled_weights_x, top_right_v);
2459*77c1e3ccSAndroid Build Coastguard Worker
2460*77c1e3ccSAndroid Build Coastguard Worker assert(height > 0);
2461*77c1e3ccSAndroid Build Coastguard Worker int y = 0;
2462*77c1e3ccSAndroid Build Coastguard Worker do {
2463*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left_v = vdup_n_u8(left_column[y]);
2464*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t weights_y_v = vdup_n_u8(weights_y[y]);
2465*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t scaled_weights_y = negate_s8(weights_y_v);
2466*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_bl = vmull_u8(scaled_weights_y, bottom_left_v);
2467*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_top_bl =
2468*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_bl, weights_y_v, top_v);
2469*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_tr =
2470*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_tr, weights_x_v, left_v);
2471*77c1e3ccSAndroid Build Coastguard Worker // Maximum value of each parameter: 0xFF00
2472*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t avg = vhaddq_u16(weighted_top_bl, weighted_left_tr);
2473*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t result = vrshrn_n_u16(avg, SMOOTH_WEIGHT_LOG2_SCALE);
2474*77c1e3ccSAndroid Build Coastguard Worker
2475*77c1e3ccSAndroid Build Coastguard Worker vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(result), 0);
2476*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
2477*77c1e3ccSAndroid Build Coastguard Worker } while (++y != height);
2478*77c1e3ccSAndroid Build Coastguard Worker }
2479*77c1e3ccSAndroid Build Coastguard Worker
calculate_pred(const uint16x8_t weighted_top_bl,const uint16x8_t weighted_left_tr)2480*77c1e3ccSAndroid Build Coastguard Worker static inline uint8x8_t calculate_pred(const uint16x8_t weighted_top_bl,
2481*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_tr) {
2482*77c1e3ccSAndroid Build Coastguard Worker // Maximum value of each parameter: 0xFF00
2483*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t avg = vhaddq_u16(weighted_top_bl, weighted_left_tr);
2484*77c1e3ccSAndroid Build Coastguard Worker return vrshrn_n_u16(avg, SMOOTH_WEIGHT_LOG2_SCALE);
2485*77c1e3ccSAndroid Build Coastguard Worker }
2486*77c1e3ccSAndroid Build Coastguard Worker
calculate_weights_and_pred(const uint8x8_t top,const uint8x8_t left,const uint16x8_t weighted_tr,const uint8x8_t bottom_left,const uint8x8_t weights_x,const uint8x8_t scaled_weights_y,const uint8x8_t weights_y)2487*77c1e3ccSAndroid Build Coastguard Worker static inline uint8x8_t calculate_weights_and_pred(
2488*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t top, const uint8x8_t left, const uint16x8_t weighted_tr,
2489*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t bottom_left, const uint8x8_t weights_x,
2490*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t scaled_weights_y, const uint8x8_t weights_y) {
2491*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_top = vmull_u8(weights_y, top);
2492*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_top_bl =
2493*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_top, scaled_weights_y, bottom_left);
2494*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_tr = vmlal_u8(weighted_tr, weights_x, left);
2495*77c1e3ccSAndroid Build Coastguard Worker return calculate_pred(weighted_top_bl, weighted_left_tr);
2496*77c1e3ccSAndroid Build Coastguard Worker }
2497*77c1e3ccSAndroid Build Coastguard Worker
smooth_8xh_neon(uint8_t * dst,ptrdiff_t stride,const uint8_t * const top_row,const uint8_t * const left_column,const int height)2498*77c1e3ccSAndroid Build Coastguard Worker static void smooth_8xh_neon(uint8_t *dst, ptrdiff_t stride,
2499*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const top_row,
2500*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const left_column,
2501*77c1e3ccSAndroid Build Coastguard Worker const int height) {
2502*77c1e3ccSAndroid Build Coastguard Worker const uint8_t top_right = top_row[7];
2503*77c1e3ccSAndroid Build Coastguard Worker const uint8_t bottom_left = left_column[height - 1];
2504*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const weights_y = smooth_weights + height - 4;
2505*77c1e3ccSAndroid Build Coastguard Worker
2506*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t top_v = vld1_u8(top_row);
2507*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t top_right_v = vdup_n_u8(top_right);
2508*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t bottom_left_v = vdup_n_u8(bottom_left);
2509*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t weights_x_v = vld1_u8(smooth_weights + 4);
2510*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t scaled_weights_x = negate_s8(weights_x_v);
2511*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_tr = vmull_u8(scaled_weights_x, top_right_v);
2512*77c1e3ccSAndroid Build Coastguard Worker
2513*77c1e3ccSAndroid Build Coastguard Worker assert(height > 0);
2514*77c1e3ccSAndroid Build Coastguard Worker int y = 0;
2515*77c1e3ccSAndroid Build Coastguard Worker do {
2516*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left_v = vdup_n_u8(left_column[y]);
2517*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t weights_y_v = vdup_n_u8(weights_y[y]);
2518*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t scaled_weights_y = negate_s8(weights_y_v);
2519*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t result =
2520*77c1e3ccSAndroid Build Coastguard Worker calculate_weights_and_pred(top_v, left_v, weighted_tr, bottom_left_v,
2521*77c1e3ccSAndroid Build Coastguard Worker weights_x_v, scaled_weights_y, weights_y_v);
2522*77c1e3ccSAndroid Build Coastguard Worker
2523*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst, result);
2524*77c1e3ccSAndroid Build Coastguard Worker dst += stride;
2525*77c1e3ccSAndroid Build Coastguard Worker } while (++y != height);
2526*77c1e3ccSAndroid Build Coastguard Worker }
2527*77c1e3ccSAndroid Build Coastguard Worker
2528*77c1e3ccSAndroid Build Coastguard Worker #define SMOOTH_NXM(W, H) \
2529*77c1e3ccSAndroid Build Coastguard Worker void aom_smooth_predictor_##W##x##H##_neon(uint8_t *dst, ptrdiff_t y_stride, \
2530*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, \
2531*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
2532*77c1e3ccSAndroid Build Coastguard Worker smooth_##W##xh_neon(dst, y_stride, above, left, H); \
2533*77c1e3ccSAndroid Build Coastguard Worker }
2534*77c1e3ccSAndroid Build Coastguard Worker
2535*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM(4, 4)
2536*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM(4, 8)
2537*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM(8, 4)
2538*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM(8, 8)
2539*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM(8, 16)
2540*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2541*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM(4, 16)
2542*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM(8, 32)
2543*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2544*77c1e3ccSAndroid Build Coastguard Worker
2545*77c1e3ccSAndroid Build Coastguard Worker #undef SMOOTH_NXM
2546*77c1e3ccSAndroid Build Coastguard Worker
calculate_weights_and_predq(const uint8x16_t top,const uint8x8_t left,const uint8x8_t top_right,const uint8x8_t weights_y,const uint8x16_t weights_x,const uint8x16_t scaled_weights_x,const uint16x8_t weighted_bl)2547*77c1e3ccSAndroid Build Coastguard Worker static inline uint8x16_t calculate_weights_and_predq(
2548*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t top, const uint8x8_t left, const uint8x8_t top_right,
2549*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t weights_y, const uint8x16_t weights_x,
2550*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t scaled_weights_x, const uint16x8_t weighted_bl) {
2551*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_top_bl_low =
2552*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_bl, weights_y, vget_low_u8(top));
2553*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_low = vmull_u8(vget_low_u8(weights_x), left);
2554*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_tr_low =
2555*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_left_low, vget_low_u8(scaled_weights_x), top_right);
2556*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t result_low =
2557*77c1e3ccSAndroid Build Coastguard Worker calculate_pred(weighted_top_bl_low, weighted_left_tr_low);
2558*77c1e3ccSAndroid Build Coastguard Worker
2559*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_top_bl_high =
2560*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_bl, weights_y, vget_high_u8(top));
2561*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_high = vmull_u8(vget_high_u8(weights_x), left);
2562*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_tr_high =
2563*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_left_high, vget_high_u8(scaled_weights_x), top_right);
2564*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t result_high =
2565*77c1e3ccSAndroid Build Coastguard Worker calculate_pred(weighted_top_bl_high, weighted_left_tr_high);
2566*77c1e3ccSAndroid Build Coastguard Worker
2567*77c1e3ccSAndroid Build Coastguard Worker return vcombine_u8(result_low, result_high);
2568*77c1e3ccSAndroid Build Coastguard Worker }
2569*77c1e3ccSAndroid Build Coastguard Worker
2570*77c1e3ccSAndroid Build Coastguard Worker // 256 - v = vneg_s8(v)
negate_s8q(const uint8x16_t v)2571*77c1e3ccSAndroid Build Coastguard Worker static inline uint8x16_t negate_s8q(const uint8x16_t v) {
2572*77c1e3ccSAndroid Build Coastguard Worker return vreinterpretq_u8_s8(vnegq_s8(vreinterpretq_s8_u8(v)));
2573*77c1e3ccSAndroid Build Coastguard Worker }
2574*77c1e3ccSAndroid Build Coastguard Worker
2575*77c1e3ccSAndroid Build Coastguard Worker // For width 16 and above.
2576*77c1e3ccSAndroid Build Coastguard Worker #define SMOOTH_PREDICTOR(W) \
2577*77c1e3ccSAndroid Build Coastguard Worker static void smooth_##W##xh_neon( \
2578*77c1e3ccSAndroid Build Coastguard Worker uint8_t *dst, ptrdiff_t stride, const uint8_t *const top_row, \
2579*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const left_column, const int height) { \
2580*77c1e3ccSAndroid Build Coastguard Worker const uint8_t top_right = top_row[(W)-1]; \
2581*77c1e3ccSAndroid Build Coastguard Worker const uint8_t bottom_left = left_column[height - 1]; \
2582*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const weights_y = smooth_weights + height - 4; \
2583*77c1e3ccSAndroid Build Coastguard Worker \
2584*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t top_v[4]; \
2585*77c1e3ccSAndroid Build Coastguard Worker top_v[0] = vld1q_u8(top_row); \
2586*77c1e3ccSAndroid Build Coastguard Worker if ((W) > 16) { \
2587*77c1e3ccSAndroid Build Coastguard Worker top_v[1] = vld1q_u8(top_row + 16); \
2588*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 64) { \
2589*77c1e3ccSAndroid Build Coastguard Worker top_v[2] = vld1q_u8(top_row + 32); \
2590*77c1e3ccSAndroid Build Coastguard Worker top_v[3] = vld1q_u8(top_row + 48); \
2591*77c1e3ccSAndroid Build Coastguard Worker } \
2592*77c1e3ccSAndroid Build Coastguard Worker } \
2593*77c1e3ccSAndroid Build Coastguard Worker \
2594*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t top_right_v = vdup_n_u8(top_right); \
2595*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t bottom_left_v = vdup_n_u8(bottom_left); \
2596*77c1e3ccSAndroid Build Coastguard Worker \
2597*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t weights_x_v[4]; \
2598*77c1e3ccSAndroid Build Coastguard Worker weights_x_v[0] = vld1q_u8(smooth_weights + (W)-4); \
2599*77c1e3ccSAndroid Build Coastguard Worker if ((W) > 16) { \
2600*77c1e3ccSAndroid Build Coastguard Worker weights_x_v[1] = vld1q_u8(smooth_weights + (W) + 16 - 4); \
2601*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 64) { \
2602*77c1e3ccSAndroid Build Coastguard Worker weights_x_v[2] = vld1q_u8(smooth_weights + (W) + 32 - 4); \
2603*77c1e3ccSAndroid Build Coastguard Worker weights_x_v[3] = vld1q_u8(smooth_weights + (W) + 48 - 4); \
2604*77c1e3ccSAndroid Build Coastguard Worker } \
2605*77c1e3ccSAndroid Build Coastguard Worker } \
2606*77c1e3ccSAndroid Build Coastguard Worker \
2607*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t scaled_weights_x[4]; \
2608*77c1e3ccSAndroid Build Coastguard Worker scaled_weights_x[0] = negate_s8q(weights_x_v[0]); \
2609*77c1e3ccSAndroid Build Coastguard Worker if ((W) > 16) { \
2610*77c1e3ccSAndroid Build Coastguard Worker scaled_weights_x[1] = negate_s8q(weights_x_v[1]); \
2611*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 64) { \
2612*77c1e3ccSAndroid Build Coastguard Worker scaled_weights_x[2] = negate_s8q(weights_x_v[2]); \
2613*77c1e3ccSAndroid Build Coastguard Worker scaled_weights_x[3] = negate_s8q(weights_x_v[3]); \
2614*77c1e3ccSAndroid Build Coastguard Worker } \
2615*77c1e3ccSAndroid Build Coastguard Worker } \
2616*77c1e3ccSAndroid Build Coastguard Worker \
2617*77c1e3ccSAndroid Build Coastguard Worker for (int y = 0; y < height; ++y) { \
2618*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left_v = vdup_n_u8(left_column[y]); \
2619*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t weights_y_v = vdup_n_u8(weights_y[y]); \
2620*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t scaled_weights_y = negate_s8(weights_y_v); \
2621*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_bl = \
2622*77c1e3ccSAndroid Build Coastguard Worker vmull_u8(scaled_weights_y, bottom_left_v); \
2623*77c1e3ccSAndroid Build Coastguard Worker \
2624*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst, calculate_weights_and_predq( \
2625*77c1e3ccSAndroid Build Coastguard Worker top_v[0], left_v, top_right_v, weights_y_v, \
2626*77c1e3ccSAndroid Build Coastguard Worker weights_x_v[0], scaled_weights_x[0], weighted_bl)); \
2627*77c1e3ccSAndroid Build Coastguard Worker \
2628*77c1e3ccSAndroid Build Coastguard Worker if ((W) > 16) { \
2629*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, \
2630*77c1e3ccSAndroid Build Coastguard Worker calculate_weights_and_predq( \
2631*77c1e3ccSAndroid Build Coastguard Worker top_v[1], left_v, top_right_v, weights_y_v, \
2632*77c1e3ccSAndroid Build Coastguard Worker weights_x_v[1], scaled_weights_x[1], weighted_bl)); \
2633*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 64) { \
2634*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, \
2635*77c1e3ccSAndroid Build Coastguard Worker calculate_weights_and_predq( \
2636*77c1e3ccSAndroid Build Coastguard Worker top_v[2], left_v, top_right_v, weights_y_v, \
2637*77c1e3ccSAndroid Build Coastguard Worker weights_x_v[2], scaled_weights_x[2], weighted_bl)); \
2638*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, \
2639*77c1e3ccSAndroid Build Coastguard Worker calculate_weights_and_predq( \
2640*77c1e3ccSAndroid Build Coastguard Worker top_v[3], left_v, top_right_v, weights_y_v, \
2641*77c1e3ccSAndroid Build Coastguard Worker weights_x_v[3], scaled_weights_x[3], weighted_bl)); \
2642*77c1e3ccSAndroid Build Coastguard Worker } \
2643*77c1e3ccSAndroid Build Coastguard Worker } \
2644*77c1e3ccSAndroid Build Coastguard Worker \
2645*77c1e3ccSAndroid Build Coastguard Worker dst += stride; \
2646*77c1e3ccSAndroid Build Coastguard Worker } \
2647*77c1e3ccSAndroid Build Coastguard Worker }
2648*77c1e3ccSAndroid Build Coastguard Worker
2649*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_PREDICTOR(16)
2650*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_PREDICTOR(32)
2651*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_PREDICTOR(64)
2652*77c1e3ccSAndroid Build Coastguard Worker
2653*77c1e3ccSAndroid Build Coastguard Worker #undef SMOOTH_PREDICTOR
2654*77c1e3ccSAndroid Build Coastguard Worker
2655*77c1e3ccSAndroid Build Coastguard Worker #define SMOOTH_NXM_WIDE(W, H) \
2656*77c1e3ccSAndroid Build Coastguard Worker void aom_smooth_predictor_##W##x##H##_neon(uint8_t *dst, ptrdiff_t y_stride, \
2657*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, \
2658*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
2659*77c1e3ccSAndroid Build Coastguard Worker smooth_##W##xh_neon(dst, y_stride, above, left, H); \
2660*77c1e3ccSAndroid Build Coastguard Worker }
2661*77c1e3ccSAndroid Build Coastguard Worker
2662*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2663*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(16, 4)
2664*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(16, 64)
2665*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(32, 8)
2666*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(64, 16)
2667*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2668*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(16, 8)
2669*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(16, 16)
2670*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(16, 32)
2671*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(32, 16)
2672*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(32, 32)
2673*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(32, 64)
2674*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(64, 32)
2675*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_NXM_WIDE(64, 64)
2676*77c1e3ccSAndroid Build Coastguard Worker
2677*77c1e3ccSAndroid Build Coastguard Worker #undef SMOOTH_NXM_WIDE
2678*77c1e3ccSAndroid Build Coastguard Worker
2679*77c1e3ccSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
2680*77c1e3ccSAndroid Build Coastguard Worker // SMOOTH_V_PRED
2681*77c1e3ccSAndroid Build Coastguard Worker
2682*77c1e3ccSAndroid Build Coastguard Worker // For widths 4 and 8.
2683*77c1e3ccSAndroid Build Coastguard Worker #define SMOOTH_V_PREDICTOR(W) \
2684*77c1e3ccSAndroid Build Coastguard Worker static void smooth_v_##W##xh_neon( \
2685*77c1e3ccSAndroid Build Coastguard Worker uint8_t *dst, ptrdiff_t stride, const uint8_t *const top_row, \
2686*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const left_column, const int height) { \
2687*77c1e3ccSAndroid Build Coastguard Worker const uint8_t bottom_left = left_column[height - 1]; \
2688*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const weights_y = smooth_weights + height - 4; \
2689*77c1e3ccSAndroid Build Coastguard Worker \
2690*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t top_v; \
2691*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 4) { \
2692*77c1e3ccSAndroid Build Coastguard Worker top_v = load_u8_4x1(top_row); \
2693*77c1e3ccSAndroid Build Coastguard Worker } else { /* width == 8 */ \
2694*77c1e3ccSAndroid Build Coastguard Worker top_v = vld1_u8(top_row); \
2695*77c1e3ccSAndroid Build Coastguard Worker } \
2696*77c1e3ccSAndroid Build Coastguard Worker \
2697*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t bottom_left_v = vdup_n_u8(bottom_left); \
2698*77c1e3ccSAndroid Build Coastguard Worker \
2699*77c1e3ccSAndroid Build Coastguard Worker assert(height > 0); \
2700*77c1e3ccSAndroid Build Coastguard Worker int y = 0; \
2701*77c1e3ccSAndroid Build Coastguard Worker do { \
2702*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t weights_y_v = vdup_n_u8(weights_y[y]); \
2703*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t scaled_weights_y = negate_s8(weights_y_v); \
2704*77c1e3ccSAndroid Build Coastguard Worker \
2705*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_top = vmull_u8(weights_y_v, top_v); \
2706*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_top_bl = \
2707*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_top, scaled_weights_y, bottom_left_v); \
2708*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t pred = \
2709*77c1e3ccSAndroid Build Coastguard Worker vrshrn_n_u16(weighted_top_bl, SMOOTH_WEIGHT_LOG2_SCALE); \
2710*77c1e3ccSAndroid Build Coastguard Worker \
2711*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 4) { \
2712*77c1e3ccSAndroid Build Coastguard Worker vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(pred), 0); \
2713*77c1e3ccSAndroid Build Coastguard Worker } else { /* width == 8 */ \
2714*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst, pred); \
2715*77c1e3ccSAndroid Build Coastguard Worker } \
2716*77c1e3ccSAndroid Build Coastguard Worker dst += stride; \
2717*77c1e3ccSAndroid Build Coastguard Worker } while (++y != height); \
2718*77c1e3ccSAndroid Build Coastguard Worker }
2719*77c1e3ccSAndroid Build Coastguard Worker
2720*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_PREDICTOR(4)
2721*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_PREDICTOR(8)
2722*77c1e3ccSAndroid Build Coastguard Worker
2723*77c1e3ccSAndroid Build Coastguard Worker #undef SMOOTH_V_PREDICTOR
2724*77c1e3ccSAndroid Build Coastguard Worker
2725*77c1e3ccSAndroid Build Coastguard Worker #define SMOOTH_V_NXM(W, H) \
2726*77c1e3ccSAndroid Build Coastguard Worker void aom_smooth_v_predictor_##W##x##H##_neon( \
2727*77c1e3ccSAndroid Build Coastguard Worker uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, \
2728*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
2729*77c1e3ccSAndroid Build Coastguard Worker smooth_v_##W##xh_neon(dst, y_stride, above, left, H); \
2730*77c1e3ccSAndroid Build Coastguard Worker }
2731*77c1e3ccSAndroid Build Coastguard Worker
2732*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2733*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM(4, 16)
2734*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM(8, 32)
2735*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2736*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM(4, 4)
2737*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM(4, 8)
2738*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM(8, 4)
2739*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM(8, 8)
2740*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM(8, 16)
2741*77c1e3ccSAndroid Build Coastguard Worker
2742*77c1e3ccSAndroid Build Coastguard Worker #undef SMOOTH_V_NXM
2743*77c1e3ccSAndroid Build Coastguard Worker
calculate_vertical_weights_and_pred(const uint8x16_t top,const uint8x8_t weights_y,const uint16x8_t weighted_bl)2744*77c1e3ccSAndroid Build Coastguard Worker static inline uint8x16_t calculate_vertical_weights_and_pred(
2745*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t top, const uint8x8_t weights_y,
2746*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_bl) {
2747*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t pred_low =
2748*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_bl, weights_y, vget_low_u8(top));
2749*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t pred_high =
2750*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_bl, weights_y, vget_high_u8(top));
2751*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t pred_scaled_low =
2752*77c1e3ccSAndroid Build Coastguard Worker vrshrn_n_u16(pred_low, SMOOTH_WEIGHT_LOG2_SCALE);
2753*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t pred_scaled_high =
2754*77c1e3ccSAndroid Build Coastguard Worker vrshrn_n_u16(pred_high, SMOOTH_WEIGHT_LOG2_SCALE);
2755*77c1e3ccSAndroid Build Coastguard Worker return vcombine_u8(pred_scaled_low, pred_scaled_high);
2756*77c1e3ccSAndroid Build Coastguard Worker }
2757*77c1e3ccSAndroid Build Coastguard Worker
2758*77c1e3ccSAndroid Build Coastguard Worker // For width 16 and above.
2759*77c1e3ccSAndroid Build Coastguard Worker #define SMOOTH_V_PREDICTOR(W) \
2760*77c1e3ccSAndroid Build Coastguard Worker static void smooth_v_##W##xh_neon( \
2761*77c1e3ccSAndroid Build Coastguard Worker uint8_t *dst, ptrdiff_t stride, const uint8_t *const top_row, \
2762*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const left_column, const int height) { \
2763*77c1e3ccSAndroid Build Coastguard Worker const uint8_t bottom_left = left_column[height - 1]; \
2764*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const weights_y = smooth_weights + height - 4; \
2765*77c1e3ccSAndroid Build Coastguard Worker \
2766*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t top_v[4]; \
2767*77c1e3ccSAndroid Build Coastguard Worker top_v[0] = vld1q_u8(top_row); \
2768*77c1e3ccSAndroid Build Coastguard Worker if ((W) > 16) { \
2769*77c1e3ccSAndroid Build Coastguard Worker top_v[1] = vld1q_u8(top_row + 16); \
2770*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 64) { \
2771*77c1e3ccSAndroid Build Coastguard Worker top_v[2] = vld1q_u8(top_row + 32); \
2772*77c1e3ccSAndroid Build Coastguard Worker top_v[3] = vld1q_u8(top_row + 48); \
2773*77c1e3ccSAndroid Build Coastguard Worker } \
2774*77c1e3ccSAndroid Build Coastguard Worker } \
2775*77c1e3ccSAndroid Build Coastguard Worker \
2776*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t bottom_left_v = vdup_n_u8(bottom_left); \
2777*77c1e3ccSAndroid Build Coastguard Worker \
2778*77c1e3ccSAndroid Build Coastguard Worker assert(height > 0); \
2779*77c1e3ccSAndroid Build Coastguard Worker int y = 0; \
2780*77c1e3ccSAndroid Build Coastguard Worker do { \
2781*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t weights_y_v = vdup_n_u8(weights_y[y]); \
2782*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t scaled_weights_y = negate_s8(weights_y_v); \
2783*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_bl = \
2784*77c1e3ccSAndroid Build Coastguard Worker vmull_u8(scaled_weights_y, bottom_left_v); \
2785*77c1e3ccSAndroid Build Coastguard Worker \
2786*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t pred_0 = calculate_vertical_weights_and_pred( \
2787*77c1e3ccSAndroid Build Coastguard Worker top_v[0], weights_y_v, weighted_bl); \
2788*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst, pred_0); \
2789*77c1e3ccSAndroid Build Coastguard Worker \
2790*77c1e3ccSAndroid Build Coastguard Worker if ((W) > 16) { \
2791*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t pred_1 = calculate_vertical_weights_and_pred( \
2792*77c1e3ccSAndroid Build Coastguard Worker top_v[1], weights_y_v, weighted_bl); \
2793*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, pred_1); \
2794*77c1e3ccSAndroid Build Coastguard Worker \
2795*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 64) { \
2796*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t pred_2 = calculate_vertical_weights_and_pred( \
2797*77c1e3ccSAndroid Build Coastguard Worker top_v[2], weights_y_v, weighted_bl); \
2798*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, pred_2); \
2799*77c1e3ccSAndroid Build Coastguard Worker \
2800*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t pred_3 = calculate_vertical_weights_and_pred( \
2801*77c1e3ccSAndroid Build Coastguard Worker top_v[3], weights_y_v, weighted_bl); \
2802*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, pred_3); \
2803*77c1e3ccSAndroid Build Coastguard Worker } \
2804*77c1e3ccSAndroid Build Coastguard Worker } \
2805*77c1e3ccSAndroid Build Coastguard Worker \
2806*77c1e3ccSAndroid Build Coastguard Worker dst += stride; \
2807*77c1e3ccSAndroid Build Coastguard Worker } while (++y != height); \
2808*77c1e3ccSAndroid Build Coastguard Worker }
2809*77c1e3ccSAndroid Build Coastguard Worker
2810*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_PREDICTOR(16)
2811*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_PREDICTOR(32)
2812*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_PREDICTOR(64)
2813*77c1e3ccSAndroid Build Coastguard Worker
2814*77c1e3ccSAndroid Build Coastguard Worker #undef SMOOTH_V_PREDICTOR
2815*77c1e3ccSAndroid Build Coastguard Worker
2816*77c1e3ccSAndroid Build Coastguard Worker #define SMOOTH_V_NXM_WIDE(W, H) \
2817*77c1e3ccSAndroid Build Coastguard Worker void aom_smooth_v_predictor_##W##x##H##_neon( \
2818*77c1e3ccSAndroid Build Coastguard Worker uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, \
2819*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
2820*77c1e3ccSAndroid Build Coastguard Worker smooth_v_##W##xh_neon(dst, y_stride, above, left, H); \
2821*77c1e3ccSAndroid Build Coastguard Worker }
2822*77c1e3ccSAndroid Build Coastguard Worker
2823*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2824*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(16, 4)
2825*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(32, 8)
2826*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(64, 16)
2827*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(16, 64)
2828*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2829*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(16, 8)
2830*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(16, 16)
2831*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(16, 32)
2832*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(32, 16)
2833*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(32, 32)
2834*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(32, 64)
2835*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(64, 32)
2836*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_V_NXM_WIDE(64, 64)
2837*77c1e3ccSAndroid Build Coastguard Worker
2838*77c1e3ccSAndroid Build Coastguard Worker #undef SMOOTH_V_NXM_WIDE
2839*77c1e3ccSAndroid Build Coastguard Worker
2840*77c1e3ccSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
2841*77c1e3ccSAndroid Build Coastguard Worker // SMOOTH_H_PRED
2842*77c1e3ccSAndroid Build Coastguard Worker
2843*77c1e3ccSAndroid Build Coastguard Worker // For widths 4 and 8.
2844*77c1e3ccSAndroid Build Coastguard Worker #define SMOOTH_H_PREDICTOR(W) \
2845*77c1e3ccSAndroid Build Coastguard Worker static void smooth_h_##W##xh_neon( \
2846*77c1e3ccSAndroid Build Coastguard Worker uint8_t *dst, ptrdiff_t stride, const uint8_t *const top_row, \
2847*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const left_column, const int height) { \
2848*77c1e3ccSAndroid Build Coastguard Worker const uint8_t top_right = top_row[(W)-1]; \
2849*77c1e3ccSAndroid Build Coastguard Worker \
2850*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t top_right_v = vdup_n_u8(top_right); \
2851*77c1e3ccSAndroid Build Coastguard Worker /* Over-reads for 4xN but still within the array. */ \
2852*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t weights_x = vld1_u8(smooth_weights + (W)-4); \
2853*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t scaled_weights_x = negate_s8(weights_x); \
2854*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_tr = vmull_u8(scaled_weights_x, top_right_v); \
2855*77c1e3ccSAndroid Build Coastguard Worker \
2856*77c1e3ccSAndroid Build Coastguard Worker assert(height > 0); \
2857*77c1e3ccSAndroid Build Coastguard Worker int y = 0; \
2858*77c1e3ccSAndroid Build Coastguard Worker do { \
2859*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left_v = vdup_n_u8(left_column[y]); \
2860*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_tr = \
2861*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_tr, weights_x, left_v); \
2862*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t pred = \
2863*77c1e3ccSAndroid Build Coastguard Worker vrshrn_n_u16(weighted_left_tr, SMOOTH_WEIGHT_LOG2_SCALE); \
2864*77c1e3ccSAndroid Build Coastguard Worker \
2865*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 4) { \
2866*77c1e3ccSAndroid Build Coastguard Worker vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(pred), 0); \
2867*77c1e3ccSAndroid Build Coastguard Worker } else { /* width == 8 */ \
2868*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dst, pred); \
2869*77c1e3ccSAndroid Build Coastguard Worker } \
2870*77c1e3ccSAndroid Build Coastguard Worker dst += stride; \
2871*77c1e3ccSAndroid Build Coastguard Worker } while (++y != height); \
2872*77c1e3ccSAndroid Build Coastguard Worker }
2873*77c1e3ccSAndroid Build Coastguard Worker
2874*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_PREDICTOR(4)
2875*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_PREDICTOR(8)
2876*77c1e3ccSAndroid Build Coastguard Worker
2877*77c1e3ccSAndroid Build Coastguard Worker #undef SMOOTH_H_PREDICTOR
2878*77c1e3ccSAndroid Build Coastguard Worker
2879*77c1e3ccSAndroid Build Coastguard Worker #define SMOOTH_H_NXM(W, H) \
2880*77c1e3ccSAndroid Build Coastguard Worker void aom_smooth_h_predictor_##W##x##H##_neon( \
2881*77c1e3ccSAndroid Build Coastguard Worker uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, \
2882*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
2883*77c1e3ccSAndroid Build Coastguard Worker smooth_h_##W##xh_neon(dst, y_stride, above, left, H); \
2884*77c1e3ccSAndroid Build Coastguard Worker }
2885*77c1e3ccSAndroid Build Coastguard Worker
2886*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2887*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM(4, 16)
2888*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM(8, 32)
2889*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2890*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM(4, 4)
2891*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM(4, 8)
2892*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM(8, 4)
2893*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM(8, 8)
2894*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM(8, 16)
2895*77c1e3ccSAndroid Build Coastguard Worker
2896*77c1e3ccSAndroid Build Coastguard Worker #undef SMOOTH_H_NXM
2897*77c1e3ccSAndroid Build Coastguard Worker
calculate_horizontal_weights_and_pred(const uint8x8_t left,const uint8x8_t top_right,const uint8x16_t weights_x,const uint8x16_t scaled_weights_x)2898*77c1e3ccSAndroid Build Coastguard Worker static inline uint8x16_t calculate_horizontal_weights_and_pred(
2899*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left, const uint8x8_t top_right, const uint8x16_t weights_x,
2900*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t scaled_weights_x) {
2901*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_low = vmull_u8(vget_low_u8(weights_x), left);
2902*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_tr_low =
2903*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_left_low, vget_low_u8(scaled_weights_x), top_right);
2904*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t pred_scaled_low =
2905*77c1e3ccSAndroid Build Coastguard Worker vrshrn_n_u16(weighted_left_tr_low, SMOOTH_WEIGHT_LOG2_SCALE);
2906*77c1e3ccSAndroid Build Coastguard Worker
2907*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_high = vmull_u8(vget_high_u8(weights_x), left);
2908*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t weighted_left_tr_high =
2909*77c1e3ccSAndroid Build Coastguard Worker vmlal_u8(weighted_left_high, vget_high_u8(scaled_weights_x), top_right);
2910*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t pred_scaled_high =
2911*77c1e3ccSAndroid Build Coastguard Worker vrshrn_n_u16(weighted_left_tr_high, SMOOTH_WEIGHT_LOG2_SCALE);
2912*77c1e3ccSAndroid Build Coastguard Worker
2913*77c1e3ccSAndroid Build Coastguard Worker return vcombine_u8(pred_scaled_low, pred_scaled_high);
2914*77c1e3ccSAndroid Build Coastguard Worker }
2915*77c1e3ccSAndroid Build Coastguard Worker
2916*77c1e3ccSAndroid Build Coastguard Worker // For width 16 and above.
2917*77c1e3ccSAndroid Build Coastguard Worker #define SMOOTH_H_PREDICTOR(W) \
2918*77c1e3ccSAndroid Build Coastguard Worker static void smooth_h_##W##xh_neon( \
2919*77c1e3ccSAndroid Build Coastguard Worker uint8_t *dst, ptrdiff_t stride, const uint8_t *const top_row, \
2920*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const left_column, const int height) { \
2921*77c1e3ccSAndroid Build Coastguard Worker const uint8_t top_right = top_row[(W)-1]; \
2922*77c1e3ccSAndroid Build Coastguard Worker \
2923*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t top_right_v = vdup_n_u8(top_right); \
2924*77c1e3ccSAndroid Build Coastguard Worker \
2925*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t weights_x[4]; \
2926*77c1e3ccSAndroid Build Coastguard Worker weights_x[0] = vld1q_u8(smooth_weights + (W)-4); \
2927*77c1e3ccSAndroid Build Coastguard Worker if ((W) > 16) { \
2928*77c1e3ccSAndroid Build Coastguard Worker weights_x[1] = vld1q_u8(smooth_weights + (W) + 16 - 4); \
2929*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 64) { \
2930*77c1e3ccSAndroid Build Coastguard Worker weights_x[2] = vld1q_u8(smooth_weights + (W) + 32 - 4); \
2931*77c1e3ccSAndroid Build Coastguard Worker weights_x[3] = vld1q_u8(smooth_weights + (W) + 48 - 4); \
2932*77c1e3ccSAndroid Build Coastguard Worker } \
2933*77c1e3ccSAndroid Build Coastguard Worker } \
2934*77c1e3ccSAndroid Build Coastguard Worker \
2935*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t scaled_weights_x[4]; \
2936*77c1e3ccSAndroid Build Coastguard Worker scaled_weights_x[0] = negate_s8q(weights_x[0]); \
2937*77c1e3ccSAndroid Build Coastguard Worker if ((W) > 16) { \
2938*77c1e3ccSAndroid Build Coastguard Worker scaled_weights_x[1] = negate_s8q(weights_x[1]); \
2939*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 64) { \
2940*77c1e3ccSAndroid Build Coastguard Worker scaled_weights_x[2] = negate_s8q(weights_x[2]); \
2941*77c1e3ccSAndroid Build Coastguard Worker scaled_weights_x[3] = negate_s8q(weights_x[3]); \
2942*77c1e3ccSAndroid Build Coastguard Worker } \
2943*77c1e3ccSAndroid Build Coastguard Worker } \
2944*77c1e3ccSAndroid Build Coastguard Worker \
2945*77c1e3ccSAndroid Build Coastguard Worker assert(height > 0); \
2946*77c1e3ccSAndroid Build Coastguard Worker int y = 0; \
2947*77c1e3ccSAndroid Build Coastguard Worker do { \
2948*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left_v = vdup_n_u8(left_column[y]); \
2949*77c1e3ccSAndroid Build Coastguard Worker \
2950*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t pred_0 = calculate_horizontal_weights_and_pred( \
2951*77c1e3ccSAndroid Build Coastguard Worker left_v, top_right_v, weights_x[0], scaled_weights_x[0]); \
2952*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst, pred_0); \
2953*77c1e3ccSAndroid Build Coastguard Worker \
2954*77c1e3ccSAndroid Build Coastguard Worker if ((W) > 16) { \
2955*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t pred_1 = calculate_horizontal_weights_and_pred( \
2956*77c1e3ccSAndroid Build Coastguard Worker left_v, top_right_v, weights_x[1], scaled_weights_x[1]); \
2957*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 16, pred_1); \
2958*77c1e3ccSAndroid Build Coastguard Worker \
2959*77c1e3ccSAndroid Build Coastguard Worker if ((W) == 64) { \
2960*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t pred_2 = calculate_horizontal_weights_and_pred( \
2961*77c1e3ccSAndroid Build Coastguard Worker left_v, top_right_v, weights_x[2], scaled_weights_x[2]); \
2962*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 32, pred_2); \
2963*77c1e3ccSAndroid Build Coastguard Worker \
2964*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t pred_3 = calculate_horizontal_weights_and_pred( \
2965*77c1e3ccSAndroid Build Coastguard Worker left_v, top_right_v, weights_x[3], scaled_weights_x[3]); \
2966*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dst + 48, pred_3); \
2967*77c1e3ccSAndroid Build Coastguard Worker } \
2968*77c1e3ccSAndroid Build Coastguard Worker } \
2969*77c1e3ccSAndroid Build Coastguard Worker dst += stride; \
2970*77c1e3ccSAndroid Build Coastguard Worker } while (++y != height); \
2971*77c1e3ccSAndroid Build Coastguard Worker }
2972*77c1e3ccSAndroid Build Coastguard Worker
2973*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_PREDICTOR(16)
2974*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_PREDICTOR(32)
2975*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_PREDICTOR(64)
2976*77c1e3ccSAndroid Build Coastguard Worker
2977*77c1e3ccSAndroid Build Coastguard Worker #undef SMOOTH_H_PREDICTOR
2978*77c1e3ccSAndroid Build Coastguard Worker
2979*77c1e3ccSAndroid Build Coastguard Worker #define SMOOTH_H_NXM_WIDE(W, H) \
2980*77c1e3ccSAndroid Build Coastguard Worker void aom_smooth_h_predictor_##W##x##H##_neon( \
2981*77c1e3ccSAndroid Build Coastguard Worker uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, \
2982*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
2983*77c1e3ccSAndroid Build Coastguard Worker smooth_h_##W##xh_neon(dst, y_stride, above, left, H); \
2984*77c1e3ccSAndroid Build Coastguard Worker }
2985*77c1e3ccSAndroid Build Coastguard Worker
2986*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2987*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(16, 4)
2988*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(16, 64)
2989*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(32, 8)
2990*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(64, 16)
2991*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
2992*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(16, 8)
2993*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(16, 16)
2994*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(16, 32)
2995*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(32, 16)
2996*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(32, 32)
2997*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(32, 64)
2998*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(64, 32)
2999*77c1e3ccSAndroid Build Coastguard Worker SMOOTH_H_NXM_WIDE(64, 64)
3000*77c1e3ccSAndroid Build Coastguard Worker
3001*77c1e3ccSAndroid Build Coastguard Worker #undef SMOOTH_H_NXM_WIDE
3002*77c1e3ccSAndroid Build Coastguard Worker
3003*77c1e3ccSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
3004*77c1e3ccSAndroid Build Coastguard Worker // PAETH
3005*77c1e3ccSAndroid Build Coastguard Worker
paeth_4or8_x_h_neon(uint8_t * dest,ptrdiff_t stride,const uint8_t * const top_row,const uint8_t * const left_column,int width,int height)3006*77c1e3ccSAndroid Build Coastguard Worker static inline void paeth_4or8_x_h_neon(uint8_t *dest, ptrdiff_t stride,
3007*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const top_row,
3008*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const left_column,
3009*77c1e3ccSAndroid Build Coastguard Worker int width, int height) {
3010*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t top_left = vdup_n_u8(top_row[-1]);
3011*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t top_left_x2 = vdupq_n_u16(top_row[-1] + top_row[-1]);
3012*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t top;
3013*77c1e3ccSAndroid Build Coastguard Worker if (width == 4) {
3014*77c1e3ccSAndroid Build Coastguard Worker top = load_u8_4x1(top_row);
3015*77c1e3ccSAndroid Build Coastguard Worker } else { // width == 8
3016*77c1e3ccSAndroid Build Coastguard Worker top = vld1_u8(top_row);
3017*77c1e3ccSAndroid Build Coastguard Worker }
3018*77c1e3ccSAndroid Build Coastguard Worker
3019*77c1e3ccSAndroid Build Coastguard Worker assert(height > 0);
3020*77c1e3ccSAndroid Build Coastguard Worker int y = 0;
3021*77c1e3ccSAndroid Build Coastguard Worker do {
3022*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left = vdup_n_u8(left_column[y]);
3023*77c1e3ccSAndroid Build Coastguard Worker
3024*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left_dist = vabd_u8(top, top_left);
3025*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t top_dist = vabd_u8(left, top_left);
3026*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t top_left_dist =
3027*77c1e3ccSAndroid Build Coastguard Worker vabdq_u16(vaddl_u8(top, left), top_left_x2);
3028*77c1e3ccSAndroid Build Coastguard Worker
3029*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left_le_top = vcle_u8(left_dist, top_dist);
3030*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left_le_top_left =
3031*77c1e3ccSAndroid Build Coastguard Worker vmovn_u16(vcleq_u16(vmovl_u8(left_dist), top_left_dist));
3032*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t top_le_top_left =
3033*77c1e3ccSAndroid Build Coastguard Worker vmovn_u16(vcleq_u16(vmovl_u8(top_dist), top_left_dist));
3034*77c1e3ccSAndroid Build Coastguard Worker
3035*77c1e3ccSAndroid Build Coastguard Worker // if (left_dist <= top_dist && left_dist <= top_left_dist)
3036*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left_mask = vand_u8(left_le_top, left_le_top_left);
3037*77c1e3ccSAndroid Build Coastguard Worker // dest[x] = left_column[y];
3038*77c1e3ccSAndroid Build Coastguard Worker // Fill all the unused spaces with 'top'. They will be overwritten when
3039*77c1e3ccSAndroid Build Coastguard Worker // the positions for top_left are known.
3040*77c1e3ccSAndroid Build Coastguard Worker uint8x8_t result = vbsl_u8(left_mask, left, top);
3041*77c1e3ccSAndroid Build Coastguard Worker // else if (top_dist <= top_left_dist)
3042*77c1e3ccSAndroid Build Coastguard Worker // dest[x] = top_row[x];
3043*77c1e3ccSAndroid Build Coastguard Worker // Add these values to the mask. They were already set.
3044*77c1e3ccSAndroid Build Coastguard Worker const uint8x8_t left_or_top_mask = vorr_u8(left_mask, top_le_top_left);
3045*77c1e3ccSAndroid Build Coastguard Worker // else
3046*77c1e3ccSAndroid Build Coastguard Worker // dest[x] = top_left;
3047*77c1e3ccSAndroid Build Coastguard Worker result = vbsl_u8(left_or_top_mask, result, top_left);
3048*77c1e3ccSAndroid Build Coastguard Worker
3049*77c1e3ccSAndroid Build Coastguard Worker if (width == 4) {
3050*77c1e3ccSAndroid Build Coastguard Worker store_u8_4x1(dest, result);
3051*77c1e3ccSAndroid Build Coastguard Worker } else { // width == 8
3052*77c1e3ccSAndroid Build Coastguard Worker vst1_u8(dest, result);
3053*77c1e3ccSAndroid Build Coastguard Worker }
3054*77c1e3ccSAndroid Build Coastguard Worker dest += stride;
3055*77c1e3ccSAndroid Build Coastguard Worker } while (++y != height);
3056*77c1e3ccSAndroid Build Coastguard Worker }
3057*77c1e3ccSAndroid Build Coastguard Worker
3058*77c1e3ccSAndroid Build Coastguard Worker #define PAETH_NXM(W, H) \
3059*77c1e3ccSAndroid Build Coastguard Worker void aom_paeth_predictor_##W##x##H##_neon(uint8_t *dst, ptrdiff_t stride, \
3060*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, \
3061*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
3062*77c1e3ccSAndroid Build Coastguard Worker paeth_4or8_x_h_neon(dst, stride, above, left, W, H); \
3063*77c1e3ccSAndroid Build Coastguard Worker }
3064*77c1e3ccSAndroid Build Coastguard Worker
3065*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3066*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM(4, 16)
3067*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM(8, 32)
3068*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3069*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM(4, 4)
3070*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM(4, 8)
3071*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM(8, 4)
3072*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM(8, 8)
3073*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM(8, 16)
3074*77c1e3ccSAndroid Build Coastguard Worker
3075*77c1e3ccSAndroid Build Coastguard Worker // Calculate X distance <= TopLeft distance and pack the resulting mask into
3076*77c1e3ccSAndroid Build Coastguard Worker // uint8x8_t.
x_le_top_left(const uint8x16_t x_dist,const uint16x8_t top_left_dist_low,const uint16x8_t top_left_dist_high)3077*77c1e3ccSAndroid Build Coastguard Worker static inline uint8x16_t x_le_top_left(const uint8x16_t x_dist,
3078*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t top_left_dist_low,
3079*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t top_left_dist_high) {
3080*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t top_left_dist = vcombine_u8(vqmovn_u16(top_left_dist_low),
3081*77c1e3ccSAndroid Build Coastguard Worker vqmovn_u16(top_left_dist_high));
3082*77c1e3ccSAndroid Build Coastguard Worker return vcleq_u8(x_dist, top_left_dist);
3083*77c1e3ccSAndroid Build Coastguard Worker }
3084*77c1e3ccSAndroid Build Coastguard Worker
3085*77c1e3ccSAndroid Build Coastguard Worker // Select the closest values and collect them.
select_paeth(const uint8x16_t top,const uint8x16_t left,const uint8x16_t top_left,const uint8x16_t left_le_top,const uint8x16_t left_le_top_left,const uint8x16_t top_le_top_left)3086*77c1e3ccSAndroid Build Coastguard Worker static inline uint8x16_t select_paeth(const uint8x16_t top,
3087*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left,
3088*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t top_left,
3089*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_le_top,
3090*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_le_top_left,
3091*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t top_le_top_left) {
3092*77c1e3ccSAndroid Build Coastguard Worker // if (left_dist <= top_dist && left_dist <= top_left_dist)
3093*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_mask = vandq_u8(left_le_top, left_le_top_left);
3094*77c1e3ccSAndroid Build Coastguard Worker // dest[x] = left_column[y];
3095*77c1e3ccSAndroid Build Coastguard Worker // Fill all the unused spaces with 'top'. They will be overwritten when
3096*77c1e3ccSAndroid Build Coastguard Worker // the positions for top_left are known.
3097*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t result = vbslq_u8(left_mask, left, top);
3098*77c1e3ccSAndroid Build Coastguard Worker // else if (top_dist <= top_left_dist)
3099*77c1e3ccSAndroid Build Coastguard Worker // dest[x] = top_row[x];
3100*77c1e3ccSAndroid Build Coastguard Worker // Add these values to the mask. They were already set.
3101*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_or_top_mask = vorrq_u8(left_mask, top_le_top_left);
3102*77c1e3ccSAndroid Build Coastguard Worker // else
3103*77c1e3ccSAndroid Build Coastguard Worker // dest[x] = top_left;
3104*77c1e3ccSAndroid Build Coastguard Worker return vbslq_u8(left_or_top_mask, result, top_left);
3105*77c1e3ccSAndroid Build Coastguard Worker }
3106*77c1e3ccSAndroid Build Coastguard Worker
3107*77c1e3ccSAndroid Build Coastguard Worker // Generate numbered and high/low versions of top_left_dist.
3108*77c1e3ccSAndroid Build Coastguard Worker #define TOP_LEFT_DIST(num) \
3109*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t top_left_##num##_dist_low = vabdq_u16( \
3110*77c1e3ccSAndroid Build Coastguard Worker vaddl_u8(vget_low_u8(top[num]), vget_low_u8(left)), top_left_x2); \
3111*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t top_left_##num##_dist_high = vabdq_u16( \
3112*77c1e3ccSAndroid Build Coastguard Worker vaddl_u8(vget_high_u8(top[num]), vget_low_u8(left)), top_left_x2)
3113*77c1e3ccSAndroid Build Coastguard Worker
3114*77c1e3ccSAndroid Build Coastguard Worker // Generate numbered versions of XLeTopLeft with x = left.
3115*77c1e3ccSAndroid Build Coastguard Worker #define LEFT_LE_TOP_LEFT(num) \
3116*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_le_top_left_##num = \
3117*77c1e3ccSAndroid Build Coastguard Worker x_le_top_left(left_##num##_dist, top_left_##num##_dist_low, \
3118*77c1e3ccSAndroid Build Coastguard Worker top_left_##num##_dist_high)
3119*77c1e3ccSAndroid Build Coastguard Worker
3120*77c1e3ccSAndroid Build Coastguard Worker // Generate numbered versions of XLeTopLeft with x = top.
3121*77c1e3ccSAndroid Build Coastguard Worker #define TOP_LE_TOP_LEFT(num) \
3122*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t top_le_top_left_##num = x_le_top_left( \
3123*77c1e3ccSAndroid Build Coastguard Worker top_dist, top_left_##num##_dist_low, top_left_##num##_dist_high)
3124*77c1e3ccSAndroid Build Coastguard Worker
paeth16_plus_x_h_neon(uint8_t * dest,ptrdiff_t stride,const uint8_t * const top_row,const uint8_t * const left_column,int width,int height)3125*77c1e3ccSAndroid Build Coastguard Worker static inline void paeth16_plus_x_h_neon(uint8_t *dest, ptrdiff_t stride,
3126*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const top_row,
3127*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *const left_column,
3128*77c1e3ccSAndroid Build Coastguard Worker int width, int height) {
3129*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t top_left = vdupq_n_u8(top_row[-1]);
3130*77c1e3ccSAndroid Build Coastguard Worker const uint16x8_t top_left_x2 = vdupq_n_u16(top_row[-1] + top_row[-1]);
3131*77c1e3ccSAndroid Build Coastguard Worker uint8x16_t top[4];
3132*77c1e3ccSAndroid Build Coastguard Worker top[0] = vld1q_u8(top_row);
3133*77c1e3ccSAndroid Build Coastguard Worker if (width > 16) {
3134*77c1e3ccSAndroid Build Coastguard Worker top[1] = vld1q_u8(top_row + 16);
3135*77c1e3ccSAndroid Build Coastguard Worker if (width == 64) {
3136*77c1e3ccSAndroid Build Coastguard Worker top[2] = vld1q_u8(top_row + 32);
3137*77c1e3ccSAndroid Build Coastguard Worker top[3] = vld1q_u8(top_row + 48);
3138*77c1e3ccSAndroid Build Coastguard Worker }
3139*77c1e3ccSAndroid Build Coastguard Worker }
3140*77c1e3ccSAndroid Build Coastguard Worker
3141*77c1e3ccSAndroid Build Coastguard Worker assert(height > 0);
3142*77c1e3ccSAndroid Build Coastguard Worker int y = 0;
3143*77c1e3ccSAndroid Build Coastguard Worker do {
3144*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left = vdupq_n_u8(left_column[y]);
3145*77c1e3ccSAndroid Build Coastguard Worker
3146*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t top_dist = vabdq_u8(left, top_left);
3147*77c1e3ccSAndroid Build Coastguard Worker
3148*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_0_dist = vabdq_u8(top[0], top_left);
3149*77c1e3ccSAndroid Build Coastguard Worker TOP_LEFT_DIST(0);
3150*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_0_le_top = vcleq_u8(left_0_dist, top_dist);
3151*77c1e3ccSAndroid Build Coastguard Worker LEFT_LE_TOP_LEFT(0);
3152*77c1e3ccSAndroid Build Coastguard Worker TOP_LE_TOP_LEFT(0);
3153*77c1e3ccSAndroid Build Coastguard Worker
3154*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t result_0 =
3155*77c1e3ccSAndroid Build Coastguard Worker select_paeth(top[0], left, top_left, left_0_le_top, left_le_top_left_0,
3156*77c1e3ccSAndroid Build Coastguard Worker top_le_top_left_0);
3157*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dest, result_0);
3158*77c1e3ccSAndroid Build Coastguard Worker
3159*77c1e3ccSAndroid Build Coastguard Worker if (width > 16) {
3160*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_1_dist = vabdq_u8(top[1], top_left);
3161*77c1e3ccSAndroid Build Coastguard Worker TOP_LEFT_DIST(1);
3162*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_1_le_top = vcleq_u8(left_1_dist, top_dist);
3163*77c1e3ccSAndroid Build Coastguard Worker LEFT_LE_TOP_LEFT(1);
3164*77c1e3ccSAndroid Build Coastguard Worker TOP_LE_TOP_LEFT(1);
3165*77c1e3ccSAndroid Build Coastguard Worker
3166*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t result_1 =
3167*77c1e3ccSAndroid Build Coastguard Worker select_paeth(top[1], left, top_left, left_1_le_top,
3168*77c1e3ccSAndroid Build Coastguard Worker left_le_top_left_1, top_le_top_left_1);
3169*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dest + 16, result_1);
3170*77c1e3ccSAndroid Build Coastguard Worker
3171*77c1e3ccSAndroid Build Coastguard Worker if (width == 64) {
3172*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_2_dist = vabdq_u8(top[2], top_left);
3173*77c1e3ccSAndroid Build Coastguard Worker TOP_LEFT_DIST(2);
3174*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_2_le_top = vcleq_u8(left_2_dist, top_dist);
3175*77c1e3ccSAndroid Build Coastguard Worker LEFT_LE_TOP_LEFT(2);
3176*77c1e3ccSAndroid Build Coastguard Worker TOP_LE_TOP_LEFT(2);
3177*77c1e3ccSAndroid Build Coastguard Worker
3178*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t result_2 =
3179*77c1e3ccSAndroid Build Coastguard Worker select_paeth(top[2], left, top_left, left_2_le_top,
3180*77c1e3ccSAndroid Build Coastguard Worker left_le_top_left_2, top_le_top_left_2);
3181*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dest + 32, result_2);
3182*77c1e3ccSAndroid Build Coastguard Worker
3183*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_3_dist = vabdq_u8(top[3], top_left);
3184*77c1e3ccSAndroid Build Coastguard Worker TOP_LEFT_DIST(3);
3185*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t left_3_le_top = vcleq_u8(left_3_dist, top_dist);
3186*77c1e3ccSAndroid Build Coastguard Worker LEFT_LE_TOP_LEFT(3);
3187*77c1e3ccSAndroid Build Coastguard Worker TOP_LE_TOP_LEFT(3);
3188*77c1e3ccSAndroid Build Coastguard Worker
3189*77c1e3ccSAndroid Build Coastguard Worker const uint8x16_t result_3 =
3190*77c1e3ccSAndroid Build Coastguard Worker select_paeth(top[3], left, top_left, left_3_le_top,
3191*77c1e3ccSAndroid Build Coastguard Worker left_le_top_left_3, top_le_top_left_3);
3192*77c1e3ccSAndroid Build Coastguard Worker vst1q_u8(dest + 48, result_3);
3193*77c1e3ccSAndroid Build Coastguard Worker }
3194*77c1e3ccSAndroid Build Coastguard Worker }
3195*77c1e3ccSAndroid Build Coastguard Worker
3196*77c1e3ccSAndroid Build Coastguard Worker dest += stride;
3197*77c1e3ccSAndroid Build Coastguard Worker } while (++y != height);
3198*77c1e3ccSAndroid Build Coastguard Worker }
3199*77c1e3ccSAndroid Build Coastguard Worker
3200*77c1e3ccSAndroid Build Coastguard Worker #define PAETH_NXM_WIDE(W, H) \
3201*77c1e3ccSAndroid Build Coastguard Worker void aom_paeth_predictor_##W##x##H##_neon(uint8_t *dst, ptrdiff_t stride, \
3202*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *above, \
3203*77c1e3ccSAndroid Build Coastguard Worker const uint8_t *left) { \
3204*77c1e3ccSAndroid Build Coastguard Worker paeth16_plus_x_h_neon(dst, stride, above, left, W, H); \
3205*77c1e3ccSAndroid Build Coastguard Worker }
3206*77c1e3ccSAndroid Build Coastguard Worker
3207*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3208*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(16, 4)
3209*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(16, 64)
3210*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(32, 8)
3211*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(64, 16)
3212*77c1e3ccSAndroid Build Coastguard Worker #endif // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
3213*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(16, 8)
3214*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(16, 16)
3215*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(16, 32)
3216*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(32, 16)
3217*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(32, 32)
3218*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(32, 64)
3219*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(64, 32)
3220*77c1e3ccSAndroid Build Coastguard Worker PAETH_NXM_WIDE(64, 64)
3221