Merge "cosmetic: clean idct neon functions"

This commit is contained in:
Linfeng Zhang 2018-01-29 17:34:11 +00:00 committed by Gerrit Code Review
commit 2654afc16c
8 changed files with 539 additions and 615 deletions

View File

@ -124,83 +124,77 @@ static INLINE void do_butterfly(const int32x4x2_t qIn0, const int32x4x2_t qIn1,
vrshrn_n_s64(q[3].val[1], DCT_CONST_BITS));
}
static INLINE void load_s32x4q_dual(
const int32_t *in, int32x4x2_t *const s0, int32x4x2_t *const s1,
int32x4x2_t *const s2, int32x4x2_t *const s3, int32x4x2_t *const s4,
int32x4x2_t *const s5, int32x4x2_t *const s6, int32x4x2_t *const s7) {
s0->val[0] = vld1q_s32(in);
s0->val[1] = vld1q_s32(in + 4);
static INLINE void load_s32x4q_dual(const int32_t *in, int32x4x2_t *const s) {
s[0].val[0] = vld1q_s32(in);
s[0].val[1] = vld1q_s32(in + 4);
in += 32;
s1->val[0] = vld1q_s32(in);
s1->val[1] = vld1q_s32(in + 4);
s[1].val[0] = vld1q_s32(in);
s[1].val[1] = vld1q_s32(in + 4);
in += 32;
s2->val[0] = vld1q_s32(in);
s2->val[1] = vld1q_s32(in + 4);
s[2].val[0] = vld1q_s32(in);
s[2].val[1] = vld1q_s32(in + 4);
in += 32;
s3->val[0] = vld1q_s32(in);
s3->val[1] = vld1q_s32(in + 4);
s[3].val[0] = vld1q_s32(in);
s[3].val[1] = vld1q_s32(in + 4);
in += 32;
s4->val[0] = vld1q_s32(in);
s4->val[1] = vld1q_s32(in + 4);
s[4].val[0] = vld1q_s32(in);
s[4].val[1] = vld1q_s32(in + 4);
in += 32;
s5->val[0] = vld1q_s32(in);
s5->val[1] = vld1q_s32(in + 4);
s[5].val[0] = vld1q_s32(in);
s[5].val[1] = vld1q_s32(in + 4);
in += 32;
s6->val[0] = vld1q_s32(in);
s6->val[1] = vld1q_s32(in + 4);
s[6].val[0] = vld1q_s32(in);
s[6].val[1] = vld1q_s32(in + 4);
in += 32;
s7->val[0] = vld1q_s32(in);
s7->val[1] = vld1q_s32(in + 4);
s[7].val[0] = vld1q_s32(in);
s[7].val[1] = vld1q_s32(in + 4);
}
static INLINE void transpose_and_store_s32_8x8(int32x4x2_t a0, int32x4x2_t a1,
int32x4x2_t a2, int32x4x2_t a3,
int32x4x2_t a4, int32x4x2_t a5,
int32x4x2_t a6, int32x4x2_t a7,
static INLINE void transpose_and_store_s32_8x8(int32x4x2_t *const a,
int32_t **out) {
transpose_s32_8x8(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7);
transpose_s32_8x8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]);
vst1q_s32(*out, a0.val[0]);
vst1q_s32(*out, a[0].val[0]);
*out += 4;
vst1q_s32(*out, a0.val[1]);
vst1q_s32(*out, a[0].val[1]);
*out += 4;
vst1q_s32(*out, a1.val[0]);
vst1q_s32(*out, a[1].val[0]);
*out += 4;
vst1q_s32(*out, a1.val[1]);
vst1q_s32(*out, a[1].val[1]);
*out += 4;
vst1q_s32(*out, a2.val[0]);
vst1q_s32(*out, a[2].val[0]);
*out += 4;
vst1q_s32(*out, a2.val[1]);
vst1q_s32(*out, a[2].val[1]);
*out += 4;
vst1q_s32(*out, a3.val[0]);
vst1q_s32(*out, a[3].val[0]);
*out += 4;
vst1q_s32(*out, a3.val[1]);
vst1q_s32(*out, a[3].val[1]);
*out += 4;
vst1q_s32(*out, a4.val[0]);
vst1q_s32(*out, a[4].val[0]);
*out += 4;
vst1q_s32(*out, a4.val[1]);
vst1q_s32(*out, a[4].val[1]);
*out += 4;
vst1q_s32(*out, a5.val[0]);
vst1q_s32(*out, a[5].val[0]);
*out += 4;
vst1q_s32(*out, a5.val[1]);
vst1q_s32(*out, a[5].val[1]);
*out += 4;
vst1q_s32(*out, a6.val[0]);
vst1q_s32(*out, a[6].val[0]);
*out += 4;
vst1q_s32(*out, a6.val[1]);
vst1q_s32(*out, a[6].val[1]);
*out += 4;
vst1q_s32(*out, a7.val[0]);
vst1q_s32(*out, a[7].val[0]);
*out += 4;
vst1q_s32(*out, a7.val[1]);
vst1q_s32(*out, a[7].val[1]);
*out += 4;
}
static INLINE void idct32_transpose_pair(const int32_t *input, int32_t *t_buf) {
int i;
int32x4x2_t s0, s1, s2, s3, s4, s5, s6, s7;
int32x4x2_t s[8];
for (i = 0; i < 4; i++, input += 8) {
load_s32x4q_dual(input, &s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7);
transpose_and_store_s32_8x8(s0, s1, s2, s3, s4, s5, s6, s7, &t_buf);
load_s32x4q_dual(input, s);
transpose_and_store_s32_8x8(s, &t_buf);
}
}

View File

