@@ -105,45 +105,6 @@ Mutex* __initialization_mutex_initializer = &getInitializationMutex();
105
105
#undef max
106
106
#undef abs
107
107
#include < tchar.h>
108
- #if defined _MSC_VER
109
- #if _MSC_VER >= 1400
110
- #include < intrin.h>
111
- #elif defined _M_IX86
112
- static void __cpuid (int * cpuid_data, int )
113
- {
114
- __asm
115
- {
116
- push ebx
117
- push edi
118
- mov edi, cpuid_data
119
- mov eax, 1
120
- cpuid
121
- mov [edi], eax
122
- mov [edi + 4 ], ebx
123
- mov [edi + 8 ], ecx
124
- mov [edi + 12 ], edx
125
- pop edi
126
- pop ebx
127
- }
128
- }
129
- static void __cpuidex (int * cpuid_data, int , int )
130
- {
131
- __asm
132
- {
133
- push edi
134
- mov edi, cpuid_data
135
- mov eax, 7
136
- mov ecx, 0
137
- cpuid
138
- mov [edi], eax
139
- mov [edi + 4 ], ebx
140
- mov [edi + 8 ], ecx
141
- mov [edi + 12 ], edx
142
- pop edi
143
- }
144
- }
145
- #endif
146
- #endif
147
108
148
109
#ifdef WINRT
149
110
#include < wrl/client.h>
@@ -228,6 +189,44 @@ std::wstring GetTempFileNameWinRT(std::wstring prefix)
228
189
# include < android/log.h>
229
190
#endif
230
191
192
+ #ifdef DECLARE_CV_CPUID_X86
193
+ DECLARE_CV_CPUID_X86
194
+ #endif
195
+ #ifndef CV_CPUID_X86
196
+ #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
197
+ #if _MSC_VER >= 1400 // MSVS 2005
198
+ #include < intrin.h> // __cpuidex()
199
+ #define CV_CPUID_X86 __cpuidex
200
+ #else
201
+ #error "Required MSVS 2005+"
202
+ #endif
203
+ #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
204
+ static void cv_cpuid (int * cpuid_data, int reg_eax, int reg_ecx)
205
+ {
206
+ int __eax = reg_eax, __ebx = 0 , __ecx = reg_ecx, __edx = 0 ;
207
+ // tested with available compilers (-fPIC -O2 -m32/-m64): https://godbolt.org/
208
+ #if !defined(__PIC__) \
209
+ || defined (__x86_64__) || __GNUC__ >= 5 \
210
+ || defined (__clang__) || defined (__INTEL_COMPILER)
211
+ __asm__ (" cpuid\n\t "
212
+ : " +a" (__eax), " =b" (__ebx), " +c" (__ecx), " =d" (__edx)
213
+ );
214
+ #elif defined(__i386__) // ebx may be reserved as the PIC register
215
+ __asm__ (" xchg{l}\t {%%}ebx, %1\n\t "
216
+ " cpuid\n\t "
217
+ " xchg{l}\t {%%}ebx, %1\n\t "
218
+ : " +a" (__eax), " =&r" (__ebx), " +c" (__ecx), " =d" (__edx)
219
+ );
220
+ #else
221
+ #error "Configuration error"
222
+ #endif
223
+ cpuid_data[0 ] = __eax; cpuid_data[1 ] = __ebx; cpuid_data[2 ] = __ecx; cpuid_data[3 ] = __edx;
224
+ }
225
+ #define CV_CPUID_X86 cv_cpuid
226
+ #endif
227
+ #endif
228
+
229
+
231
230
namespace cv
232
231
{
233
232
@@ -325,38 +324,12 @@ struct HWFeatures
325
324
326
325
initializeNames ();
327
326
327
+ #ifdef CV_CPUID_X86
328
328
int cpuid_data[4 ] = { 0 , 0 , 0 , 0 };
329
329
int cpuid_data_ex[4 ] = { 0 , 0 , 0 , 0 };
330
330
331
- #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
332
- #define OPENCV_HAVE_X86_CPUID 1
333
- __cpuid (cpuid_data, 1 );
334
- #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
335
- #define OPENCV_HAVE_X86_CPUID 1
336
- #ifdef __x86_64__
337
- asm __volatile__
338
- (
339
- " movl $1, %%eax\n\t "
340
- " cpuid\n\t "
341
- :[eax]" =a" (cpuid_data[0 ]),[ebx]" =b" (cpuid_data[1 ]),[ecx]" =c" (cpuid_data[2 ]),[edx]" =d" (cpuid_data[3 ])
342
- :
343
- : " cc"
344
- );
345
- #else
346
- asm volatile
347
- (
348
- " pushl %%ebx\n\t "
349
- " movl $1,%%eax\n\t "
350
- " cpuid\n\t "
351
- " popl %%ebx\n\t "
352
- : " =a" (cpuid_data[0 ]), " =c" (cpuid_data[2 ]), " =d" (cpuid_data[3 ])
353
- :
354
- : " cc"
355
- );
356
- #endif
357
- #endif
331
+ CV_CPUID_X86 (cpuid_data, 1 , 0 /* unused*/ );
358
332
359
- #ifdef OPENCV_HAVE_X86_CPUID
360
333
int x86_family = (cpuid_data[0 ] >> 8 ) & 15 ;
361
334
if ( x86_family >= 6 )
362
335
{
@@ -374,38 +347,8 @@ struct HWFeatures
374
347
375
348
// make the second call to the cpuid command in order to get
376
349
// information about extended features like AVX2
377
- #if defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
378
- #define OPENCV_HAVE_X86_CPUID_EX 1
379
- __cpuidex (cpuid_data_ex, 7 , 0 );
380
- #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
381
- #define OPENCV_HAVE_X86_CPUID_EX 1
382
- #ifdef __x86_64__
383
- asm __volatile__
384
- (
385
- " movl $7, %%eax\n\t "
386
- " movl $0, %%ecx\n\t "
387
- " cpuid\n\t "
388
- :[eax]" =a" (cpuid_data_ex[0 ]),[ebx]" =b" (cpuid_data_ex[1 ]),[ecx]" =c" (cpuid_data_ex[2 ]),[edx]" =d" (cpuid_data_ex[3 ])
389
- :
390
- : " cc"
391
- );
392
- #else
393
- asm volatile
394
- (
395
- " pushl %%ebx\n\t "
396
- " movl $7,%%eax\n\t "
397
- " movl $0,%%ecx\n\t "
398
- " cpuid\n\t "
399
- " movl %%ebx, %0\n\t "
400
- " popl %%ebx\n\t "
401
- : " =r" (cpuid_data_ex[1 ]), " =c" (cpuid_data_ex[2 ])
402
- :
403
- : " cc"
404
- );
405
- #endif
406
- #endif
350
+ CV_CPUID_X86 (cpuid_data_ex, 7 , 0 );
407
351
408
- #ifdef OPENCV_HAVE_X86_CPUID_EX
409
352
have[CV_CPU_AVX2] = (cpuid_data_ex[1 ] & (1 <<5 )) != 0 ;
410
353
411
354
have[CV_CPU_AVX_512F] = (cpuid_data_ex[1 ] & (1 <<16 )) != 0 ;
@@ -417,9 +360,6 @@ struct HWFeatures
417
360
have[CV_CPU_AVX_512BW] = (cpuid_data_ex[1 ] & (1 <<30 )) != 0 ;
418
361
have[CV_CPU_AVX_512VL] = (cpuid_data_ex[1 ] & (1 <<31 )) != 0 ;
419
362
have[CV_CPU_AVX_512VBMI] = (cpuid_data_ex[2 ] & (1 <<1 )) != 0 ;
420
- #else
421
- CV_UNUSED (cpuid_data_ex);
422
- #endif
423
363
424
364
bool have_AVX_OS_support = true ;
425
365
bool have_AVX512_OS_support = true ;
@@ -431,7 +371,7 @@ struct HWFeatures
431
371
#ifdef _XCR_XFEATURE_ENABLED_MASK // requires immintrin.h
432
372
xcr0 = (int )_xgetbv (_XCR_XFEATURE_ENABLED_MASK);
433
373
#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
434
- __asm__ (" xgetbv" : " =a" (xcr0) : " c" (0 ) : " %edx" );
374
+ __asm__ (" xgetbv\n\t " : " =a" (xcr0) : " c" (0 ) : " %edx" );
435
375
#endif
436
376
if ((xcr0 & 0x6 ) != 0x6 )
437
377
have_AVX_OS_support = false ; // YMM registers
@@ -464,10 +404,7 @@ struct HWFeatures
464
404
have[CV_CPU_AVX512_SKX] = have[CV_CPU_AVX_512F] & have[CV_CPU_AVX_512CD] & have[CV_CPU_AVX_512BW] & have[CV_CPU_AVX_512DQ] & have[CV_CPU_AVX_512VL];
465
405
}
466
406
}
467
- #else
468
- CV_UNUSED (cpuid_data);
469
- CV_UNUSED (cpuid_data_ex);
470
- #endif // OPENCV_HAVE_X86_CPUID
407
+ #endif // CV_CPUID_X86
471
408
472
409
#if defined __ANDROID__ || defined __linux__
473
410
#ifdef __aarch64__
0 commit comments