]> git.sesse.net Git - x264/blob - common/cpu.c
remove sad_pde. it's been unused ever since successive elimination replaced it.
[x264] / common / cpu.c
1 /*****************************************************************************
2  * cpu.c: h264 encoder library
3  *****************************************************************************
4  * Copyright (C) 2003 Laurent Aimar
5  * $Id: cpu.c,v 1.1 2004/06/03 19:27:06 fenrir Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #if defined(HAVE_PTHREAD) && defined(SYS_LINUX)
25 #define _GNU_SOURCE
26 #include <sched.h>
27 #endif
28 #ifdef SYS_BEOS
29 #include <kernel/OS.h>
30 #endif
31 #ifdef SYS_MACOSX
32 #include <sys/types.h>
33 #include <sys/sysctl.h>
34 #endif
35
36 #include "common.h"
37
38 #ifdef HAVE_MMX
39 extern int  x264_cpu_cpuid_test( void );
40 extern uint32_t  x264_cpu_cpuid( uint32_t op, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx );
41 extern void x264_emms( void );
42
43 uint32_t x264_cpu_detect( void )
44 {
45     uint32_t cpu = 0;
46
47     uint32_t eax, ebx, ecx, edx;
48     int      b_amd;
49
50     if( !x264_cpu_cpuid_test() )
51     {
52         /* No cpuid */
53         return 0;
54     }
55
56     x264_cpu_cpuid( 0, &eax, &ebx, &ecx, &edx);
57     if( eax == 0 )
58     {
59         return 0;
60     }
61     b_amd   = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
62
63     x264_cpu_cpuid( 1, &eax, &ebx, &ecx, &edx );
64     if( (edx&0x00800000) == 0 )
65     {
66         /* No MMX */
67         return 0;
68     }
69     cpu = X264_CPU_MMX;
70     if( (edx&0x02000000) )
71     {
72         /* SSE - identical to AMD MMX extensions */
73         cpu |= X264_CPU_MMXEXT|X264_CPU_SSE;
74     }
75     if( (edx&0x04000000) )
76     {
77         /* Is it OK ? */
78         cpu |= X264_CPU_SSE2;
79     }
80 #ifdef HAVE_SSE3
81     if( (ecx&0x00000001) )
82     {
83         cpu |= X264_CPU_SSE3;
84     }
85     if( (ecx&0x00000200) )
86     {
87         cpu |= X264_CPU_SSSE3;
88     }
89 #endif
90
91     x264_cpu_cpuid( 0x80000000, &eax, &ebx, &ecx, &edx );
92     if( eax < 0x80000001 )
93     {
94         /* no extended capabilities */
95         return cpu;
96     }
97
98     x264_cpu_cpuid( 0x80000001, &eax, &ebx, &ecx, &edx );
99     if( edx&0x80000000 )
100     {
101         cpu |= X264_CPU_3DNOW;
102     }
103     if( b_amd && (edx&0x00400000) )
104     {
105         /* AMD MMX extensions */
106         cpu |= X264_CPU_MMXEXT;
107     }
108
109     return cpu;
110 }
111
112 void     x264_cpu_restore( uint32_t cpu )
113 {
114     if( cpu&(X264_CPU_MMX|X264_CPU_MMXEXT|X264_CPU_3DNOW|X264_CPU_3DNOWEXT) )
115     {
116         x264_emms();
117     }
118 }
119
120 #elif defined( ARCH_PPC )
121
122 #ifdef SYS_MACOSX
123 #include <sys/sysctl.h>
124 uint32_t x264_cpu_detect( void )
125 {
126     /* Thank you VLC */
127     uint32_t cpu = 0;
128     int      selectors[2] = { CTL_HW, HW_VECTORUNIT };
129     int      has_altivec = 0;
130     size_t   length = sizeof( has_altivec );
131     int      error = sysctl( selectors, 2, &has_altivec, &length, NULL, 0 );
132
133     if( error == 0 && has_altivec != 0 )
134     {
135         cpu |= X264_CPU_ALTIVEC;
136     }
137
138     return cpu;
139 }
140
141 #elif defined( SYS_LINUX )
142 #include <signal.h>
143 #include <setjmp.h>
144 static sigjmp_buf jmpbuf;
145 static volatile sig_atomic_t canjump = 0;
146
147 static void sigill_handler( int sig )
148 {
149     if( !canjump )
150     {
151         signal( sig, SIG_DFL );
152         raise( sig );
153     }
154
155     canjump = 0;
156     siglongjmp( jmpbuf, 1 );
157 }
158
159 uint32_t x264_cpu_detect( void )
160 {
161     static void (* oldsig)( int );
162
163     oldsig = signal( SIGILL, sigill_handler );
164     if( sigsetjmp( jmpbuf, 1 ) )
165     {
166         signal( SIGILL, oldsig );
167         return 0;
168     }
169
170     canjump = 1;
171     asm volatile( "mtspr 256, %0\n\t"
172                   "vand 0, 0, 0\n\t"
173                   :
174                   : "r"(-1) );
175     canjump = 0;
176
177     signal( SIGILL, oldsig );
178
179     return X264_CPU_ALTIVEC;
180 }
181 #endif
182
183 void     x264_cpu_restore( uint32_t cpu )
184 {
185 }
186
187 #else
188
189 uint32_t x264_cpu_detect( void )
190 {
191     return 0;
192 }
193
194 void     x264_cpu_restore( uint32_t cpu )
195 {
196 }
197
198 #endif
199
200
201 int x264_cpu_num_processors( void )
202 {
203 #if !defined(HAVE_PTHREAD)
204     return 1;
205
206 #elif defined(WIN32)
207     return pthread_num_processors_np();
208
209 #elif defined(SYS_LINUX)
210     unsigned int bit;
211     int np;
212     cpu_set_t p_aff;
213     memset( &p_aff, 0, sizeof(p_aff) );
214     sched_getaffinity( 0, sizeof(p_aff), &p_aff );
215     for( np = 0, bit = 0; bit < sizeof(p_aff); bit++ )
216         np += (((uint8_t *)&p_aff)[bit / 8] >> (bit % 8)) & 1;
217     return np;
218
219 #elif defined(SYS_BEOS)
220     system_info info;
221     get_system_info( &info );
222     return info.cpu_count;
223
224 #elif defined(SYS_MACOSX)
225     int numberOfCPUs;
226     size_t length = sizeof( numberOfCPUs );
227     if( sysctlbyname("hw.ncpu", &numberOfCPUs, &length, NULL, 0) )
228     {
229         numberOfCPUs = 1;
230     }
231     return numberOfCPUs;
232
233 #else
234     return 1;
235 #endif
236 }