| Index: source/libvpx/vp9/encoder/x86/vp9_avg_intrin_sse2.c
|
| diff --git a/source/libvpx/vp9/encoder/x86/vp9_avg_intrin_sse2.c b/source/libvpx/vp9/encoder/x86/vp9_avg_intrin_sse2.c
|
| index 4e80b255e88fb318e31f25b504d380d46fb6afe7..4672aa6b8cf2300d123ebbae22a1daf8b2112490 100644
|
| --- a/source/libvpx/vp9/encoder/x86/vp9_avg_intrin_sse2.c
|
| +++ b/source/libvpx/vp9/encoder/x86/vp9_avg_intrin_sse2.c
|
| @@ -11,6 +11,83 @@
|
| #include <emmintrin.h>
|
| #include "vpx_ports/mem.h"
|
|
|
| +void vp9_minmax_8x8_sse2(const uint8_t *s, int p, const uint8_t *d, int dp,
|
| + int *min, int *max) {
|
| + __m128i u0, s0, d0, diff, maxabsdiff, minabsdiff, negdiff, absdiff0, absdiff;
|
| + u0 = _mm_setzero_si128();
|
| + // Row 0
|
| + s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s)), u0);
|
| + d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d)), u0);
|
| + diff = _mm_subs_epi16(s0, d0);
|
| + negdiff = _mm_subs_epi16(u0, diff);
|
| + absdiff0 = _mm_max_epi16(diff, negdiff);
|
| + // Row 1
|
| + s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + p)), u0);
|
| + d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + dp)), u0);
|
| + diff = _mm_subs_epi16(s0, d0);
|
| + negdiff = _mm_subs_epi16(u0, diff);
|
| + absdiff = _mm_max_epi16(diff, negdiff);
|
| + maxabsdiff = _mm_max_epi16(absdiff0, absdiff);
|
| + minabsdiff = _mm_min_epi16(absdiff0, absdiff);
|
| + // Row 2
|
| + s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 2 * p)), u0);
|
| + d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 2 * dp)), u0);
|
| + diff = _mm_subs_epi16(s0, d0);
|
| + negdiff = _mm_subs_epi16(u0, diff);
|
| + absdiff = _mm_max_epi16(diff, negdiff);
|
| + maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
| + minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
| + // Row 3
|
| + s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 3 * p)), u0);
|
| + d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 3 * dp)), u0);
|
| + diff = _mm_subs_epi16(s0, d0);
|
| + negdiff = _mm_subs_epi16(u0, diff);
|
| + absdiff = _mm_max_epi16(diff, negdiff);
|
| + maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
| + minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
| + // Row 4
|
| + s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 4 * p)), u0);
|
| + d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 4 * dp)), u0);
|
| + diff = _mm_subs_epi16(s0, d0);
|
| + negdiff = _mm_subs_epi16(u0, diff);
|
| + absdiff = _mm_max_epi16(diff, negdiff);
|
| + maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
| + minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
| + // Row 5
|
| + s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 5 * p)), u0);
|
| + d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 5 * dp)), u0);
|
| + diff = _mm_subs_epi16(s0, d0);
|
| + negdiff = _mm_subs_epi16(u0, diff);
|
| + absdiff = _mm_max_epi16(diff, negdiff);
|
| + maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
| + minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
| + // Row 6
|
| + s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 6 * p)), u0);
|
| + d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 6 * dp)), u0);
|
| + diff = _mm_subs_epi16(s0, d0);
|
| + negdiff = _mm_subs_epi16(u0, diff);
|
| + absdiff = _mm_max_epi16(diff, negdiff);
|
| + maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
| + minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
| + // Row 7
|
| + s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 7 * p)), u0);
|
| + d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 7 * dp)), u0);
|
| + diff = _mm_subs_epi16(s0, d0);
|
| + negdiff = _mm_subs_epi16(u0, diff);
|
| + absdiff = _mm_max_epi16(diff, negdiff);
|
| + maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
| + minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
| +
|
| + maxabsdiff = _mm_max_epi16(maxabsdiff, _mm_srli_si128(maxabsdiff, 8));
|
| + maxabsdiff = _mm_max_epi16(maxabsdiff, _mm_srli_epi64(maxabsdiff, 32));
|
| + maxabsdiff = _mm_max_epi16(maxabsdiff, _mm_srli_epi64(maxabsdiff, 16));
|
| + *max = _mm_extract_epi16(maxabsdiff, 0);
|
| +
|
| + minabsdiff = _mm_min_epi16(minabsdiff, _mm_srli_si128(minabsdiff, 8));
|
| + minabsdiff = _mm_min_epi16(minabsdiff, _mm_srli_epi64(minabsdiff, 32));
|
| + minabsdiff = _mm_min_epi16(minabsdiff, _mm_srli_epi64(minabsdiff, 16));
|
| + *min = _mm_extract_epi16(minabsdiff, 0);
|
| +}
|
|
|
| unsigned int vp9_avg_8x8_sse2(const uint8_t *s, int p) {
|
| __m128i s0, s1, u0;
|
| @@ -57,6 +134,179 @@ unsigned int vp9_avg_4x4_sse2(const uint8_t *s, int p) {
|
| return (avg + 8) >> 4;
|
| }
|
|
|
| +static void hadamard_col8_sse2(__m128i *in, int iter) {
|
| + __m128i a0 = in[0];
|
| + __m128i a1 = in[1];
|
| + __m128i a2 = in[2];
|
| + __m128i a3 = in[3];
|
| + __m128i a4 = in[4];
|
| + __m128i a5 = in[5];
|
| + __m128i a6 = in[6];
|
| + __m128i a7 = in[7];
|
| +
|
| + __m128i b0 = _mm_add_epi16(a0, a1);
|
| + __m128i b1 = _mm_sub_epi16(a0, a1);
|
| + __m128i b2 = _mm_add_epi16(a2, a3);
|
| + __m128i b3 = _mm_sub_epi16(a2, a3);
|
| + __m128i b4 = _mm_add_epi16(a4, a5);
|
| + __m128i b5 = _mm_sub_epi16(a4, a5);
|
| + __m128i b6 = _mm_add_epi16(a6, a7);
|
| + __m128i b7 = _mm_sub_epi16(a6, a7);
|
| +
|
| + a0 = _mm_add_epi16(b0, b2);
|
| + a1 = _mm_add_epi16(b1, b3);
|
| + a2 = _mm_sub_epi16(b0, b2);
|
| + a3 = _mm_sub_epi16(b1, b3);
|
| + a4 = _mm_add_epi16(b4, b6);
|
| + a5 = _mm_add_epi16(b5, b7);
|
| + a6 = _mm_sub_epi16(b4, b6);
|
| + a7 = _mm_sub_epi16(b5, b7);
|
| +
|
| + if (iter == 0) {
|
| + b0 = _mm_add_epi16(a0, a4);
|
| + b7 = _mm_add_epi16(a1, a5);
|
| + b3 = _mm_add_epi16(a2, a6);
|
| + b4 = _mm_add_epi16(a3, a7);
|
| + b2 = _mm_sub_epi16(a0, a4);
|
| + b6 = _mm_sub_epi16(a1, a5);
|
| + b1 = _mm_sub_epi16(a2, a6);
|
| + b5 = _mm_sub_epi16(a3, a7);
|
| +
|
| + a0 = _mm_unpacklo_epi16(b0, b1);
|
| + a1 = _mm_unpacklo_epi16(b2, b3);
|
| + a2 = _mm_unpackhi_epi16(b0, b1);
|
| + a3 = _mm_unpackhi_epi16(b2, b3);
|
| + a4 = _mm_unpacklo_epi16(b4, b5);
|
| + a5 = _mm_unpacklo_epi16(b6, b7);
|
| + a6 = _mm_unpackhi_epi16(b4, b5);
|
| + a7 = _mm_unpackhi_epi16(b6, b7);
|
| +
|
| + b0 = _mm_unpacklo_epi32(a0, a1);
|
| + b1 = _mm_unpacklo_epi32(a4, a5);
|
| + b2 = _mm_unpackhi_epi32(a0, a1);
|
| + b3 = _mm_unpackhi_epi32(a4, a5);
|
| + b4 = _mm_unpacklo_epi32(a2, a3);
|
| + b5 = _mm_unpacklo_epi32(a6, a7);
|
| + b6 = _mm_unpackhi_epi32(a2, a3);
|
| + b7 = _mm_unpackhi_epi32(a6, a7);
|
| +
|
| + in[0] = _mm_unpacklo_epi64(b0, b1);
|
| + in[1] = _mm_unpackhi_epi64(b0, b1);
|
| + in[2] = _mm_unpacklo_epi64(b2, b3);
|
| + in[3] = _mm_unpackhi_epi64(b2, b3);
|
| + in[4] = _mm_unpacklo_epi64(b4, b5);
|
| + in[5] = _mm_unpackhi_epi64(b4, b5);
|
| + in[6] = _mm_unpacklo_epi64(b6, b7);
|
| + in[7] = _mm_unpackhi_epi64(b6, b7);
|
| + } else {
|
| + in[0] = _mm_add_epi16(a0, a4);
|
| + in[7] = _mm_add_epi16(a1, a5);
|
| + in[3] = _mm_add_epi16(a2, a6);
|
| + in[4] = _mm_add_epi16(a3, a7);
|
| + in[2] = _mm_sub_epi16(a0, a4);
|
| + in[6] = _mm_sub_epi16(a1, a5);
|
| + in[1] = _mm_sub_epi16(a2, a6);
|
| + in[5] = _mm_sub_epi16(a3, a7);
|
| + }
|
| +}
|
| +
|
| +void vp9_hadamard_8x8_sse2(int16_t const *src_diff, int src_stride,
|
| + int16_t *coeff) {
|
| + __m128i src[8];
|
| + src[0] = _mm_load_si128((const __m128i *)src_diff);
|
| + src[1] = _mm_load_si128((const __m128i *)(src_diff += src_stride));
|
| + src[2] = _mm_load_si128((const __m128i *)(src_diff += src_stride));
|
| + src[3] = _mm_load_si128((const __m128i *)(src_diff += src_stride));
|
| + src[4] = _mm_load_si128((const __m128i *)(src_diff += src_stride));
|
| + src[5] = _mm_load_si128((const __m128i *)(src_diff += src_stride));
|
| + src[6] = _mm_load_si128((const __m128i *)(src_diff += src_stride));
|
| + src[7] = _mm_load_si128((const __m128i *)(src_diff += src_stride));
|
| +
|
| + hadamard_col8_sse2(src, 0);
|
| + hadamard_col8_sse2(src, 1);
|
| +
|
| + _mm_store_si128((__m128i *)coeff, src[0]);
|
| + coeff += 8;
|
| + _mm_store_si128((__m128i *)coeff, src[1]);
|
| + coeff += 8;
|
| + _mm_store_si128((__m128i *)coeff, src[2]);
|
| + coeff += 8;
|
| + _mm_store_si128((__m128i *)coeff, src[3]);
|
| + coeff += 8;
|
| + _mm_store_si128((__m128i *)coeff, src[4]);
|
| + coeff += 8;
|
| + _mm_store_si128((__m128i *)coeff, src[5]);
|
| + coeff += 8;
|
| + _mm_store_si128((__m128i *)coeff, src[6]);
|
| + coeff += 8;
|
| + _mm_store_si128((__m128i *)coeff, src[7]);
|
| +}
|
| +
|
| +void vp9_hadamard_16x16_sse2(int16_t const *src_diff, int src_stride,
|
| + int16_t *coeff) {
|
| + int idx;
|
| + for (idx = 0; idx < 4; ++idx) {
|
| + int16_t const *src_ptr = src_diff + (idx >> 1) * 8 * src_stride
|
| + + (idx & 0x01) * 8;
|
| + vp9_hadamard_8x8_sse2(src_ptr, src_stride, coeff + idx * 64);
|
| + }
|
| +
|
| + for (idx = 0; idx < 64; idx += 8) {
|
| + __m128i coeff0 = _mm_load_si128((const __m128i *)coeff);
|
| + __m128i coeff1 = _mm_load_si128((const __m128i *)(coeff + 64));
|
| + __m128i coeff2 = _mm_load_si128((const __m128i *)(coeff + 128));
|
| + __m128i coeff3 = _mm_load_si128((const __m128i *)(coeff + 192));
|
| +
|
| + __m128i b0 = _mm_add_epi16(coeff0, coeff1);
|
| + __m128i b1 = _mm_sub_epi16(coeff0, coeff1);
|
| + __m128i b2 = _mm_add_epi16(coeff2, coeff3);
|
| + __m128i b3 = _mm_sub_epi16(coeff2, coeff3);
|
| +
|
| + coeff0 = _mm_add_epi16(b0, b2);
|
| + coeff1 = _mm_add_epi16(b1, b3);
|
| + coeff0 = _mm_srai_epi16(coeff0, 1);
|
| + coeff1 = _mm_srai_epi16(coeff1, 1);
|
| + _mm_store_si128((__m128i *)coeff, coeff0);
|
| + _mm_store_si128((__m128i *)(coeff + 64), coeff1);
|
| +
|
| + coeff2 = _mm_sub_epi16(b0, b2);
|
| + coeff3 = _mm_sub_epi16(b1, b3);
|
| + coeff2 = _mm_srai_epi16(coeff2, 1);
|
| + coeff3 = _mm_srai_epi16(coeff3, 1);
|
| + _mm_store_si128((__m128i *)(coeff + 128), coeff2);
|
| + _mm_store_si128((__m128i *)(coeff + 192), coeff3);
|
| +
|
| + coeff += 8;
|
| + }
|
| +}
|
| +
|
| +int16_t vp9_satd_sse2(const int16_t *coeff, int length) {
|
| + int i;
|
| + __m128i sum = _mm_load_si128((const __m128i *)coeff);
|
| + __m128i sign = _mm_srai_epi16(sum, 15);
|
| + __m128i val = _mm_xor_si128(sum, sign);
|
| + sum = _mm_sub_epi16(val, sign);
|
| + coeff += 8;
|
| +
|
| + for (i = 8; i < length; i += 8) {
|
| + __m128i src_line = _mm_load_si128((const __m128i *)coeff);
|
| + sign = _mm_srai_epi16(src_line, 15);
|
| + val = _mm_xor_si128(src_line, sign);
|
| + val = _mm_sub_epi16(val, sign);
|
| + sum = _mm_add_epi16(sum, val);
|
| + coeff += 8;
|
| + }
|
| +
|
| + val = _mm_srli_si128(sum, 8);
|
| + sum = _mm_add_epi16(sum, val);
|
| + val = _mm_srli_epi64(sum, 32);
|
| + sum = _mm_add_epi16(sum, val);
|
| + val = _mm_srli_epi32(sum, 16);
|
| + sum = _mm_add_epi16(sum, val);
|
| +
|
| + return _mm_extract_epi16(sum, 0);
|
| +}
|
| +
|
| void vp9_int_pro_row_sse2(int16_t *hbuf, uint8_t const*ref,
|
| const int ref_stride, const int height) {
|
| int idx;
|
|
|