tahoma2d/toonz/sources/common/tsystem/cpuextensions.cpp

171 lines
3.3 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
#include "tsystem.h"
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-03-19 06:57:51 +13:00
#include <wtypes.h>
#include <winnt.h>
#include <emmintrin.h>
#endif
using namespace TSystem;
#ifdef x64
2016-06-15 18:43:10 +12:00
long TSystem::getCPUExtensions() {
return TSystem::CpuSupportsSse |
TSystem::CpuSupportsSse2; // TSystem::CPUExtensionsNone
2016-03-19 06:57:51 +13:00
}
#else
#ifndef _MSC_VER
2016-06-15 18:43:10 +12:00
long TSystem::getCPUExtensions() { return TSystem::CPUExtensionsNone; }
2016-03-19 06:57:51 +13:00
#else
2016-06-15 18:43:10 +12:00
namespace {
2016-03-19 06:57:51 +13:00
long CPUExtensionsAvailable = TSystem::CPUExtensionsNone;
2016-06-15 18:43:10 +12:00
bool CPUExtensionsEnabled = true;
bool FistTime = true;
2016-03-19 06:57:51 +13:00
2016-04-15 17:11:23 +12:00
//#ifdef _WIN32
2016-03-19 06:57:51 +13:00
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
long CPUCheckForSSESupport() {
__try {
// __asm andps xmm0,xmm0
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
__asm _emit 0x0f __asm _emit 0x54 __asm _emit 0xc0
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
} __except (EXCEPTION_EXECUTE_HANDLER) {
if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
CPUExtensionsAvailable &= ~(CpuSupportsSse | CpuSupportsSse2);
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
return CPUExtensionsAvailable;
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
long __declspec(naked) CPUCheckForExtensions() {
__asm {
2016-03-19 06:57:51 +13:00
push ebp
push edi
push esi
push ebx
2016-07-05 16:54:52 +12:00
xor ebp,ebp ;cpu flags - if we do not have CPUID, we probably
;will not want to try FPU optimizations.
2016-03-19 06:57:51 +13:00
;check for CPUID.
pushfd ;flags -> EAX
pop eax
or eax,00200000h ;set the ID bit
push eax ;EAX -> flags
popfd
pushfd ;flags -> EAX
pop eax
and eax,00200000h ;ID bit set?
jz done ;nope...
;CPUID exists, check for features register.
mov ebp,00000003h
xor eax,eax
cpuid
or eax,eax
jz done ;no features register?!?
;features register exists, look for MMX, SSE, SSE2.
mov eax,1
cpuid
mov ebx,edx
and ebx,00800000h ;MMX is bit 23
shr ebx,21
or ebp,ebx ;set bit 2 if MMX exists
mov ebx,edx
and edx,02000000h ;SSE is bit 25
shr edx,25
neg edx
and edx,00000018h ;set bits 3 and 4 if SSE exists
or ebp,edx
and ebx,04000000h ;SSE2 is bit 26
shr ebx,21
and ebx,00000020h ;set bit 5
or ebp,ebx
;check for vendor feature register (K6/Athlon).
mov eax,80000000h
cpuid
mov ecx,80000001h
cmp eax,ecx
jb done
;vendor feature register exists, look for 3DNow! and Athlon extensions
mov eax,ecx
cpuid
mov eax,edx
and edx,80000000h ;3DNow! is bit 31
shr edx,25
or ebp,edx ;set bit 6
mov edx,eax
and eax,40000000h ;3DNow!2 is bit 30
shr eax,23
or ebp,eax ;set bit 7
and edx,00400000h ;AMD MMX extensions (integer SSE) is bit 22
shr edx,19
or ebp,edx
done:
mov eax,ebp
mov CPUExtensionsAvailable, ebp
;Full SSE and SSE-2 require OS support for the xmm* registers.
test eax,00000030h
jz nocheck
call CPUCheckForSSESupport
nocheck:
pop ebx
pop esi
pop edi
pop ebp
ret
}
}
//#endif
//#endif
2016-06-15 18:43:10 +12:00
} // anonymous namespace
2016-03-19 06:57:51 +13:00
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
long TSystem::getCPUExtensions() {
if (FistTime) {
CPUCheckForExtensions();
FistTime = false;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (CPUExtensionsEnabled)
return CPUExtensionsAvailable;
else
return TSystem::CPUExtensionsNone;
2016-03-19 06:57:51 +13:00
}
#endif
#endif
//------------------------------------------------------------------------------
/*
void TSystem::enableCPUExtensions(bool on)
{
CPUExtensionsEnabled = on;
}
*/