@ -66,108 +66,104 @@ void vpx_highbd_idct4x4_1_add_neon(const tran_low_t *input, uint16_t *dest,
}
static INLINE void idct4x4_16_kernel_bd10(const int32x4_t cospis,
int32x4_t *const a0,
int32x4_t *const a1,
int32x4_t *const a2,
int32x4_t *const a3) {
int32x4_t *const a) {
int32x4_t b0, b1, b2, b3;
transpose_s32_4x4(a0, a1, a2, a3);
b0 = vaddq_s32(*a0, *a2);
b1 = vsubq_s32(*a0, *a2);
transpose_s32_4x4(&a[0], &a[1], &a[2], &a[3]);
b0 = vaddq_s32(a[0], a[2]);
b1 = vsubq_s32(a[0], a[2]);
b0 = vmulq_lane_s32(b0, vget_high_s32(cospis), 0);
b1 = vmulq_lane_s32(b1, vget_high_s32(cospis), 0);
b2 = vmulq_lane_s32(*a1, vget_high_s32(cospis), 1);
b3 = vmulq_lane_s32(*a1, vget_low_s32(cospis), 1);
b2 = vmlsq_lane_s32(b2, *a3, vget_low_s32(cospis), 1);
b3 = vmlaq_lane_s32(b3, *a3, vget_high_s32(cospis), 1);
b2 = vmulq_lane_s32(a[1], vget_high_s32(cospis), 1);
b3 = vmulq_lane_s32(a[1], vget_low_s32(cospis), 1);
b2 = vmlsq_lane_s32(b2, a[3], vget_low_s32(cospis), 1);
b3 = vmlaq_lane_s32(b3, a[3], vget_high_s32(cospis), 1);
b0 = vrshrq_n_s32(b0, DCT_CONST_BITS);
b1 = vrshrq_n_s32(b1, DCT_CONST_BITS);
b2 = vrshrq_n_s32(b2, DCT_CONST_BITS);
b3 = vrshrq_n_s32(b3, DCT_CONST_BITS);
*a0 = vaddq_s32(b0, b3);
*a1 = vaddq_s32(b1, b2);
*a2 = vsubq_s32(b1, b2);
*a3 = vsubq_s32(b0, b3);
a[0] = vaddq_s32(b0, b3);
a[1] = vaddq_s32(b1, b2);
a[2] = vsubq_s32(b1, b2);
a[3] = vsubq_s32(b0, b3);
}
static INLINE void idct4x4_16_kernel_bd12(const int32x4_t cospis,
int32x4_t *const a0,
int32x4_t *const a1,
int32x4_t *const a2,
int32x4_t *const a3) {
int32x4_t *const a) {
int32x4_t b0, b1, b2, b3;
int64x2_t c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11;
int64x2_t c[12];
transpose_s32_4x4(a0, a1, a2, a3);
b0 = vaddq_s32(*a0, *a2);
b1 = vsubq_s32(*a0, *a2);
c0 = vmull_lane_s32(vget_low_s32(b0), vget_high_s32(cospis), 0);
c1 = vmull_lane_s32(vget_high_s32(b0), vget_high_s32(cospis), 0);
c2 = vmull_lane_s32(vget_low_s32(b1), vget_high_s32(cospis), 0);
c3 = vmull_lane_s32(vget_high_s32(b1), vget_high_s32(cospis), 0);
c4 = vmull_lane_s32(vget_low_s32(*a1), vget_high_s32(cospis), 1);
c5 = vmull_lane_s32(vget_high_s32(*a1), vget_high_s32(cospis), 1);
c6 = vmull_lane_s32(vget_low_s32(*a1), vget_low_s32(cospis), 1);
c7 = vmull_lane_s32(vget_high_s32(*a1), vget_low_s32(cospis), 1);
c8 = vmull_lane_s32(vget_low_s32(*a3), vget_low_s32(cospis), 1);
c9 = vmull_lane_s32(vget_high_s32(*a3), vget_low_s32(cospis), 1);
c10 = vmull_lane_s32(vget_low_s32(*a3), vget_high_s32(cospis), 1);
c11 = vmull_lane_s32(vget_high_s32(*a3), vget_high_s32(cospis), 1);
c4 = vsubq_s64(c4, c8);
c5 = vsubq_s64(c5, c9);
c6 = vaddq_s64(c6, c10);
c7 = vaddq_s64(c7, c11);
b0 = vcombine_s32(vrshrn_n_s64(c0, DCT_CONST_BITS),
vrshrn_n_s64(c1, DCT_CONST_BITS));
b1 = vcombine_s32(vrshrn_n_s64(c2, DCT_CONST_BITS),
vrshrn_n_s64(c3, DCT_CONST_BITS));
b2 = vcombine_s32(vrshrn_n_s64(c4, DCT_CONST_BITS),
vrshrn_n_s64(c5, DCT_CONST_BITS));
b3 = vcombine_s32(vrshrn_n_s64(c6, DCT_CONST_BITS),
vrshrn_n_s64(c7, DCT_CONST_BITS));
*a0 = vaddq_s32(b0, b3);
*a1 = vaddq_s32(b1, b2);
*a2 = vsubq_s32(b1, b2);
*a3 = vsubq_s32(b0, b3);
transpose_s32_4x4(&a[0], &a[1], &a[2], &a[3]);
b0 = vaddq_s32(a[0], a[2]);
b1 = vsubq_s32(a[0], a[2]);
c[0] = vmull_lane_s32(vget_low_s32(b0), vget_high_s32(cospis), 0);
c[1] = vmull_lane_s32(vget_high_s32(b0), vget_high_s32(cospis), 0);
c[2] = vmull_lane_s32(vget_low_s32(b1), vget_high_s32(cospis), 0);
c[3] = vmull_lane_s32(vget_high_s32(b1), vget_high_s32(cospis), 0);
c[4] = vmull_lane_s32(vget_low_s32(a[1]), vget_high_s32(cospis), 1);
c[5] = vmull_lane_s32(vget_high_s32(a[1]), vget_high_s32(cospis), 1);
c[6] = vmull_lane_s32(vget_low_s32(a[1]), vget_low_s32(cospis), 1);
c[7] = vmull_lane_s32(vget_high_s32(a[1]), vget_low_s32(cospis), 1);
c[8] = vmull_lane_s32(vget_low_s32(a[3]), vget_low_s32(cospis), 1);
c[9] = vmull_lane_s32(vget_high_s32(a[3]), vget_low_s32(cospis), 1);
c[10] = vmull_lane_s32(vget_low_s32(a[3]), vget_high_s32(cospis), 1);
c[11] = vmull_lane_s32(vget_high_s32(a[3]), vget_high_s32(cospis), 1);
c[4] = vsubq_s64(c[4], c[8]);
c[5] = vsubq_s64(c[5], c[9]);
c[6] = vaddq_s64(c[6], c[10]);
c[7] = vaddq_s64(c[7], c[11]);
b0 = vcombine_s32(vrshrn_n_s64(c[0], DCT_CONST_BITS),
vrshrn_n_s64(c[1], DCT_CONST_BITS));
b1 = vcombine_s32(vrshrn_n_s64(c[2], DCT_CONST_BITS),
vrshrn_n_s64(c[3], DCT_CONST_BITS));
b2 = vcombine_s32(vrshrn_n_s64(c[4], DCT_CONST_BITS),
vrshrn_n_s64(c[5], DCT_CONST_BITS));
b3 = vcombine_s32(vrshrn_n_s64(c[6], DCT_CONST_BITS),
vrshrn_n_s64(c[7], DCT_CONST_BITS));
a[0] = vaddq_s32(b0, b3);
a[1] = vaddq_s32(b1, b2);
a[2] = vsubq_s32(b1, b2);
a[3] = vsubq_s32(b0, b3);
}
void vpx_highbd_idct4x4_16_add_neon(const tran_low_t *input, uint16_t *dest,
int stride, int bd) {
const int16x8_t max = vdupq_n_s16((1 << bd) - 1);
int32x4_t c0 = vld1q_s32(input);
int32x4_t c1 = vld1q_s32(input + 4);
int32x4_t c2 = vld1q_s32(input + 8);
int32x4_t c3 = vld1q_s32(input + 12);
int16x8_t a0, a1;
int16x8_t a[2];
int32x4_t c[4];
c[0] = vld1q_s32(input);
c[1] = vld1q_s32(input + 4);
c[2] = vld1q_s32(input + 8);
c[3] = vld1q_s32(input + 12);
if (bd == 8) {
const int16x4_t cospis = vld1_s16(kCospi);
// Rows
a0 = vcombine_s16(vmovn_s32(c0), vmovn_s32(c1));
a1 = vcombine_s16(vmovn_s32(c2), vmovn_s32(c3));
idct4x4_16_kernel_bd8(cospis, &a0, &a1);
a[0] = vcombine_s16(vmovn_s32(c[0]), vmovn_s32(c[1]));
a[1] = vcombine_s16(vmovn_s32(c[2]), vmovn_s32(c[3]));
idct4x4_16_kernel_bd8(cospis, a);
// Columns
a1 = vcombine_s16(vget_high_s16(a1), vget_low_s16(a1));
idct4x4_16_kernel_bd8(cospis, &a0, &a1);
a0 = vrshrq_n_s16(a0, 4);
a1 = vrshrq_n_s16(a1, 4);
a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1]));
idct4x4_16_kernel_bd8(cospis, a);
a[0] = vrshrq_n_s16(a[0], 4);
a[1] = vrshrq_n_s16(a[1], 4);
} else {
const int32x4_t cospis = vld1q_s32(kCospi32);
if (bd == 10) {
idct4x4_16_kernel_bd10(cospis, &c0, &c1, &c2, &c3);
idct4x4_16_kernel_bd10(cospis, &c0, &c1, &c2, &c3);
idct4x4_16_kernel_bd10(cospis, c);
idct4x4_16_kernel_bd10(cospis, c);
} else {
idct4x4_16_kernel_bd12(cospis, &c0, &c1, &c2, &c3);
idct4x4_16_kernel_bd12(cospis, &c0, &c1, &c2, &c3);
idct4x4_16_kernel_bd12(cospis, c);
idct4x4_16_kernel_bd12(cospis, c);
}
a0 = vcombine_s16(vqrshrn_n_s32(c0, 4), vqrshrn_n_s32(c1, 4));
a1 = vcombine_s16(vqrshrn_n_s32(c3, 4), vqrshrn_n_s32(c2, 4));
a[0] = vcombine_s16(vqrshrn_n_s32(c[0], 4), vqrshrn_n_s32(c[1], 4));
a[1] = vcombine_s16(vqrshrn_n_s32(c[3], 4), vqrshrn_n_s32(c[2], 4));
}
highbd_idct4x4_1_add_kernel1(&dest, stride, a0, max);
highbd_idct4x4_1_add_kernel2(&dest, stride, a1, max);
highbd_idct4x4_1_add_kernel1(&dest, stride, a[0], max);
highbd_idct4x4_1_add_kernel2(&dest, stride, a[1], max);
}

View File

