1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2009-2014 DreamWorks Animation LLC.
4 //
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met:
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
15 // distribution.
16 // * Neither the name of DreamWorks Animation nor the names of
17 // its contributors may be used to endorse or promote products derived
18 // from this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 //
32 ///////////////////////////////////////////////////////////////////////////
33
34 #include "ImfSimd.h"
35 #include "ImfSystemSpecific.h"
36 #include "ImfNamespace.h"
37 #include "OpenEXRConfig.h"
38
39 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
40
41 namespace {
42 #if defined(IMF_HAVE_SSE2) && defined(__GNUC__)
43
44 // Helper functions for gcc + SSE enabled
cpuid(int n,int & eax,int & ebx,int & ecx,int & edx)45 void cpuid(int n, int &eax, int &ebx, int &ecx, int &edx)
46 {
47 __asm__ __volatile__ (
48 "cpuid"
49 : /* Output */ "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
50 : /* Input */ "a"(n)
51 : /* Clobber */);
52 }
53
54 #else // IMF_HAVE_SSE2 && __GNUC__
55
56 // Helper functions for generic compiler - all disabled
57 void cpuid(int n, int &eax, int &ebx, int &ecx, int &edx)
58 {
59 eax = ebx = ecx = edx = 0;
60 }
61
62 #endif // IMF_HAVE_SSE2 && __GNUC__
63
64
65 #ifdef OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX
66
xgetbv(int n,int & eax,int & edx)67 void xgetbv(int n, int &eax, int &edx)
68 {
69 __asm__ __volatile__ (
70 "xgetbv"
71 : /* Output */ "=a"(eax), "=d"(edx)
72 : /* Input */ "c"(n)
73 : /* Clobber */);
74 }
75
76 #else // OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX
77
xgetbv(int n,int & eax,int & edx)78 void xgetbv(int n, int &eax, int &edx)
79 {
80 eax = edx = 0;
81 }
82
83 #endif // OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX
84
85 } // namespace
86
CpuId()87 CpuId::CpuId():
88 sse2(false),
89 sse3(false),
90 ssse3(false),
91 sse4_1(false),
92 sse4_2(false),
93 avx(false),
94 f16c(false)
95 {
96 bool osxsave = false;
97 int max = 0;
98 int eax, ebx, ecx, edx;
99
100 cpuid(0, max, ebx, ecx, edx);
101 if (max > 0)
102 {
103 cpuid(1, eax, ebx, ecx, edx);
104 sse2 = ( edx & (1<<26) );
105 sse3 = ( ecx & (1<< 0) );
106 ssse3 = ( ecx & (1<< 9) );
107 sse4_1 = ( ecx & (1<<19) );
108 sse4_2 = ( ecx & (1<<20) );
109 osxsave = ( ecx & (1<<27) );
110 avx = ( ecx & (1<<28) );
111 f16c = ( ecx & (1<<29) );
112
113 if (!osxsave)
114 {
115 avx = f16c = false;
116 }
117 else
118 {
119 xgetbv(0, eax, edx);
120 // eax bit 1 - SSE managed, bit 2 - AVX managed
121 if ((eax & 6) != 6)
122 {
123 avx = f16c = false;
124 }
125 }
126 }
127 }
128
129 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
130