OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2014 The Android Open Source Project |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. |
| 6 */ |
| 7 |
| 8 #ifndef SkMath_opts_SSE2_DEFINED |
| 9 #define SkMath_opts_SSE2_DEFINED |
| 10 |
| 11 #include <emmintrin.h> |
| 12 |
| 13 // Portable version of SkSqrtBits is in SkMath.cpp. |
| 14 static inline __m128i SkSqrtBits_SSE2(const __m128i& x, int count) { |
| 15 __m128i root = _mm_setzero_si128(); |
| 16 __m128i remHi = _mm_setzero_si128(); |
| 17 __m128i remLo = x; |
| 18 __m128i one128 = _mm_set1_epi32(1); |
| 19 |
| 20 do { |
| 21 root = _mm_slli_epi32(root, 1); |
| 22 |
| 23 remHi = _mm_or_si128(_mm_slli_epi32(remHi, 2), |
| 24 _mm_srli_epi32(remLo, 30)); |
| 25 remLo = _mm_slli_epi32(remLo, 2); |
| 26 |
| 27 __m128i testDiv = _mm_slli_epi32(root, 1); |
| 28 testDiv = _mm_add_epi32(testDiv, _mm_set1_epi32(1)); |
| 29 |
| 30 __m128i cmp = _mm_cmplt_epi32(remHi, testDiv); |
| 31 __m128i remHi1 = _mm_and_si128(cmp, remHi); |
| 32 __m128i root1 = _mm_and_si128(cmp, root); |
| 33 __m128i remHi2 = _mm_andnot_si128(cmp, _mm_sub_epi32(remHi, testDiv)); |
| 34 __m128i root2 = _mm_andnot_si128(cmp, _mm_add_epi32(root, one128)); |
| 35 |
| 36 remHi = _mm_or_si128(remHi1, remHi2); |
| 37 root = _mm_or_si128(root1, root2); |
| 38 } while (--count >= 0); |
| 39 |
| 40 return root; |
| 41 } |
| 42 |
| 43 #endif // SkMath_opts_SSE2_DEFINED |
OLD | NEW |