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