@ -127,7 +127,7 @@ static INLINE void idct8x8_12_half1d_bd12(
int32x4_t *const io1, int32x4_t *const io2, int32x4_t *const io3,
int32x4_t *const io4, int32x4_t *const io5, int32x4_t *const io6,
int32x4_t *const io7) {
int32x2_t input_1l, input_1h, input_3l, input_3h;
int32x2_t input1l, input1h, input3l, input3h;
int32x2_t step1l[2], step1h[2];
int32x4_t step1[8], step2[8];
int64x2_t t64[8];
@ -136,23 +136,23 @@ static INLINE void idct8x8_12_half1d_bd12(
transpose_s32_4x4(io0, io1, io2, io3);
// stage 1
input_1l = vget_low_s32(*io1);
input_1h = vget_high_s32(*io1);
input_3l = vget_low_s32(*io3);
input_3h = vget_high_s32(*io3);
input1l = vget_low_s32(*io1);
input1h = vget_high_s32(*io1);
input3l = vget_low_s32(*io3);
input3h = vget_high_s32(*io3);
step1l[0] = vget_low_s32(*io0);
step1h[0] = vget_high_s32(*io0);
step1l[1] = vget_low_s32(*io2);
step1h[1] = vget_high_s32(*io2);
t64[0] = vmull_lane_s32(input_1l, vget_high_s32(cospis1), 1);
t64[1] = vmull_lane_s32(input_1h, vget_high_s32(cospis1), 1);
t64[2] = vmull_lane_s32(input_3l, vget_high_s32(cospis1), 0);
t64[3] = vmull_lane_s32(input_3h, vget_high_s32(cospis1), 0);
t64[4] = vmull_lane_s32(input_3l, vget_low_s32(cospis1), 1);
t64[5] = vmull_lane_s32(input_3h, vget_low_s32(cospis1), 1);
t64[6] = vmull_lane_s32(input_1l, vget_low_s32(cospis1), 0);
t64[7] = vmull_lane_s32(input_1h, vget_low_s32(cospis1), 0);
t64[0] = vmull_lane_s32(input1l, vget_high_s32(cospis1), 1);
t64[1] = vmull_lane_s32(input1h, vget_high_s32(cospis1), 1);
t64[2] = vmull_lane_s32(input3l, vget_high_s32(cospis1), 0);
t64[3] = vmull_lane_s32(input3h, vget_high_s32(cospis1), 0);
t64[4] = vmull_lane_s32(input3l, vget_low_s32(cospis1), 1);
t64[5] = vmull_lane_s32(input3h, vget_low_s32(cospis1), 1);
t64[6] = vmull_lane_s32(input1l, vget_low_s32(cospis1), 0);
t64[7] = vmull_lane_s32(input1h, vget_low_s32(cospis1), 0);
t32[0] = vrshrn_n_s64(t64[0], DCT_CONST_BITS);
t32[1] = vrshrn_n_s64(t64[1], DCT_CONST_BITS);
t32[2] = vrshrn_n_s64(t64[2], DCT_CONST_BITS);
@ -222,9 +222,7 @@ static INLINE void idct8x8_12_half1d_bd12(
*io7 = vsubq_s32(step1[0], step2[7]);
}
static INLINE void highbd_add8x8(int16x8_t a0, int16x8_t a1, int16x8_t a2,
int16x8_t a3, int16x8_t a4, int16x8_t a5,
int16x8_t a6, int16x8_t a7, uint16_t *dest,
static INLINE void highbd_add8x8(int16x8_t *const a, uint16_t *dest,
const int stride, const int bd) {
const int16x8_t max = vdupq_n_s16((1 << bd) - 1);
const uint16_t *dst = dest;
@ -248,14 +246,14 @@ static INLINE void highbd_add8x8(int16x8_t a0, int16x8_t a1, int16x8_t a2,
dst += stride;
d7 = vld1q_u16(dst);
d0_s16 = vqaddq_s16(a0, vreinterpretq_s16_u16(d0));
d1_s16 = vqaddq_s16(a1, vreinterpretq_s16_u16(d1));
d2_s16 = vqaddq_s16(a2, vreinterpretq_s16_u16(d2));
d3_s16 = vqaddq_s16(a3, vreinterpretq_s16_u16(d3));
d4_s16 = vqaddq_s16(a4, vreinterpretq_s16_u16(d4));
d5_s16 = vqaddq_s16(a5, vreinterpretq_s16_u16(d5));
d6_s16 = vqaddq_s16(a6, vreinterpretq_s16_u16(d6));
d7_s16 = vqaddq_s16(a7, vreinterpretq_s16_u16(d7));
d0_s16 = vqaddq_s16(a[0], vreinterpretq_s16_u16(d0));
d1_s16 = vqaddq_s16(a[1], vreinterpretq_s16_u16(d1));
d2_s16 = vqaddq_s16(a[2], vreinterpretq_s16_u16(d2));
d3_s16 = vqaddq_s16(a[3], vreinterpretq_s16_u16(d3));
d4_s16 = vqaddq_s16(a[4], vreinterpretq_s16_u16(d4));
d5_s16 = vqaddq_s16(a[5], vreinterpretq_s16_u16(d5));
d6_s16 = vqaddq_s16(a[6], vreinterpretq_s16_u16(d6));
d7_s16 = vqaddq_s16(a[7], vreinterpretq_s16_u16(d7));
d0_s16 = vminq_s16(d0_s16, max);
d1_s16 = vminq_s16(d1_s16, max);
@ -293,11 +291,13 @@ static INLINE void highbd_add8x8(int16x8_t a0, int16x8_t a1, int16x8_t a2,
void vpx_highbd_idct8x8_12_add_neon(const tran_low_t *input, uint16_t *dest,
int stride, int bd) {
int32x4_t a0 = vld1q_s32(input);
int32x4_t a1 = vld1q_s32(input + 8);
int32x4_t a2 = vld1q_s32(input + 16);
int32x4_t a3 = vld1q_s32(input + 24);
int16x8_t c0, c1, c2, c3, c4, c5, c6, c7;
int32x4_t a[16];
int16x8_t c[8];
a[0] = vld1q_s32(input);
a[1] = vld1q_s32(input + 8);
a[2] = vld1q_s32(input + 16);
a[3] = vld1q_s32(input + 24);
if (bd == 8) {
const int16x8_t cospis = vld1q_s16(kCospi);
@ -305,54 +305,52 @@ void vpx_highbd_idct8x8_12_add_neon(const tran_low_t *input, uint16_t *dest,
const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24
const int16x4_t cospisd0 = vget_low_s16(cospisd); // doubled 0, 8, 16, 24
const int16x4_t cospisd1 = vget_high_s16(cospisd); // doubled 4, 12, 20, 28
int16x4_t b0 = vmovn_s32(a0);
int16x4_t b1 = vmovn_s32(a1);
int16x4_t b2 = vmovn_s32(a2);
int16x4_t b3 = vmovn_s32(a3);
int16x4_t b4, b5, b6, b7;
int16x4_t b[8];
idct8x8_12_pass1_bd8(cospis0, cospisd0, cospisd1, &b0, &b1, &b2, &b3, &b4,
&b5, &b6, &b7);
idct8x8_12_pass2_bd8(cospis0, cospisd0, cospisd1, b0, b1, b2, b3, b4, b5,
b6, b7, &c0, &c1, &c2, &c3, &c4, &c5, &c6, &c7);
c0 = vrshrq_n_s16(c0, 5);
c1 = vrshrq_n_s16(c1, 5);
c2 = vrshrq_n_s16(c2, 5);
c3 = vrshrq_n_s16(c3, 5);
c4 = vrshrq_n_s16(c4, 5);
c5 = vrshrq_n_s16(c5, 5);
c6 = vrshrq_n_s16(c6, 5);
c7 = vrshrq_n_s16(c7, 5);
b[0] = vmovn_s32(a[0]);
b[1] = vmovn_s32(a[1]);
b[2] = vmovn_s32(a[2]);
b[3] = vmovn_s32(a[3]);
idct8x8_12_pass1_bd8(cospis0, cospisd0, cospisd1, b);
idct8x8_12_pass2_bd8(cospis0, cospisd0, cospisd1, b, c);
c[0] = vrshrq_n_s16(c[0], 5);
c[1] = vrshrq_n_s16(c[1], 5);
c[2] = vrshrq_n_s16(c[2], 5);
c[3] = vrshrq_n_s16(c[3], 5);
c[4] = vrshrq_n_s16(c[4], 5);
c[5] = vrshrq_n_s16(c[5], 5);
c[6] = vrshrq_n_s16(c[6], 5);
c[7] = vrshrq_n_s16(c[7], 5);
} else {
const int32x4_t cospis0 = vld1q_s32(kCospi32); // cospi 0, 8, 16, 24
const int32x4_t cospis1 = vld1q_s32(kCospi32 + 4); // cospi 4, 12, 20, 28
int32x4_t a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15;
if (bd == 10) {
idct8x8_12_half1d_bd10(cospis0, cospis1, &a0, &a1, &a2, &a3, &a4, &a5,
&a6, &a7);
idct8x8_12_half1d_bd10(cospis0, cospis1, &a0, &a1, &a2, &a3, &a8, &a9,
&a10, &a11);
idct8x8_12_half1d_bd10(cospis0, cospis1, &a4, &a5, &a6, &a7, &a12, &a13,
&a14, &a15);
idct8x8_12_half1d_bd10(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3],
&a[4], &a[5], &a[6], &a[7]);
idct8x8_12_half1d_bd10(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3],
&a[8], &a[9], &a[10], &a[11]);
idct8x8_12_half1d_bd10(cospis0, cospis1, &a[4], &a[5], &a[6], &a[7],
&a[12], &a[13], &a[14], &a[15]);
} else {
idct8x8_12_half1d_bd12(cospis0, cospis1, &a0, &a1, &a2, &a3, &a4, &a5,
&a6, &a7);
idct8x8_12_half1d_bd12(cospis0, cospis1, &a0, &a1, &a2, &a3, &a8, &a9,
&a10, &a11);
idct8x8_12_half1d_bd12(cospis0, cospis1, &a4, &a5, &a6, &a7, &a12, &a13,
&a14, &a15);
idct8x8_12_half1d_bd12(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3],
&a[4], &a[5], &a[6], &a[7]);
idct8x8_12_half1d_bd12(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3],
&a[8], &a[9], &a[10], &a[11]);
idct8x8_12_half1d_bd12(cospis0, cospis1, &a[4], &a[5], &a[6], &a[7],
&a[12], &a[13], &a[14], &a[15]);
}
c0 = vcombine_s16(vrshrn_n_s32(a0, 5), vrshrn_n_s32(a4, 5));
c1 = vcombine_s16(vrshrn_n_s32(a1, 5), vrshrn_n_s32(a5, 5));
c2 = vcombine_s16(vrshrn_n_s32(a2, 5), vrshrn_n_s32(a6, 5));
c3 = vcombine_s16(vrshrn_n_s32(a3, 5), vrshrn_n_s32(a7, 5));
c4 = vcombine_s16(vrshrn_n_s32(a8, 5), vrshrn_n_s32(a12, 5));
c5 = vcombine_s16(vrshrn_n_s32(a9, 5), vrshrn_n_s32(a13, 5));
c6 = vcombine_s16(vrshrn_n_s32(a10, 5), vrshrn_n_s32(a14, 5));
c7 = vcombine_s16(vrshrn_n_s32(a11, 5), vrshrn_n_s32(a15, 5));
c[0] = vcombine_s16(vrshrn_n_s32(a[0], 5), vrshrn_n_s32(a[4], 5));
c[1] = vcombine_s16(vrshrn_n_s32(a[1], 5), vrshrn_n_s32(a[5], 5));
c[2] = vcombine_s16(vrshrn_n_s32(a[2], 5), vrshrn_n_s32(a[6], 5));
c[3] = vcombine_s16(vrshrn_n_s32(a[3], 5), vrshrn_n_s32(a[7], 5));
c[4] = vcombine_s16(vrshrn_n_s32(a[8], 5), vrshrn_n_s32(a[12], 5));
c[5] = vcombine_s16(vrshrn_n_s32(a[9], 5), vrshrn_n_s32(a[13], 5));
c[6] = vcombine_s16(vrshrn_n_s32(a[10], 5), vrshrn_n_s32(a[14], 5));
c[7] = vcombine_s16(vrshrn_n_s32(a[11], 5), vrshrn_n_s32(a[15], 5));
}
highbd_add8x8(c0, c1, c2, c3, c4, c5, c6, c7, dest, stride, bd);
highbd_add8x8(c, dest, stride, bd);
}
static INLINE void idct8x8_64_half1d_bd10(
@ -428,8 +426,8 @@ static INLINE void idct8x8_64_half1d_bd12(
int32x4_t *const io1, int32x4_t *const io2, int32x4_t *const io3,
int32x4_t *const io4, int32x4_t *const io5, int32x4_t *const io6,
int32x4_t *const io7) {
int32x2_t input_1l, input_1h, input_3l, input_3h, input_5l, input_5h,
input_7l, input_7h;
int32x2_t input1l, input1h, input3l, input3h, input5l, input5h, input7l,
input7h;
int32x2_t step1l[4], step1h[4];
int32x4_t step1[8], step2[8];
int64x2_t t64[8];
@ -438,14 +436,14 @@ static INLINE void idct8x8_64_half1d_bd12(
transpose_s32_8x4(io0, io1, io2, io3, io4, io5, io6, io7);
// stage 1
input_1l = vget_low_s32(*io1);
input_1h = vget_high_s32(*io1);
input_3l = vget_low_s32(*io3);
input_3h = vget_high_s32(*io3);
input_5l = vget_low_s32(*io5);
input_5h = vget_high_s32(*io5);
input_7l = vget_low_s32(*io7);
input_7h = vget_high_s32(*io7);
input1l = vget_low_s32(*io1);
input1h = vget_high_s32(*io1);
input3l = vget_low_s32(*io3);
input3h = vget_high_s32(*io3);
input5l = vget_low_s32(*io5);
input5h = vget_high_s32(*io5);
input7l = vget_low_s32(*io7);
input7h = vget_high_s32(*io7);
step1l[0] = vget_low_s32(*io0);
step1h[0] = vget_high_s32(*io0);
step1l[1] = vget_low_s32(*io2);
@ -455,22 +453,22 @@ static INLINE void idct8x8_64_half1d_bd12(
step1l[3] = vget_low_s32(*io6);
step1h[3] = vget_high_s32(*io6);
t64[0] = vmull_lane_s32(input_1l, vget_high_s32(cospis1), 1);
t64[1] = vmull_lane_s32(input_1h, vget_high_s32(cospis1), 1);
t64[2] = vmull_lane_s32(input_3l, vget_high_s32(cospis1), 0);
t64[3] = vmull_lane_s32(input_3h, vget_high_s32(cospis1), 0);
t64[4] = vmull_lane_s32(input_3l, vget_low_s32(cospis1), 1);
t64[5] = vmull_lane_s32(input_3h, vget_low_s32(cospis1), 1);
t64[6] = vmull_lane_s32(input_1l, vget_low_s32(cospis1), 0);
t64[7] = vmull_lane_s32(input_1h, vget_low_s32(cospis1), 0);
t64[0] = vmlsl_lane_s32(t64[0], input_7l, vget_low_s32(cospis1), 0);
t64[1] = vmlsl_lane_s32(t64[1], input_7h, vget_low_s32(cospis1), 0);
t64[2] = vmlal_lane_s32(t64[2], input_5l, vget_low_s32(cospis1), 1);
t64[3] = vmlal_lane_s32(t64[3], input_5h, vget_low_s32(cospis1), 1);
t64[4] = vmlsl_lane_s32(t64[4], input_5l, vget_high_s32(cospis1), 0);
t64[5] = vmlsl_lane_s32(t64[5], input_5h, vget_high_s32(cospis1), 0);
t64[6] = vmlal_lane_s32(t64[6], input_7l, vget_high_s32(cospis1), 1);
t64[7] = vmlal_lane_s32(t64[7], input_7h, vget_high_s32(cospis1), 1);
t64[0] = vmull_lane_s32(input1l, vget_high_s32(cospis1), 1);
t64[1] = vmull_lane_s32(input1h, vget_high_s32(cospis1), 1);
t64[2] = vmull_lane_s32(input3l, vget_high_s32(cospis1), 0);
t64[3] = vmull_lane_s32(input3h, vget_high_s32(cospis1), 0);
t64[4] = vmull_lane_s32(input3l, vget_low_s32(cospis1), 1);
t64[5] = vmull_lane_s32(input3h, vget_low_s32(cospis1), 1);
t64[6] = vmull_lane_s32(input1l, vget_low_s32(cospis1), 0);
t64[7] = vmull_lane_s32(input1h, vget_low_s32(cospis1), 0);
t64[0] = vmlsl_lane_s32(t64[0], input7l, vget_low_s32(cospis1), 0);
t64[1] = vmlsl_lane_s32(t64[1], input7h, vget_low_s32(cospis1), 0);
t64[2] = vmlal_lane_s32(t64[2], input5l, vget_low_s32(cospis1), 1);
t64[3] = vmlal_lane_s32(t64[3], input5h, vget_low_s32(cospis1), 1);
t64[4] = vmlsl_lane_s32(t64[4], input5l, vget_high_s32(cospis1), 0);
t64[5] = vmlsl_lane_s32(t64[5], input5h, vget_high_s32(cospis1), 0);
t64[6] = vmlal_lane_s32(t64[6], input7l, vget_high_s32(cospis1), 1);
t64[7] = vmlal_lane_s32(t64[7], input7h, vget_high_s32(cospis1), 1);
t32[0] = vrshrn_n_s64(t64[0], DCT_CONST_BITS);
t32[1] = vrshrn_n_s64(t64[1], DCT_CONST_BITS);
t32[2] = vrshrn_n_s64(t64[2], DCT_CONST_BITS);
@ -553,79 +551,83 @@ static INLINE void idct8x8_64_half1d_bd12(
void vpx_highbd_idct8x8_64_add_neon(const tran_low_t *input, uint16_t *dest,
int stride, int bd) {
int32x4_t a0 = vld1q_s32(input);
int32x4_t a1 = vld1q_s32(input + 4);
int32x4_t a2 = vld1q_s32(input + 8);
int32x4_t a3 = vld1q_s32(input + 12);
int32x4_t a4 = vld1q_s32(input + 16);
int32x4_t a5 = vld1q_s32(input + 20);
int32x4_t a6 = vld1q_s32(input + 24);
int32x4_t a7 = vld1q_s32(input + 28);
int32x4_t a8 = vld1q_s32(input + 32);
int32x4_t a9 = vld1q_s32(input + 36);
int32x4_t a10 = vld1q_s32(input + 40);
int32x4_t a11 = vld1q_s32(input + 44);
int32x4_t a12 = vld1q_s32(input + 48);
int32x4_t a13 = vld1q_s32(input + 52);
int32x4_t a14 = vld1q_s32(input + 56);
int32x4_t a15 = vld1q_s32(input + 60);
int16x8_t c0, c1, c2, c3, c4, c5, c6, c7;
int32x4_t a[16];
int16x8_t c[8];
a[0] = vld1q_s32(input);
a[1] = vld1q_s32(input + 4);
a[2] = vld1q_s32(input + 8);
a[3] = vld1q_s32(input + 12);
a[4] = vld1q_s32(input + 16);
a[5] = vld1q_s32(input + 20);
a[6] = vld1q_s32(input + 24);
a[7] = vld1q_s32(input + 28);
a[8] = vld1q_s32(input + 32);
a[9] = vld1q_s32(input + 36);
a[10] = vld1q_s32(input + 40);
a[11] = vld1q_s32(input + 44);
a[12] = vld1q_s32(input + 48);
a[13] = vld1q_s32(input + 52);
a[14] = vld1q_s32(input + 56);
a[15] = vld1q_s32(input + 60);
if (bd == 8) {
const int16x8_t cospis = vld1q_s16(kCospi);
const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24
const int16x4_t cospis1 = vget_high_s16(cospis); // cospi 4, 12, 20, 28
int16x8_t b0 = vcombine_s16(vmovn_s32(a0), vmovn_s32(a1));
int16x8_t b1 = vcombine_s16(vmovn_s32(a2), vmovn_s32(a3));
int16x8_t b2 = vcombine_s16(vmovn_s32(a4), vmovn_s32(a5));
int16x8_t b3 = vcombine_s16(vmovn_s32(a6), vmovn_s32(a7));
int16x8_t b4 = vcombine_s16(vmovn_s32(a8), vmovn_s32(a9));
int16x8_t b5 = vcombine_s16(vmovn_s32(a10), vmovn_s32(a11));
int16x8_t b6 = vcombine_s16(vmovn_s32(a12), vmovn_s32(a13));
int16x8_t b7 = vcombine_s16(vmovn_s32(a14), vmovn_s32(a15));
int16x8_t b[8];
idct8x8_64_1d_bd8(cospis0, cospis1, &b0, &b1, &b2, &b3, &b4, &b5, &b6, &b7);
idct8x8_64_1d_bd8(cospis0, cospis1, &b0, &b1, &b2, &b3, &b4, &b5, &b6, &b7);
b[0] = vcombine_s16(vmovn_s32(a[0]), vmovn_s32(a[1]));
b[1] = vcombine_s16(vmovn_s32(a[2]), vmovn_s32(a[3]));
b[2] = vcombine_s16(vmovn_s32(a[4]), vmovn_s32(a[5]));
b[3] = vcombine_s16(vmovn_s32(a[6]), vmovn_s32(a[7]));
b[4] = vcombine_s16(vmovn_s32(a[8]), vmovn_s32(a[9]));
b[5] = vcombine_s16(vmovn_s32(a[10]), vmovn_s32(a[11]));
b[6] = vcombine_s16(vmovn_s32(a[12]), vmovn_s32(a[13]));
b[7] = vcombine_s16(vmovn_s32(a[14]), vmovn_s32(a[15]));
c0 = vrshrq_n_s16(b0, 5);
c1 = vrshrq_n_s16(b1, 5);
c2 = vrshrq_n_s16(b2, 5);
c3 = vrshrq_n_s16(b3, 5);
c4 = vrshrq_n_s16(b4, 5);
c5 = vrshrq_n_s16(b5, 5);
c6 = vrshrq_n_s16(b6, 5);
c7 = vrshrq_n_s16(b7, 5);
idct8x8_64_1d_bd8(cospis0, cospis1, b);
idct8x8_64_1d_bd8(cospis0, cospis1, b);
c[0] = vrshrq_n_s16(b[0], 5);
c[1] = vrshrq_n_s16(b[1], 5);
c[2] = vrshrq_n_s16(b[2], 5);
c[3] = vrshrq_n_s16(b[3], 5);
c[4] = vrshrq_n_s16(b[4], 5);
c[5] = vrshrq_n_s16(b[5], 5);
c[6] = vrshrq_n_s16(b[6], 5);
c[7] = vrshrq_n_s16(b[7], 5);
} else {
const int32x4_t cospis0 = vld1q_s32(kCospi32); // cospi 0, 8, 16, 24
const int32x4_t cospis1 = vld1q_s32(kCospi32 + 4); // cospi 4, 12, 20, 28
if (bd == 10) {
idct8x8_64_half1d_bd10(cospis0, cospis1, &a0, &a1, &a2, &a3, &a4, &a5,
&a6, &a7);
idct8x8_64_half1d_bd10(cospis0, cospis1, &a8, &a9, &a10, &a11, &a12, &a13,
&a14, &a15);
idct8x8_64_half1d_bd10(cospis0, cospis1, &a0, &a8, &a1, &a9, &a2, &a10,
&a3, &a11);
idct8x8_64_half1d_bd10(cospis0, cospis1, &a4, &a12, &a5, &a13, &a6, &a14,
&a7, &a15);
idct8x8_64_half1d_bd10(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3],
&a[4], &a[5], &a[6], &a[7]);
idct8x8_64_half1d_bd10(cospis0, cospis1, &a[8], &a[9], &a[10], &a[11],
&a[12], &a[13], &a[14], &a[15]);
idct8x8_64_half1d_bd10(cospis0, cospis1, &a[0], &a[8], &a[1], &a[9],
&a[2], &a[10], &a[3], &a[11]);
idct8x8_64_half1d_bd10(cospis0, cospis1, &a[4], &a[12], &a[5], &a[13],
&a[6], &a[14], &a[7], &a[15]);
} else {
idct8x8_64_half1d_bd12(cospis0, cospis1, &a0, &a1, &a2, &a3, &a4, &a5,
&a6, &a7);
idct8x8_64_half1d_bd12(cospis0, cospis1, &a8, &a9, &a10, &a11, &a12, &a13,
&a14, &a15);
idct8x8_64_half1d_bd12(cospis0, cospis1, &a0, &a8, &a1, &a9, &a2, &a10,
&a3, &a11);
idct8x8_64_half1d_bd12(cospis0, cospis1, &a4, &a12, &a5, &a13, &a6, &a14,
&a7, &a15);
idct8x8_64_half1d_bd12(cospis0, cospis1, &a[0], &a[1], &a[2], &a[3],
&a[4], &a[5], &a[6], &a[7]);
idct8x8_64_half1d_bd12(cospis0, cospis1, &a[8], &a[9], &a[10], &a[11],
&a[12], &a[13], &a[14], &a[15]);
idct8x8_64_half1d_bd12(cospis0, cospis1, &a[0], &a[8], &a[1], &a[9],
&a[2], &a[10], &a[3], &a[11]);
idct8x8_64_half1d_bd12(cospis0, cospis1, &a[4], &a[12], &a[5], &a[13],
&a[6], &a[14], &a[7], &a[15]);
}
c0 = vcombine_s16(vrshrn_n_s32(a0, 5), vrshrn_n_s32(a4, 5));
c1 = vcombine_s16(vrshrn_n_s32(a8, 5), vrshrn_n_s32(a12, 5));
c2 = vcombine_s16(vrshrn_n_s32(a1, 5), vrshrn_n_s32(a5, 5));
c3 = vcombine_s16(vrshrn_n_s32(a9, 5), vrshrn_n_s32(a13, 5));
c4 = vcombine_s16(vrshrn_n_s32(a2, 5), vrshrn_n_s32(a6, 5));
c5 = vcombine_s16(vrshrn_n_s32(a10, 5), vrshrn_n_s32(a14, 5));
c6 = vcombine_s16(vrshrn_n_s32(a3, 5), vrshrn_n_s32(a7, 5));
c7 = vcombine_s16(vrshrn_n_s32(a11, 5), vrshrn_n_s32(a15, 5));
c[0] = vcombine_s16(vrshrn_n_s32(a[0], 5), vrshrn_n_s32(a[4], 5));
c[1] = vcombine_s16(vrshrn_n_s32(a[8], 5), vrshrn_n_s32(a[12], 5));
c[2] = vcombine_s16(vrshrn_n_s32(a[1], 5), vrshrn_n_s32(a[5], 5));
c[3] = vcombine_s16(vrshrn_n_s32(a[9], 5), vrshrn_n_s32(a[13], 5));
c[4] = vcombine_s16(vrshrn_n_s32(a[2], 5), vrshrn_n_s32(a[6], 5));
c[5] = vcombine_s16(vrshrn_n_s32(a[10], 5), vrshrn_n_s32(a[14], 5));
c[6] = vcombine_s16(vrshrn_n_s32(a[3], 5), vrshrn_n_s32(a[7], 5));
c[7] = vcombine_s16(vrshrn_n_s32(a[11], 5), vrshrn_n_s32(a[15], 5));
}
highbd_add8x8(c0, c1, c2, c3, c4, c5, c6, c7, dest, stride, bd);
highbd_add8x8(c, dest, stride, bd);
}

View File

@ -650,14 +650,10 @@ void vpx_idct32_16_neon(const int16_t *const input, void *const output,
highbd_add_and_store_bd8(out, output, stride);
} else {
uint8_t *const outputT = (uint8_t *)output;
add_and_store_u8_s16(out[0], out[1], out[2], out[3], out[4], out[5], out[6],
out[7], outputT, stride);
add_and_store_u8_s16(out[8], out[9], out[10], out[11], out[12], out[13],
out[14], out[15], outputT + (8 * stride), stride);
add_and_store_u8_s16(out[16], out[17], out[18], out[19], out[20], out[21],
out[22], out[23], outputT + (16 * stride), stride);
add_and_store_u8_s16(out[24], out[25], out[26], out[27], out[28], out[29],
out[30], out[31], outputT + (24 * stride), stride);
add_and_store_u8_s16(out + 0, outputT, stride);
add_and_store_u8_s16(out + 8, outputT + (8 * stride), stride);
add_and_store_u8_s16(out + 16, outputT + (16 * stride), stride);
add_and_store_u8_s16(out + 24, outputT + (24 * stride), stride);
}
}

View File

@ -490,14 +490,10 @@ void vpx_idct32_8_neon(const int16_t *input, void *const output, int stride,
highbd_add_and_store_bd8(out, output, stride);
} else {
uint8_t *const outputT = (uint8_t *)output;
add_and_store_u8_s16(out[0], out[1], out[2], out[3], out[4], out[5], out[6],
out[7], outputT, stride);
add_and_store_u8_s16(out[8], out[9], out[10], out[11], out[12], out[13],
out[14], out[15], outputT + (8 * stride), stride);
add_and_store_u8_s16(out[16], out[17], out[18], out[19], out[20], out[21],
out[22], out[23], outputT + (16 * stride), stride);
add_and_store_u8_s16(out[24], out[25], out[26], out[27], out[28], out[29],
out[30], out[31], outputT + (24 * stride), stride);
add_and_store_u8_s16(out + 0, outputT, stride);
add_and_store_u8_s16(out + 8, outputT + (8 * stride), stride);
add_and_store_u8_s16(out + 16, outputT + (16 * stride), stride);
add_and_store_u8_s16(out + 24, outputT + (24 * stride), stride);
}
}

View File

@ -20,43 +20,41 @@ void vpx_idct4x4_16_add_neon(const tran_low_t *input, uint8_t *dest,
int stride) {
const uint8_t *dst = dest;
const int16x4_t cospis = vld1_s16(kCospi);
uint8x8_t dest01_u8;
uint32x2_t dest32_u32 = vdup_n_u32(0);
int16x8_t a0, a1;
uint8x8_t d01, d32;
uint16x8_t d01_u16, d32_u16;
uint32x2_t s32 = vdup_n_u32(0);
int16x8_t a[2];
uint8x8_t s, d[2];
uint16x8_t sum[2];
assert(!((intptr_t)dest % sizeof(uint32_t)));
assert(!(stride % sizeof(uint32_t)));
// Rows
a0 = load_tran_low_to_s16q(input);
a1 = load_tran_low_to_s16q(input + 8);
idct4x4_16_kernel_bd8(cospis, &a0, &a1);
a[0] = load_tran_low_to_s16q(input);
a[1] = load_tran_low_to_s16q(input + 8);
idct4x4_16_kernel_bd8(cospis, a);
// Columns
a1 = vcombine_s16(vget_high_s16(a1), vget_low_s16(a1));
idct4x4_16_kernel_bd8(cospis, &a0, &a1);
a0 = vrshrq_n_s16(a0, 4);
a1 = vrshrq_n_s16(a1, 4);
a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1]));
idct4x4_16_kernel_bd8(cospis, a);
a[0] = vrshrq_n_s16(a[0], 4);
a[1] = vrshrq_n_s16(a[1], 4);
dest01_u8 = load_u8(dst, stride);
s = load_u8(dst, stride);
dst += 2 * stride;
// The elements are loaded in reverse order.
dest32_u32 = vld1_lane_u32((const uint32_t *)dst, dest32_u32, 1);
s32 = vld1_lane_u32((const uint32_t *)dst, s32, 1);
dst += stride;
dest32_u32 = vld1_lane_u32((const uint32_t *)dst, dest32_u32, 0);
s32 = vld1_lane_u32((const uint32_t *)dst, s32, 0);
d01_u16 = vaddw_u8(vreinterpretq_u16_s16(a0), dest01_u8);
d32_u16 =
vaddw_u8(vreinterpretq_u16_s16(a1), vreinterpret_u8_u32(dest32_u32));
d01 = vqmovun_s16(vreinterpretq_s16_u16(d01_u16));
d32 = vqmovun_s16(vreinterpretq_s16_u16(d32_u16));
sum[0] = vaddw_u8(vreinterpretq_u16_s16(a[0]), s);
sum[1] = vaddw_u8(vreinterpretq_u16_s16(a[1]), vreinterpret_u8_u32(s32));
d[0] = vqmovun_s16(vreinterpretq_s16_u16(sum[0]));
d[1] = vqmovun_s16(vreinterpretq_s16_u16(sum[1]));
store_u8(dest, stride, d01);
store_u8(dest, stride, d[0]);
dest += 2 * stride;
// The elements are stored in reverse order.
vst1_lane_u32((uint32_t *)dest, vreinterpret_u32_u8(d32), 1);
vst1_lane_u32((uint32_t *)dest, vreinterpret_u32_u8(d[1]), 1);
dest += stride;
vst1_lane_u32((uint32_t *)dest, vreinterpret_u32_u8(d32), 0);
vst1_lane_u32((uint32_t *)dest, vreinterpret_u32_u8(d[1]), 0);
}

View File

@ -17,72 +17,26 @@
#include "vpx_dsp/arm/transpose_neon.h"
#include "vpx_dsp/txfm_common.h"
static INLINE void add8x8(int16x8_t a0, int16x8_t a1, int16x8_t a2,
int16x8_t a3, int16x8_t a4, int16x8_t a5,
int16x8_t a6, int16x8_t a7, uint8_t *dest,
static INLINE void idct8x8_add8x1(const int16x8_t a, uint8_t **const dest,
const int stride) {
const uint8x8_t s = vld1_u8(*dest);
const int16x8_t res = vrshrq_n_s16(a, 5);
const uint16x8_t q = vaddw_u8(vreinterpretq_u16_s16(res), s);
const uint8x8_t d = vqmovun_s16(vreinterpretq_s16_u16(q));
vst1_u8(*dest, d);
*dest += stride;
}
static INLINE void add8x8(int16x8_t *const out, uint8_t *dest,
const int stride) {
const uint8_t *dst = dest;
uint8x8_t d0, d1, d2, d3, d4, d5, d6, d7;
uint16x8_t d0_u16, d1_u16, d2_u16, d3_u16, d4_u16, d5_u16, d6_u16, d7_u16;
a0 = vrshrq_n_s16(a0, 5);
a1 = vrshrq_n_s16(a1, 5);
a2 = vrshrq_n_s16(a2, 5);
a3 = vrshrq_n_s16(a3, 5);
a4 = vrshrq_n_s16(a4, 5);
a5 = vrshrq_n_s16(a5, 5);
a6 = vrshrq_n_s16(a6, 5);
a7 = vrshrq_n_s16(a7, 5);
d0 = vld1_u8(dst);
dst += stride;
d1 = vld1_u8(dst);
dst += stride;
d2 = vld1_u8(dst);
dst += stride;
d3 = vld1_u8(dst);
dst += stride;
d4 = vld1_u8(dst);
dst += stride;
d5 = vld1_u8(dst);
dst += stride;
d6 = vld1_u8(dst);
dst += stride;
d7 = vld1_u8(dst);
d0_u16 = vaddw_u8(vreinterpretq_u16_s16(a0), d0);
d1_u16 = vaddw_u8(vreinterpretq_u16_s16(a1), d1);
d2_u16 = vaddw_u8(vreinterpretq_u16_s16(a2), d2);
d3_u16 = vaddw_u8(vreinterpretq_u16_s16(a3), d3);
d4_u16 = vaddw_u8(vreinterpretq_u16_s16(a4), d4);
d5_u16 = vaddw_u8(vreinterpretq_u16_s16(a5), d5);
d6_u16 = vaddw_u8(vreinterpretq_u16_s16(a6), d6);
d7_u16 = vaddw_u8(vreinterpretq_u16_s16(a7), d7);
d0 = vqmovun_s16(vreinterpretq_s16_u16(d0_u16));
d1 = vqmovun_s16(vreinterpretq_s16_u16(d1_u16));
d2 = vqmovun_s16(vreinterpretq_s16_u16(d2_u16));
d3 = vqmovun_s16(vreinterpretq_s16_u16(d3_u16));
d4 = vqmovun_s16(vreinterpretq_s16_u16(d4_u16));
d5 = vqmovun_s16(vreinterpretq_s16_u16(d5_u16));
d6 = vqmovun_s16(vreinterpretq_s16_u16(d6_u16));
d7 = vqmovun_s16(vreinterpretq_s16_u16(d7_u16));
vst1_u8(dest, d0);
dest += stride;
vst1_u8(dest, d1);
dest += stride;
vst1_u8(dest, d2);
dest += stride;
vst1_u8(dest, d3);
dest += stride;
vst1_u8(dest, d4);
dest += stride;
vst1_u8(dest, d5);
dest += stride;
vst1_u8(dest, d6);
dest += stride;
vst1_u8(dest, d7);
idct8x8_add8x1(out[0], &dest, stride);
idct8x8_add8x1(out[1], &dest, stride);
idct8x8_add8x1(out[2], &dest, stride);
idct8x8_add8x1(out[3], &dest, stride);
idct8x8_add8x1(out[4], &dest, stride);
idct8x8_add8x1(out[5], &dest, stride);
idct8x8_add8x1(out[6], &dest, stride);
idct8x8_add8x1(out[7], &dest, stride);
}
void vpx_idct8x8_64_add_neon(const tran_low_t *input, uint8_t *dest,
@ -90,18 +44,20 @@ void vpx_idct8x8_64_add_neon(const tran_low_t *input, uint8_t *dest,
const int16x8_t cospis = vld1q_s16(kCospi);
const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24
const int16x4_t cospis1 = vget_high_s16(cospis); // cospi 4, 12, 20, 28
int16x8_t a0 = load_tran_low_to_s16q(input);
int16x8_t a1 = load_tran_low_to_s16q(input + 8);
int16x8_t a2 = load_tran_low_to_s16q(input + 16);
int16x8_t a3 = load_tran_low_to_s16q(input + 24);
int16x8_t a4 = load_tran_low_to_s16q(input + 32);
int16x8_t a5 = load_tran_low_to_s16q(input + 40);
int16x8_t a6 = load_tran_low_to_s16q(input + 48);
int16x8_t a7 = load_tran_low_to_s16q(input + 56);
int16x8_t a[8];
idct8x8_64_1d_bd8(cospis0, cospis1, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7);
idct8x8_64_1d_bd8(cospis0, cospis1, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7);
add8x8(a0, a1, a2, a3, a4, a5, a6, a7, dest, stride);
a[0] = load_tran_low_to_s16q(input);
a[1] = load_tran_low_to_s16q(input + 8);
a[2] = load_tran_low_to_s16q(input + 16);
a[3] = load_tran_low_to_s16q(input + 24);
a[4] = load_tran_low_to_s16q(input + 32);
a[5] = load_tran_low_to_s16q(input + 40);
a[6] = load_tran_low_to_s16q(input + 48);
a[7] = load_tran_low_to_s16q(input + 56);
idct8x8_64_1d_bd8(cospis0, cospis1, a);
idct8x8_64_1d_bd8(cospis0, cospis1, a);
add8x8(a, dest, stride);
}
void vpx_idct8x8_12_add_neon(const tran_low_t *input, uint8_t *dest,
@ -111,17 +67,15 @@ void vpx_idct8x8_12_add_neon(const tran_low_t *input, uint8_t *dest,
const int16x4_t cospis0 = vget_low_s16(cospis); // cospi 0, 8, 16, 24
const int16x4_t cospisd0 = vget_low_s16(cospisd); // doubled 0, 8, 16, 24
const int16x4_t cospisd1 = vget_high_s16(cospisd); // doubled 4, 12, 20, 28
int16x4_t a0, a1, a2, a3, a4, a5, a6, a7;
int16x8_t b0, b1, b2, b3, b4, b5, b6, b7;
int16x4_t a[8];
int16x8_t b[8];
a0 = load_tran_low_to_s16d(input);
a1 = load_tran_low_to_s16d(input + 8);
a2 = load_tran_low_to_s16d(input + 16);
a3 = load_tran_low_to_s16d(input + 24);
a[0] = load_tran_low_to_s16d(input);
a[1] = load_tran_low_to_s16d(input + 8);
a[2] = load_tran_low_to_s16d(input + 16);
a[3] = load_tran_low_to_s16d(input + 24);
idct8x8_12_pass1_bd8(cospis0, cospisd0, cospisd1, &a0, &a1, &a2, &a3, &a4,
&a5, &a6, &a7);
idct8x8_12_pass2_bd8(cospis0, cospisd0, cospisd1, a0, a1, a2, a3, a4, a5, a6,
a7, &b0, &b1, &b2, &b3, &b4, &b5, &b6, &b7);
add8x8(b0, b1, b2, b3, b4, b5, b6, b7, dest, stride);
idct8x8_12_pass1_bd8(cospis0, cospisd0, cospisd1, a);
idct8x8_12_pass2_bd8(cospis0, cospisd0, cospisd1, a, b);
add8x8(b, dest, stride);
}

View File

@ -217,64 +217,62 @@ static INLINE int32x4x2_t multiply_accumulate_shift_and_narrow_s32_dual(
}
// Shift the output down by 6 and add it to the destination buffer.
static INLINE void add_and_store_u8_s16(const int16x8_t a0, const int16x8_t a1,
const int16x8_t a2, const int16x8_t a3,
const int16x8_t a4, const int16x8_t a5,
const int16x8_t a6, const int16x8_t a7,
uint8_t *b, const int b_stride) {
uint8x8_t b0, b1, b2, b3, b4, b5, b6, b7;
int16x8_t c0, c1, c2, c3, c4, c5, c6, c7;
b0 = vld1_u8(b);
b += b_stride;
b1 = vld1_u8(b);
b += b_stride;
b2 = vld1_u8(b);
b += b_stride;
b3 = vld1_u8(b);
b += b_stride;
b4 = vld1_u8(b);
b += b_stride;
b5 = vld1_u8(b);
b += b_stride;
b6 = vld1_u8(b);
b += b_stride;
b7 = vld1_u8(b);
b -= (7 * b_stride);
static INLINE void add_and_store_u8_s16(const int16x8_t *const a, uint8_t *d,
const int stride) {
uint8x8_t b[8];
int16x8_t c[8];
b[0] = vld1_u8(d);
d += stride;
b[1] = vld1_u8(d);
d += stride;
b[2] = vld1_u8(d);
d += stride;
b[3] = vld1_u8(d);
d += stride;
b[4] = vld1_u8(d);
d += stride;
b[5] = vld1_u8(d);
d += stride;
b[6] = vld1_u8(d);
d += stride;
b[7] = vld1_u8(d);
d -= (7 * stride);
// c = b + (a >> 6)
c0 = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b0)), a0, 6);
c1 = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b1)), a1, 6);
c2 = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b2)), a2, 6);
c3 = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b3)), a3, 6);
c4 = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b4)), a4, 6);
c5 = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b5)), a5, 6);
c6 = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b6)), a6, 6);
c7 = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b7)), a7, 6);
c[0] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[0])), a[0], 6);
c[1] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[1])), a[1], 6);
c[2] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[2])), a[2], 6);
c[3] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[3])), a[3], 6);
c[4] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[4])), a[4], 6);
c[5] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[5])), a[5], 6);
c[6] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[6])), a[6], 6);
c[7] = vrsraq_n_s16(vreinterpretq_s16_u16(vmovl_u8(b[7])), a[7], 6);
b0 = vqmovun_s16(c0);
b1 = vqmovun_s16(c1);
b2 = vqmovun_s16(c2);
b3 = vqmovun_s16(c3);
b4 = vqmovun_s16(c4);
b5 = vqmovun_s16(c5);
b6 = vqmovun_s16(c6);
b7 = vqmovun_s16(c7);
b[0] = vqmovun_s16(c[0]);
b[1] = vqmovun_s16(c[1]);
b[2] = vqmovun_s16(c[2]);
b[3] = vqmovun_s16(c[3]);
b[4] = vqmovun_s16(c[4]);
b[5] = vqmovun_s16(c[5]);
b[6] = vqmovun_s16(c[6]);
b[7] = vqmovun_s16(c[7]);
vst1_u8(b, b0);
b += b_stride;
vst1_u8(b, b1);
b += b_stride;
vst1_u8(b, b2);
b += b_stride;
vst1_u8(b, b3);
b += b_stride;
vst1_u8(b, b4);
b += b_stride;
vst1_u8(b, b5);
b += b_stride;
vst1_u8(b, b6);
b += b_stride;
vst1_u8(b, b7);
vst1_u8(d, b[0]);
d += stride;
vst1_u8(d, b[1]);
d += stride;
vst1_u8(d, b[2]);
d += stride;
vst1_u8(d, b[3]);
d += stride;
vst1_u8(d, b[4]);
d += stride;
vst1_u8(d, b[5]);
d += stride;
vst1_u8(d, b[6]);
d += stride;
vst1_u8(d, b[7]);
}
static INLINE uint8x16_t create_dcq(const int16_t dc) {
@ -284,55 +282,53 @@ static INLINE uint8x16_t create_dcq(const int16_t dc) {
}
static INLINE void idct4x4_16_kernel_bd8(const int16x4_t cospis,
int16x8_t *const a0,
int16x8_t *const a1) {
int16x4_t b0, b1, b2, b3;
int32x4_t c0, c1, c2, c3;
int16x8_t d0, d1;
int16x8_t *const a) {
int16x4_t b[4];
int32x4_t c[4];
int16x8_t d[2];
transpose_s16_4x4q(a0, a1);
b0 = vget_low_s16(*a0);
b1 = vget_high_s16(*a0);
b2 = vget_low_s16(*a1);
b3 = vget_high_s16(*a1);
c0 = vmull_lane_s16(b0, cospis, 2);
c2 = vmull_lane_s16(b1, cospis, 2);
c1 = vsubq_s32(c0, c2);
c0 = vaddq_s32(c0, c2);
c2 = vmull_lane_s16(b2, cospis, 3);
c3 = vmull_lane_s16(b2, cospis, 1);
c2 = vmlsl_lane_s16(c2, b3, cospis, 1);
c3 = vmlal_lane_s16(c3, b3, cospis, 3);
b0 = vrshrn_n_s32(c0, DCT_CONST_BITS);
b1 = vrshrn_n_s32(c1, DCT_CONST_BITS);
b2 = vrshrn_n_s32(c2, DCT_CONST_BITS);
b3 = vrshrn_n_s32(c3, DCT_CONST_BITS);
d0 = vcombine_s16(b0, b1);
d1 = vcombine_s16(b3, b2);
*a0 = vaddq_s16(d0, d1);
*a1 = vsubq_s16(d0, d1);
transpose_s16_4x4q(&a[0], &a[1]);
b[0] = vget_low_s16(a[0]);
b[1] = vget_high_s16(a[0]);
b[2] = vget_low_s16(a[1]);
b[3] = vget_high_s16(a[1]);
c[0] = vmull_lane_s16(b[0], cospis, 2);
c[2] = vmull_lane_s16(b[1], cospis, 2);
c[1] = vsubq_s32(c[0], c[2]);
c[0] = vaddq_s32(c[0], c[2]);
c[2] = vmull_lane_s16(b[2], cospis, 3);
c[3] = vmull_lane_s16(b[2], cospis, 1);
c[2] = vmlsl_lane_s16(c[2], b[3], cospis, 1);
c[3] = vmlal_lane_s16(c[3], b[3], cospis, 3);
b[0] = vrshrn_n_s32(c[0], DCT_CONST_BITS);
b[1] = vrshrn_n_s32(c[1], DCT_CONST_BITS);
b[2] = vrshrn_n_s32(c[2], DCT_CONST_BITS);
b[3] = vrshrn_n_s32(c[3], DCT_CONST_BITS);
d[0] = vcombine_s16(b[0], b[1]);
d[1] = vcombine_s16(b[3], b[2]);
a[0] = vaddq_s16(d[0], d[1]);
a[1] = vsubq_s16(d[0], d[1]);
}
static INLINE void idct8x8_12_pass1_bd8(
const int16x4_t cospis0, const int16x4_t cospisd0, const int16x4_t cospisd1,
int16x4_t *const io0, int16x4_t *const io1, int16x4_t *const io2,
int16x4_t *const io3, int16x4_t *const io4, int16x4_t *const io5,
int16x4_t *const io6, int16x4_t *const io7) {
static INLINE void idct8x8_12_pass1_bd8(const int16x4_t cospis0,
const int16x4_t cospisd0,
const int16x4_t cospisd1,
int16x4_t *const io) {
int16x4_t step1[8], step2[8];
int32x4_t t32[2];
transpose_s16_4x4d(io0, io1, io2, io3);
transpose_s16_4x4d(&io[0], &io[1], &io[2], &io[3]);
// stage 1
step1[4] = vqrdmulh_lane_s16(*io1, cospisd1, 3);
step1[5] = vqrdmulh_lane_s16(*io3, cospisd1, 2);
step1[6] = vqrdmulh_lane_s16(*io3, cospisd1, 1);
step1[7] = vqrdmulh_lane_s16(*io1, cospisd1, 0);
step1[4] = vqrdmulh_lane_s16(io[1], cospisd1, 3);
step1[5] = vqrdmulh_lane_s16(io[3], cospisd1, 2);
step1[6] = vqrdmulh_lane_s16(io[3], cospisd1, 1);
step1[7] = vqrdmulh_lane_s16(io[1], cospisd1, 0);
// stage 2
step2[1] = vqrdmulh_lane_s16(*io0, cospisd0, 2);
step2[2] = vqrdmulh_lane_s16(*io2, cospisd0, 3);
step2[3] = vqrdmulh_lane_s16(*io2, cospisd0, 1);
step2[1] = vqrdmulh_lane_s16(io[0], cospisd0, 2);
step2[2] = vqrdmulh_lane_s16(io[2], cospisd0, 3);
step2[3] = vqrdmulh_lane_s16(io[2], cospisd0, 1);
step2[4] = vadd_s16(step1[4], step1[5]);
step2[5] = vsub_s16(step1[4], step1[5]);
@ -352,32 +348,28 @@ static INLINE void idct8x8_12_pass1_bd8(
step1[6] = vrshrn_n_s32(t32[1], DCT_CONST_BITS);
// stage 4
*io0 = vadd_s16(step1[0], step2[7]);
*io1 = vadd_s16(step1[1], step1[6]);
*io2 = vadd_s16(step1[2], step1[5]);
*io3 = vadd_s16(step1[3], step2[4]);
*io4 = vsub_s16(step1[3], step2[4]);
*io5 = vsub_s16(step1[2], step1[5]);
*io6 = vsub_s16(step1[1], step1[6]);
*io7 = vsub_s16(step1[0], step2[7]);
io[0] = vadd_s16(step1[0], step2[7]);
io[1] = vadd_s16(step1[1], step1[6]);
io[2] = vadd_s16(step1[2], step1[5]);
io[3] = vadd_s16(step1[3], step2[4]);
io[4] = vsub_s16(step1[3], step2[4]);
io[5] = vsub_s16(step1[2], step1[5]);
io[6] = vsub_s16(step1[1], step1[6]);
io[7] = vsub_s16(step1[0], step2[7]);
}
static INLINE void idct8x8_12_pass2_bd8(
const int16x4_t cospis0, const int16x4_t cospisd0, const int16x4_t cospisd1,
const int16x4_t input0, const int16x4_t input1, const int16x4_t input2,
const int16x4_t input3, const int16x4_t input4, const int16x4_t input5,
const int16x4_t input6, const int16x4_t input7, int16x8_t *const output0,
int16x8_t *const output1, int16x8_t *const output2,
int16x8_t *const output3, int16x8_t *const output4,
int16x8_t *const output5, int16x8_t *const output6,
int16x8_t *const output7) {
static INLINE void idct8x8_12_pass2_bd8(const int16x4_t cospis0,
const int16x4_t cospisd0,
const int16x4_t cospisd1,
const int16x4_t *const input,
int16x8_t *const output) {
int16x8_t in[4];
int16x8_t step1[8], step2[8];
int32x4_t t32[8];
int16x4_t t16[8];
transpose_s16_4x8(input0, input1, input2, input3, input4, input5, input6,
input7, &in[0], &in[1], &in[2], &in[3]);
transpose_s16_4x8(input[0], input[1], input[2], input[3], input[4], input[5],
input[6], input[7], &in[0], &in[1], &in[2], &in[3]);
// stage 1
step1[4] = vqrdmulhq_lane_s16(in[1], cospisd1, 3);
@ -415,66 +407,63 @@ static INLINE void idct8x8_12_pass2_bd8(
step1[6] = vcombine_s16(t16[2], t16[3]);
// stage 4
*output0 = vaddq_s16(step1[0], step2[7]);
*output1 = vaddq_s16(step1[1], step1[6]);
*output2 = vaddq_s16(step1[2], step1[5]);
*output3 = vaddq_s16(step1[3], step2[4]);
*output4 = vsubq_s16(step1[3], step2[4]);
*output5 = vsubq_s16(step1[2], step1[5]);
*output6 = vsubq_s16(step1[1], step1[6]);
*output7 = vsubq_s16(step1[0], step2[7]);
output[0] = vaddq_s16(step1[0], step2[7]);
output[1] = vaddq_s16(step1[1], step1[6]);
output[2] = vaddq_s16(step1[2], step1[5]);
output[3] = vaddq_s16(step1[3], step2[4]);
output[4] = vsubq_s16(step1[3], step2[4]);
output[5] = vsubq_s16(step1[2], step1[5]);
output[6] = vsubq_s16(step1[1], step1[6]);
output[7] = vsubq_s16(step1[0], step2[7]);
}
static INLINE void idct8x8_64_1d_bd8(const int16x4_t cospis0,
const int16x4_t cospis1,
int16x8_t *const io0, int16x8_t *const io1,
int16x8_t *const io2, int16x8_t *const io3,
int16x8_t *const io4, int16x8_t *const io5,
int16x8_t *const io6,
int16x8_t *const io7) {
int16x4_t input_1l, input_1h, input_3l, input_3h, input_5l, input_5h,
input_7l, input_7h;
int16x8_t *const io) {
int16x4_t input1l, input1h, input3l, input3h, input5l, input5h, input7l,
input7h;
int16x4_t step1l[4], step1h[4];
int16x8_t step1[8], step2[8];
int32x4_t t32[8];
int16x4_t t16[8];
transpose_s16_8x8(io0, io1, io2, io3, io4, io5, io6, io7);
transpose_s16_8x8(&io[0], &io[1], &io[2], &io[3], &io[4], &io[5], &io[6],
&io[7]);
// stage 1
input_1l = vget_low_s16(*io1);
input_1h = vget_high_s16(*io1);
input_3l = vget_low_s16(*io3);
input_3h = vget_high_s16(*io3);
input_5l = vget_low_s16(*io5);
input_5h = vget_high_s16(*io5);
input_7l = vget_low_s16(*io7);
input_7h = vget_high_s16(*io7);
step1l[0] = vget_low_s16(*io0);
step1h[0] = vget_high_s16(*io0);
step1l[1] = vget_low_s16(*io2);
step1h[1] = vget_high_s16(*io2);
step1l[2] = vget_low_s16(*io4);
step1h[2] = vget_high_s16(*io4);
step1l[3] = vget_low_s16(*io6);
step1h[3] = vget_high_s16(*io6);
input1l = vget_low_s16(io[1]);
input1h = vget_high_s16(io[1]);
input3l = vget_low_s16(io[3]);
input3h = vget_high_s16(io[3]);
input5l = vget_low_s16(io[5]);
input5h = vget_high_s16(io[5]);
input7l = vget_low_s16(io[7]);
input7h = vget_high_s16(io[7]);
step1l[0] = vget_low_s16(io[0]);
step1h[0] = vget_high_s16(io[0]);
step1l[1] = vget_low_s16(io[2]);
step1h[1] = vget_high_s16(io[2]);
step1l[2] = vget_low_s16(io[4]);
step1h[2] = vget_high_s16(io[4]);
step1l[3] = vget_low_s16(io[6]);
step1h[3] = vget_high_s16(io[6]);
t32[0] = vmull_lane_s16(input_1l, cospis1, 3);
t32[1] = vmull_lane_s16(input_1h, cospis1, 3);
t32[2] = vmull_lane_s16(input_3l, cospis1, 2);
t32[3] = vmull_lane_s16(input_3h, cospis1, 2);
t32[4] = vmull_lane_s16(input_3l, cospis1, 1);
t32[5] = vmull_lane_s16(input_3h, cospis1, 1);
t32[6] = vmull_lane_s16(input_1l, cospis1, 0);
t32[7] = vmull_lane_s16(input_1h, cospis1, 0);
t32[0] = vmlsl_lane_s16(t32[0], input_7l, cospis1, 0);
t32[1] = vmlsl_lane_s16(t32[1], input_7h, cospis1, 0);
t32[2] = vmlal_lane_s16(t32[2], input_5l, cospis1, 1);
t32[3] = vmlal_lane_s16(t32[3], input_5h, cospis1, 1);
t32[4] = vmlsl_lane_s16(t32[4], input_5l, cospis1, 2);
t32[5] = vmlsl_lane_s16(t32[5], input_5h, cospis1, 2);
t32[6] = vmlal_lane_s16(t32[6], input_7l, cospis1, 3);
t32[7] = vmlal_lane_s16(t32[7], input_7h, cospis1, 3);
t32[0] = vmull_lane_s16(input1l, cospis1, 3);
t32[1] = vmull_lane_s16(input1h, cospis1, 3);
t32[2] = vmull_lane_s16(input3l, cospis1, 2);
t32[3] = vmull_lane_s16(input3h, cospis1, 2);
t32[4] = vmull_lane_s16(input3l, cospis1, 1);
t32[5] = vmull_lane_s16(input3h, cospis1, 1);
t32[6] = vmull_lane_s16(input1l, cospis1, 0);
t32[7] = vmull_lane_s16(input1h, cospis1, 0);
t32[0] = vmlsl_lane_s16(t32[0], input7l, cospis1, 0);
t32[1] = vmlsl_lane_s16(t32[1], input7h, cospis1, 0);
t32[2] = vmlal_lane_s16(t32[2], input5l, cospis1, 1);
t32[3] = vmlal_lane_s16(t32[3], input5h, cospis1, 1);
t32[4] = vmlsl_lane_s16(t32[4], input5l, cospis1, 2);
t32[5] = vmlsl_lane_s16(t32[5], input5h, cospis1, 2);
t32[6] = vmlal_lane_s16(t32[6], input7l, cospis1, 3);
t32[7] = vmlal_lane_s16(t32[7], input7h, cospis1, 3);
t16[0] = vrshrn_n_s32(t32[0], DCT_CONST_BITS);
t16[1] = vrshrn_n_s32(t32[1], DCT_CONST_BITS);
t16[2] = vrshrn_n_s32(t32[2], DCT_CONST_BITS);
@ -541,14 +530,14 @@ static INLINE void idct8x8_64_1d_bd8(const int16x4_t cospis0,
step1[6] = vcombine_s16(t16[2], t16[3]);
// stage 4
*io0 = vaddq_s16(step1[0], step2[7]);
*io1 = vaddq_s16(step1[1], step1[6]);
*io2 = vaddq_s16(step1[2], step1[5]);
*io3 = vaddq_s16(step1[3], step2[4]);
*io4 = vsubq_s16(step1[3], step2[4]);
*io5 = vsubq_s16(step1[2], step1[5]);
*io6 = vsubq_s16(step1[1], step1[6]);
*io7 = vsubq_s16(step1[0], step2[7]);
io[0] = vaddq_s16(step1[0], step2[7]);
io[1] = vaddq_s16(step1[1], step1[6]);
io[2] = vaddq_s16(step1[2], step1[5]);
io[3] = vaddq_s16(step1[3], step2[4]);
io[4] = vsubq_s16(step1[3], step2[4]);
io[5] = vsubq_s16(step1[2], step1[5]);
io[6] = vsubq_s16(step1[1], step1[6]);
io[7] = vsubq_s16(step1[0], step2[7]);
}
static INLINE void idct16x16_add_wrap_low_8x2(const int32x4_t *const t32,
@ -786,73 +775,72 @@ static INLINE void idct16x16_store_pass1(const int16x8_t *const out,
vst1q_s16(output, out[15]);
}
static INLINE void idct16x16_add8x1(int16x8_t res, uint8_t **dest,
static INLINE void idct16x16_add8x1(const int16x8_t a, uint8_t **const dest,
const int stride) {
uint8x8_t d = vld1_u8(*dest);
uint16x8_t q;
res = vrshrq_n_s16(res, 6);
q = vaddw_u8(vreinterpretq_u16_s16(res), d);
d = vqmovun_s16(vreinterpretq_s16_u16(q));
const uint8x8_t s = vld1_u8(*dest);
const int16x8_t res = vrshrq_n_s16(a, 6);
const uint16x8_t q = vaddw_u8(vreinterpretq_u16_s16(res), s);
const uint8x8_t d = vqmovun_s16(vreinterpretq_s16_u16(q));
vst1_u8(*dest, d);
*dest += stride;
}
static INLINE void highbd_idct16x16_add8x1(int16x8_t res, const int16x8_t max,
uint16_t **dest, const int stride) {
uint16x8_t d = vld1q_u16(*dest);
res = vqaddq_s16(res, vreinterpretq_s16_u16(d));
res = vminq_s16(res, max);
d = vqshluq_n_s16(res, 0);
static INLINE void highbd_idct16x16_add8x1(const int16x8_t a,
const int16x8_t max,
uint16_t **const dest,
const int stride) {
const uint16x8_t s = vld1q_u16(*dest);
const int16x8_t res0 = vqaddq_s16(a, vreinterpretq_s16_u16(s));
const int16x8_t res1 = vminq_s16(res0, max);
const uint16x8_t d = vqshluq_n_s16(res1, 0);
vst1q_u16(*dest, d);
*dest += stride;
}
static INLINE void highbd_idct16x16_add8x1_bd8(int16x8_t res, uint16_t **dest,
static INLINE void highbd_idct16x16_add8x1_bd8(const int16x8_t a,
uint16_t **const dest,
const int stride) {
uint16x8_t d = vld1q_u16(*dest);
res = vrsraq_n_s16(vreinterpretq_s16_u16(d), res, 6);
d = vmovl_u8(vqmovun_s16(res));
const uint16x8_t s = vld1q_u16(*dest);
const int16x8_t res = vrsraq_n_s16(vreinterpretq_s16_u16(s), a, 6);
const uint16x8_t d = vmovl_u8(vqmovun_s16(res));
vst1q_u16(*dest, d);
*dest += stride;
}
static INLINE void highbd_add_and_store_bd8(const int16x8_t *const a,
uint16_t *out, const int b_stride) {
highbd_idct16x16_add8x1_bd8(a[0], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[1], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[2], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[3], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[4], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[5], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[6], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[7], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[8], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[9], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[10], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[11], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[12], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[13], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[14], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[15], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[16], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[17], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[18], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[19], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[20], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[21], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[22], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[23], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[24], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[25], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[26], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[27], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[28], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[29], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[30], &out, b_stride);
highbd_idct16x16_add8x1_bd8(a[31], &out, b_stride);
uint16_t *out, const int stride) {
highbd_idct16x16_add8x1_bd8(a[0], &out, stride);
highbd_idct16x16_add8x1_bd8(a[1], &out, stride);
highbd_idct16x16_add8x1_bd8(a[2], &out, stride);
highbd_idct16x16_add8x1_bd8(a[3], &out, stride);
highbd_idct16x16_add8x1_bd8(a[4], &out, stride);
highbd_idct16x16_add8x1_bd8(a[5], &out, stride);
highbd_idct16x16_add8x1_bd8(a[6], &out, stride);
highbd_idct16x16_add8x1_bd8(a[7], &out, stride);
highbd_idct16x16_add8x1_bd8(a[8], &out, stride);
highbd_idct16x16_add8x1_bd8(a[9], &out, stride);
highbd_idct16x16_add8x1_bd8(a[10], &out, stride);
highbd_idct16x16_add8x1_bd8(a[11], &out, stride);
highbd_idct16x16_add8x1_bd8(a[12], &out, stride);
highbd_idct16x16_add8x1_bd8(a[13], &out, stride);
highbd_idct16x16_add8x1_bd8(a[14], &out, stride);
highbd_idct16x16_add8x1_bd8(a[15], &out, stride);
highbd_idct16x16_add8x1_bd8(a[16], &out, stride);
highbd_idct16x16_add8x1_bd8(a[17], &out, stride);
highbd_idct16x16_add8x1_bd8(a[18], &out, stride);
highbd_idct16x16_add8x1_bd8(a[19], &out, stride);
highbd_idct16x16_add8x1_bd8(a[20], &out, stride);
highbd_idct16x16_add8x1_bd8(a[21], &out, stride);
highbd_idct16x16_add8x1_bd8(a[22], &out, stride);
highbd_idct16x16_add8x1_bd8(a[23], &out, stride);
highbd_idct16x16_add8x1_bd8(a[24], &out, stride);
highbd_idct16x16_add8x1_bd8(a[25], &out, stride);
highbd_idct16x16_add8x1_bd8(a[26], &out, stride);
highbd_idct16x16_add8x1_bd8(a[27], &out, stride);
highbd_idct16x16_add8x1_bd8(a[28], &out, stride);
highbd_idct16x16_add8x1_bd8(a[29], &out, stride);
highbd_idct16x16_add8x1_bd8(a[30], &out, stride);
highbd_idct16x16_add8x1_bd8(a[31], &out, stride);
}
static INLINE void highbd_idct16x16_add_store(const int32x4x2_t *const out,