• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdefx
 

tdefx

  • tdefx
kcpuinfo.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2003 Fredrik Höglund <fredrik@kde.org>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <csignal>
28 #include <csetjmp>
29 
30 #include <config.h>
31 #include "kcpuinfo.h"
32 
33 
34 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
35 # define HAVE_GNU_INLINE_ASM
36 #endif
37 
38 typedef void (*kde_sighandler_t) (int);
39 
40 #ifdef __i386__
41 static jmp_buf env;
42 
43 // Sighandler for the SSE OS support check
44 static void sighandler( int )
45 {
46  std::longjmp( env, 1 );
47 }
48 #endif
49 
50 #ifdef __PPC__
51 static sigjmp_buf TDE_NO_EXPORT jmpbuf;
52 static sig_atomic_t TDE_NO_EXPORT canjump = 0;
53 
54 static void TDE_NO_EXPORT sigill_handler( int sig )
55 {
56  if ( !canjump ) {
57  signal( sig, SIG_DFL );
58  raise( sig );
59  }
60  canjump = 0;
61  siglongjmp( jmpbuf, 1 );
62 }
63 #endif
64 
65 static int getCpuFeatures()
66 {
67  volatile int features = 0;
68 
69 #if defined( HAVE_GNU_INLINE_ASM )
70 #if defined( __i386__ )
71  bool haveCPUID = false;
72  bool have3DNOW = false;
73  int result = 0;
74 
75  // First check if the CPU supports the CPUID instruction
76  __asm__ __volatile__(
77  // Try to toggle the CPUID bit in the EFLAGS register
78  "pushf \n\t" // Push the EFLAGS register onto the stack
79  "popl %%ecx \n\t" // Pop the value into ECX
80  "movl %%ecx, %%edx \n\t" // Copy ECX to EDX
81  "xorl $0x00200000, %%ecx \n\t" // Toggle bit 21 (CPUID) in ECX
82  "pushl %%ecx \n\t" // Push the modified value onto the stack
83  "popf \n\t" // Pop it back into EFLAGS
84 
85  // Check if the CPUID bit was successfully toggled
86  "pushf \n\t" // Push EFLAGS back onto the stack
87  "popl %%ecx \n\t" // Pop the value into ECX
88  "xorl %%eax, %%eax \n\t" // Zero out the EAX register
89  "cmpl %%ecx, %%edx \n\t" // Compare ECX with EDX
90  "je .Lno_cpuid_support%= \n\t" // Jump if they're identical
91  "movl $1, %%eax \n\t" // Set EAX to true
92  ".Lno_cpuid_support%=: \n\t"
93  : "=a"(haveCPUID) : : "%ecx", "%edx" );
94 
95  // If we don't have CPUID we won't have the other extensions either
96  if ( ! haveCPUID )
97  return 0L;
98 
99  // Execute CPUID with the feature request bit set
100  __asm__ __volatile__(
101  "pushl %%ebx \n\t" // Save EBX
102  "movl $1, %%eax \n\t" // Set EAX to 1 (features request)
103  "cpuid \n\t" // Call CPUID
104  "popl %%ebx \n\t" // Restore EBX
105  : "=d"(result) : : "%eax", "%ecx" );
106 
107  // Test bit 23 (MMX support)
108  if ( result & 0x00800000 )
109  features |= KCPUInfo::IntelMMX;
110 
111  __asm__ __volatile__(
112  "pushl %%ebx \n\t"
113  "movl $0x80000000, %%eax \n\t"
114  "cpuid \n\t"
115  "cmpl $0x80000000, %%eax \n\t"
116  "jbe .Lno_extended%= \n\t"
117  "movl $0x80000001, %%eax \n\t"
118  "cpuid \n\t"
119  "test $0x80000000, %%edx \n\t"
120  "jz .Lno_extended%= \n\t"
121  "movl $1, %%eax \n\t" // // Set EAX to true
122  ".Lno_extended%=: \n\t"
123  "popl %%ebx \n\t" // Restore EBX
124  : "=a"(have3DNOW) : );
125 
126  if ( have3DNOW )
127  features |= KCPUInfo::AMD3DNOW;
128 
129 #ifdef HAVE_X86_SSE
130  // Test bit 25 (SSE support)
131  if ( result & 0x00200000 ) {
132  features |= KCPUInfo::IntelSSE;
133 
134  // OS support test for SSE.
135  // Install our own sighandler for SIGILL.
136  kde_sighandler_t oldhandler = std::signal( SIGILL, sighandler );
137 
138  // Try executing an SSE insn to see if we get a SIGILL
139  if ( setjmp( env ) )
140  features ^= KCPUInfo::IntelSSE; // The OS support test failed
141  else
142  __asm__ __volatile__("xorps %xmm0, %xmm0");
143 
144  // Restore the default sighandler
145  std::signal( SIGILL, oldhandler );
146 
147  // Test bit 26 (SSE2 support)
148  if ( (result & 0x00400000) && (features & KCPUInfo::IntelSSE) )
149  features |= KCPUInfo::IntelSSE2;
150 
151  // Note: The OS requirements for SSE2 are the same as for SSE
152  // so we don't have to do any additional tests for that.
153  }
154 #endif // HAVE_X86_SSE
155 #elif defined __PPC__ && defined HAVE_PPC_ALTIVEC
156  signal( SIGILL, sigill_handler );
157  if ( sigsetjmp( jmpbuf, 1 ) ) {
158  signal( SIGILL, SIG_DFL );
159  } else {
160  canjump = 1;
161  __asm__ __volatile__( "mtspr 256, %0\n\t"
162  "vand %%v0, %%v0, %%v0"
163  : /* none */
164  : "r" (-1) );
165  signal( SIGILL, SIG_DFL );
166  features |= KCPUInfo::AltiVec;
167  }
168 #endif // __i386__
169 #endif //HAVE_GNU_INLINE_ASM
170 
171  return features;
172 }
173 
174 unsigned int KCPUInfo::s_features = getCpuFeatures();
175 
176 
KCPUInfo::IntelSSE
@ IntelSSE
Intel's SSE instructions.
Definition: kcpuinfo.h:48
KCPUInfo::IntelSSE2
@ IntelSSE2
Intel's SSE2 instructions.
Definition: kcpuinfo.h:49
KCPUInfo::AltiVec
@ AltiVec
Motorola AltiVec instructions.
Definition: kcpuinfo.h:51
KCPUInfo::AMD3DNOW
@ AMD3DNOW
AMD 3DNOW instructions.
Definition: kcpuinfo.h:50
KCPUInfo::IntelMMX
@ IntelMMX
Intel's MMX instructions.
Definition: kcpuinfo.h:47

tdefx

Skip menu "tdefx"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

tdefx

Skip menu "tdefx"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdefx by doxygen 1.9.1
This website is maintained by Timothy Pearson.