OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 Google Inc. All Rights Reserved. |
| 2 // |
| 3 // Use of this source code is governed by a BSD-style license |
| 4 // that can be found in the COPYING file in the root of the source |
| 5 // tree. An additional intellectual property rights grant can be found |
| 6 // in the file PATENTS. All contributing project authors may |
| 7 // be found in the AUTHORS file in the root of the source tree. |
| 8 // ----------------------------------------------------------------------------- |
| 9 // |
| 10 // SSE2 code common to several files. |
| 11 // |
| 12 // Author: Vincent Rabaud (vrabaud@google.com) |
| 13 |
| 14 #ifndef WEBP_DSP_COMMON_SSE2_H_ |
| 15 #define WEBP_DSP_COMMON_SSE2_H_ |
| 16 |
| 17 #ifdef __cplusplus |
| 18 extern "C" { |
| 19 #endif |
| 20 |
| 21 #if defined(WEBP_USE_SSE2) |
| 22 |
| 23 #include <emmintrin.h> |
| 24 |
| 25 //------------------------------------------------------------------------------ |
| 26 // Quite useful macro for debugging. Left here for convenience. |
| 27 |
| 28 #if 0 |
| 29 #include <stdio.h> |
| 30 static WEBP_INLINE void PrintReg(const __m128i r, const char* const name, |
| 31 int size) { |
| 32 int n; |
| 33 union { |
| 34 __m128i r; |
| 35 uint8_t i8[16]; |
| 36 uint16_t i16[8]; |
| 37 uint32_t i32[4]; |
| 38 uint64_t i64[2]; |
| 39 } tmp; |
| 40 tmp.r = r; |
| 41 fprintf(stderr, "%s\t: ", name); |
| 42 if (size == 8) { |
| 43 for (n = 0; n < 16; ++n) fprintf(stderr, "%.2x ", tmp.i8[n]); |
| 44 } else if (size == 16) { |
| 45 for (n = 0; n < 8; ++n) fprintf(stderr, "%.4x ", tmp.i16[n]); |
| 46 } else if (size == 32) { |
| 47 for (n = 0; n < 4; ++n) fprintf(stderr, "%.8x ", tmp.i32[n]); |
| 48 } else { |
| 49 for (n = 0; n < 2; ++n) fprintf(stderr, "%.16lx ", tmp.i64[n]); |
| 50 } |
| 51 fprintf(stderr, "\n"); |
| 52 } |
| 53 #endif |
| 54 |
| 55 //------------------------------------------------------------------------------ |
| 56 // Math functions. |
| 57 |
| 58 // Return the sum of all the 8b in the register. |
| 59 static WEBP_INLINE int VP8HorizontalAdd8b(const __m128i* const a) { |
| 60 const __m128i zero = _mm_setzero_si128(); |
| 61 const __m128i sad8x2 = _mm_sad_epu8(*a, zero); |
| 62 // sum the two sads: sad8x2[0:1] + sad8x2[8:9] |
| 63 const __m128i sum = _mm_add_epi32(sad8x2, _mm_shuffle_epi32(sad8x2, 2)); |
| 64 return _mm_cvtsi128_si32(sum); |
| 65 } |
| 66 |
| 67 // Transpose two 4x4 16b matrices horizontally stored in registers. |
| 68 static WEBP_INLINE void VP8Transpose_2_4x4_16b( |
| 69 const __m128i* const in0, const __m128i* const in1, |
| 70 const __m128i* const in2, const __m128i* const in3, __m128i* const out0, |
| 71 __m128i* const out1, __m128i* const out2, __m128i* const out3) { |
| 72 // Transpose the two 4x4. |
| 73 // a00 a01 a02 a03 b00 b01 b02 b03 |
| 74 // a10 a11 a12 a13 b10 b11 b12 b13 |
| 75 // a20 a21 a22 a23 b20 b21 b22 b23 |
| 76 // a30 a31 a32 a33 b30 b31 b32 b33 |
| 77 const __m128i transpose0_0 = _mm_unpacklo_epi16(*in0, *in1); |
| 78 const __m128i transpose0_1 = _mm_unpacklo_epi16(*in2, *in3); |
| 79 const __m128i transpose0_2 = _mm_unpackhi_epi16(*in0, *in1); |
| 80 const __m128i transpose0_3 = _mm_unpackhi_epi16(*in2, *in3); |
| 81 // a00 a10 a01 a11 a02 a12 a03 a13 |
| 82 // a20 a30 a21 a31 a22 a32 a23 a33 |
| 83 // b00 b10 b01 b11 b02 b12 b03 b13 |
| 84 // b20 b30 b21 b31 b22 b32 b23 b33 |
| 85 const __m128i transpose1_0 = _mm_unpacklo_epi32(transpose0_0, transpose0_1); |
| 86 const __m128i transpose1_1 = _mm_unpacklo_epi32(transpose0_2, transpose0_3); |
| 87 const __m128i transpose1_2 = _mm_unpackhi_epi32(transpose0_0, transpose0_1); |
| 88 const __m128i transpose1_3 = _mm_unpackhi_epi32(transpose0_2, transpose0_3); |
| 89 // a00 a10 a20 a30 a01 a11 a21 a31 |
| 90 // b00 b10 b20 b30 b01 b11 b21 b31 |
| 91 // a02 a12 a22 a32 a03 a13 a23 a33 |
| 92 // b02 b12 a22 b32 b03 b13 b23 b33 |
| 93 *out0 = _mm_unpacklo_epi64(transpose1_0, transpose1_1); |
| 94 *out1 = _mm_unpackhi_epi64(transpose1_0, transpose1_1); |
| 95 *out2 = _mm_unpacklo_epi64(transpose1_2, transpose1_3); |
| 96 *out3 = _mm_unpackhi_epi64(transpose1_2, transpose1_3); |
| 97 // a00 a10 a20 a30 b00 b10 b20 b30 |
| 98 // a01 a11 a21 a31 b01 b11 b21 b31 |
| 99 // a02 a12 a22 a32 b02 b12 b22 b32 |
| 100 // a03 a13 a23 a33 b03 b13 b23 b33 |
| 101 } |
| 102 |
| 103 #endif // WEBP_USE_SSE2 |
| 104 |
| 105 #ifdef __cplusplus |
| 106 } // extern "C" |
| 107 #endif |
| 108 |
| 109 #endif // WEBP_DSP_COMMON_SSE2_H_ |
OLD | NEW |