aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/opts/opts_check_SSE2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/opts/opts_check_SSE2.cpp')
-rw-r--r--src/opts/opts_check_SSE2.cpp104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/opts/opts_check_SSE2.cpp b/src/opts/opts_check_SSE2.cpp
new file mode 100644
index 0000000000..4757ed859e
--- /dev/null
+++ b/src/opts/opts_check_SSE2.cpp
@@ -0,0 +1,104 @@
+/*
+ **
+ ** Copyright 2009, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#include "SkBlitRow_opts_SSE2.h"
+#include "SkUtils_opts_SSE2.h"
+#include "SkUtils.h"
+
+/* This file must *not* be compiled with -msse or -msse2, otherwise
+ gcc may generate sse2 even for scalar ops (and thus give an invalid
+ instruction on Pentium3 on the code below). Only files named *_SSE2.cpp
+ in this directory should be compiled with -msse2. */
+
+#ifdef __x86_64__
+/* All x86_64 machines have SSE2, so don't even bother checking. */
+static inline bool hasSSE2() {
+ return true;
+}
+#else
+#ifdef _MSC_VER
+static inline void getcpuid(int info_type, int info[4]) {
+ __asm {
+ mov eax, [info_type]
+ cpuid
+ mov edi, [info]
+ mov [edi], eax
+ mov [edi+4], ebx
+ mov [edi+8], ecx
+ mov [edi+12], edx
+ }
+}
+#else
+static inline void getcpuid(int info_type, int info[4]) {
+ // We save and restore ebx, so this code can be compatible with -fPIC
+ asm volatile (
+ "pushl %%ebx \n\t"
+ "cpuid \n\t"
+ "movl %%ebx, %1 \n\t"
+ "popl %%ebx \n\t"
+ : "=a"(info[0]), "=r"(info[1]), "=c"(info[2]), "=d"(info[3])
+ : "a"(info_type)
+ :
+ );
+}
+#endif
+
+static inline bool hasSSE2() {
+ int cpu_info[4] = { 0 };
+ getcpuid(1, cpu_info);
+ return (cpu_info[3] & (1<<26)) != 0;
+}
+#endif
+
+static SkBlitRow::Proc32 platform_32_procs[] = {
+ NULL, // S32_Opaque,
+ S32_Blend_BlitRow32_SSE2, // S32_Blend,
+ S32A_Opaque_BlitRow32_SSE2, // S32A_Opaque
+ S32A_Blend_BlitRow32_SSE2, // S32A_Blend,
+};
+
+SkBlitRow::Proc SkBlitRow::PlatformProcs4444(unsigned flags) {
+ return NULL;
+}
+
+SkBlitRow::Proc SkBlitRow::PlatformProcs565(unsigned flags) {
+ return NULL;
+}
+
+SkBlitRow::Proc32 SkBlitRow::PlatformProcs32(unsigned flags) {
+ if (hasSSE2()) {
+ return platform_32_procs[flags];
+ } else {
+ return NULL;
+ }
+}
+
+SkMemset16Proc SkMemset16GetPlatformProc() {
+ if (hasSSE2()) {
+ return sk_memset16_SSE2;
+ } else {
+ return NULL;
+ }
+}
+
+SkMemset32Proc SkMemset32GetPlatformProc() {
+ if (hasSSE2()) {
+ return sk_memset32_SSE2;
+ } else {
+ return NULL;
+ }
+}