Refactor I8MM av1_convolve_x_sr_neon 8-tap path
Remove unnecessary variable forward declarations, rename the convolve
helper functions and pull them into the .c file since they're not
used anywhere else.
Change-Id: I31caf46eb063f41a4b82db8299c62b59fc2ceac9
diff --git a/av1/common/arm/convolve_neon.c b/av1/common/arm/convolve_neon.c
index a46cb16..2e973b1 100644
--- a/av1/common/arm/convolve_neon.c
+++ b/av1/common/arm/convolve_neon.c
@@ -202,6 +202,52 @@
}
}
+static INLINE int16x4_t convolve8_4_x(uint8x16_t samples, const int8x8_t filter,
+ const uint8x16x2_t permute_tbl,
+ const int32x4_t horiz_const) {
+ uint8x16_t permuted_samples[2];
+ int32x4_t sum;
+
+ // Permute samples ready for dot product.
+ // { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 }
+ permuted_samples[0] = vqtbl1q_u8(samples, permute_tbl.val[0]);
+ // { 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 }
+ permuted_samples[1] = vqtbl1q_u8(samples, permute_tbl.val[1]);
+
+ // First 4 output values.
+ sum = vusdotq_lane_s32(horiz_const, permuted_samples[0], filter, 0);
+ sum = vusdotq_lane_s32(sum, permuted_samples[1], filter, 1);
+
+ // Packing is performed by the caller.
+ return vmovn_s32(sum);
+}
+
+static INLINE uint8x8_t convolve8_8_x(uint8x16_t samples, const int8x8_t filter,
+ const uint8x16x3_t permute_tbl,
+ const int32x4_t horiz_const) {
+ uint8x16_t permuted_samples[3];
+ int32x4_t sum[2];
+
+ // Permute samples ready for dot product.
+ // { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 }
+ permuted_samples[0] = vqtbl1q_u8(samples, permute_tbl.val[0]);
+ // { 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 }
+ permuted_samples[1] = vqtbl1q_u8(samples, permute_tbl.val[1]);
+ // { 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14 }
+ permuted_samples[2] = vqtbl1q_u8(samples, permute_tbl.val[2]);
+
+ // First 4 output values.
+ sum[0] = vusdotq_lane_s32(horiz_const, permuted_samples[0], filter, 0);
+ sum[0] = vusdotq_lane_s32(sum[0], permuted_samples[1], filter, 1);
+ // Second 4 output values.
+ sum[1] = vusdotq_lane_s32(horiz_const, permuted_samples[1], filter, 0);
+ sum[1] = vusdotq_lane_s32(sum[1], permuted_samples[2], filter, 1);
+
+ int16x8_t sum_s16 = vcombine_s16(vmovn_s32(sum[0]), vmovn_s32(sum[1]));
+ // We halved the convolution filter values so - 1 from the right shift.
+ return vqrshrun_n_s16(sum_s16, FILTER_BITS - 1);
+}
+
void av1_convolve_x_sr_neon(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
const InterpFilterParams *filter_params_x,
@@ -209,10 +255,10 @@
ConvolveParams *conv_params) {
(void)conv_params;
const uint8_t horiz_offset = filter_params_x->taps / 2 - 1;
+ src -= horiz_offset;
const int16_t *x_filter_ptr = av1_get_interp_filter_subpel_kernel(
filter_params_x, subpel_x_qn & SUBPEL_MASK);
- src -= horiz_offset;
if (filter_params_x->taps > 8) {
convolve_x_sr_12tap_neon(src, src_stride, dst, dst_stride, w, h,
@@ -220,7 +266,7 @@
return;
}
- // Filter values are even, so downshift by 1 to reduce intermediate precision
+ // Filter values are even, so halve to reduce intermediate precision
// requirements.
const int8x8_t x_filter = vshrn_n_s16(vld1q_s16(x_filter_ptr), 1);
// This shim of 1 << ((ROUND0_BITS - 1) - 1) enables us to use a single
@@ -232,25 +278,19 @@
if (w <= 4) {
const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl);
- uint8x16_t s0, s1, s2, s3;
- int32x4_t t0, t1, t2, t3;
- int16x8_t t01, t23;
- uint8x8_t d01, d23;
do {
+ uint8x16_t s0, s1, s2, s3;
load_u8_16x4(src, src_stride, &s0, &s1, &s2, &s3);
- t0 = convolve8_4_usdot(s0, x_filter, permute_tbl, horiz_const);
- t1 = convolve8_4_usdot(s1, x_filter, permute_tbl, horiz_const);
- t2 = convolve8_4_usdot(s2, x_filter, permute_tbl, horiz_const);
- t3 = convolve8_4_usdot(s3, x_filter, permute_tbl, horiz_const);
-
- t01 = vcombine_s16(vmovn_s32(t0), vmovn_s32(t1));
- t23 = vcombine_s16(vmovn_s32(t2), vmovn_s32(t3));
+ int16x4_t d0 = convolve8_4_x(s0, x_filter, permute_tbl, horiz_const);
+ int16x4_t d1 = convolve8_4_x(s1, x_filter, permute_tbl, horiz_const);
+ int16x4_t d2 = convolve8_4_x(s2, x_filter, permute_tbl, horiz_const);
+ int16x4_t d3 = convolve8_4_x(s3, x_filter, permute_tbl, horiz_const);
// We halved the convolution filter values so - 1 from the right shift.
- d01 = vqrshrun_n_s16(t01, FILTER_BITS - 1);
- d23 = vqrshrun_n_s16(t23, FILTER_BITS - 1);
+ uint8x8_t d01 = vqrshrun_n_s16(vcombine_s16(d0, d1), FILTER_BITS - 1);
+ uint8x8_t d23 = vqrshrun_n_s16(vcombine_s16(d2, d3), FILTER_BITS - 1);
if (w == 2) {
store_u8_2x1(dst + 0 * dst_stride, d01, 0);
@@ -268,35 +308,27 @@
}
}
- h -= 4;
src += 4 * src_stride;
dst += 4 * dst_stride;
+ h -= 4;
} while (h > 0);
} else {
const uint8x16x3_t permute_tbl = vld1q_u8_x3(dot_prod_permute_tbl);
- uint8x16_t s0, s1, s2, s3;
- int16x8_t t0, t1, t2, t3;
- uint8x8_t d0, d1, d2, d3;
do {
- int width = w;
const uint8_t *s = src;
uint8_t *d = dst;
+ int width = w;
do {
+ uint8x16_t s0, s1, s2, s3;
load_u8_16x4(s, src_stride, &s0, &s1, &s2, &s3);
- t0 = convolve8_x_8_usdot(s0, x_filter, permute_tbl, horiz_const);
- t1 = convolve8_x_8_usdot(s1, x_filter, permute_tbl, horiz_const);
- t2 = convolve8_x_8_usdot(s2, x_filter, permute_tbl, horiz_const);
- t3 = convolve8_x_8_usdot(s3, x_filter, permute_tbl, horiz_const);
-
- // We halved the convolution filter values so - 1 from the right shift.
- d0 = vqrshrun_n_s16(t0, FILTER_BITS - 1);
- d1 = vqrshrun_n_s16(t1, FILTER_BITS - 1);
- d2 = vqrshrun_n_s16(t2, FILTER_BITS - 1);
- d3 = vqrshrun_n_s16(t3, FILTER_BITS - 1);
+ uint8x8_t d0 = convolve8_8_x(s0, x_filter, permute_tbl, horiz_const);
+ uint8x8_t d1 = convolve8_8_x(s1, x_filter, permute_tbl, horiz_const);
+ uint8x8_t d2 = convolve8_8_x(s2, x_filter, permute_tbl, horiz_const);
+ uint8x8_t d3 = convolve8_8_x(s3, x_filter, permute_tbl, horiz_const);
vst1_u8(d + 0 * dst_stride, d0);
vst1_u8(d + 1 * dst_stride, d1);
@@ -309,7 +341,6 @@
d += 8;
width -= 8;
} while (width > 0);
-
src += 4 * src_stride;
dst += 4 * dst_stride;
h -= 4;
diff --git a/av1/common/arm/convolve_neon.h b/av1/common/arm/convolve_neon.h
index 899c790..462bcd1 100644
--- a/av1/common/arm/convolve_neon.h
+++ b/av1/common/arm/convolve_neon.h
@@ -221,54 +221,4 @@
#endif // AOM_ARCH_AARCH64 && defined(__ARM_FEATURE_DOTPROD)
-#if AOM_ARCH_AARCH64 && defined(__ARM_FEATURE_MATMUL_INT8)
-
-static INLINE int16x8_t convolve8_x_8_usdot(uint8x16_t samples,
- const int8x8_t filters,
- const uint8x16x3_t permute_tbl,
- const int32x4_t horiz_const) {
- uint8x16_t permuted_samples[3];
- int32x4_t sum[2];
-
- /* Permute samples ready for dot product. */
- /* { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 } */
- permuted_samples[0] = vqtbl1q_u8(samples, permute_tbl.val[0]);
- /* { 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 } */
- permuted_samples[1] = vqtbl1q_u8(samples, permute_tbl.val[1]);
- /* { 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14 } */
- permuted_samples[2] = vqtbl1q_u8(samples, permute_tbl.val[2]);
-
- /* First 4 output values. */
- sum[0] = vusdotq_lane_s32(horiz_const, permuted_samples[0], filters, 0);
- sum[0] = vusdotq_lane_s32(sum[0], permuted_samples[1], filters, 1);
- /* Second 4 output values. */
- sum[1] = vusdotq_lane_s32(horiz_const, permuted_samples[1], filters, 0);
- sum[1] = vusdotq_lane_s32(sum[1], permuted_samples[2], filters, 1);
-
- return vcombine_s16(vmovn_s32(sum[0]), vmovn_s32(sum[1]));
-}
-
-static INLINE int32x4_t convolve8_4_usdot(uint8x16_t samples,
- const int8x8_t filters,
- const uint8x16x2_t permute_tbl,
- const int32x4_t horiz_const) {
- uint8x16_t permuted_samples[2];
- int32x4_t sum;
-
- /* Permute samples ready for dot product. */
- /* { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 } */
- permuted_samples[0] = vqtbl1q_u8(samples, permute_tbl.val[0]);
- /* { 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 } */
- permuted_samples[1] = vqtbl1q_u8(samples, permute_tbl.val[1]);
-
- /* First 4 output values. */
- sum = vusdotq_lane_s32(horiz_const, permuted_samples[0], filters, 0);
- sum = vusdotq_lane_s32(sum, permuted_samples[1], filters, 1);
-
- /* Narrowing and packing is performed by the caller. */
- return sum;
-}
-
-#endif // AOM_ARCH_AARCH64 && defined(__ARM_FEATURE_MATMUL_INT8)
-
#endif // AOM_AV1_COMMON_ARM_CONVOLVE_NEON_H_