| Index: src/opts/SkMath_opts_SSE2.h
|
| diff --git a/src/opts/SkMath_opts_SSE2.h b/src/opts/SkMath_opts_SSE2.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d8aeac9b7503b6b958f43633f42cdcc339b877e1
|
| --- /dev/null
|
| +++ b/src/opts/SkMath_opts_SSE2.h
|
| @@ -0,0 +1,43 @@
|
| +/*
|
| + * Copyright 2014 The Android Open Source Project
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#ifndef SkMath_opts_SSE2_DEFINED
|
| +#define SkMath_opts_SSE2_DEFINED
|
| +
|
| +#include <emmintrin.h>
|
| +
|
| +// Portable version of SkSqrtBits is in SkMath.cpp.
|
| +static inline __m128i SkSqrtBits_SSE2(const __m128i& x, int count) {
|
| + __m128i root = _mm_setzero_si128();
|
| + __m128i remHi = _mm_setzero_si128();
|
| + __m128i remLo = x;
|
| + __m128i one128 = _mm_set1_epi32(1);
|
| +
|
| + do {
|
| + root = _mm_slli_epi32(root, 1);
|
| +
|
| + remHi = _mm_or_si128(_mm_slli_epi32(remHi, 2),
|
| + _mm_srli_epi32(remLo, 30));
|
| + remLo = _mm_slli_epi32(remLo, 2);
|
| +
|
| + __m128i testDiv = _mm_slli_epi32(root, 1);
|
| + testDiv = _mm_add_epi32(testDiv, _mm_set1_epi32(1));
|
| +
|
| + __m128i cmp = _mm_cmplt_epi32(remHi, testDiv);
|
| + __m128i remHi1 = _mm_and_si128(cmp, remHi);
|
| + __m128i root1 = _mm_and_si128(cmp, root);
|
| + __m128i remHi2 = _mm_andnot_si128(cmp, _mm_sub_epi32(remHi, testDiv));
|
| + __m128i root2 = _mm_andnot_si128(cmp, _mm_add_epi32(root, one128));
|
| +
|
| + remHi = _mm_or_si128(remHi1, remHi2);
|
| + root = _mm_or_si128(root1, root2);
|
| + } while (--count >= 0);
|
| +
|
| + return root;
|
| +}
|
| +
|
| +#endif // SkMath_opts_SSE2_DEFINED
|
|
|