/********************************************************************************
* *
* C P U I D S u p p o r t *
* *
*********************************************************************************
* Copyright (C) 1998,2021 by Jeroen van der Zijp. All Rights Reserved. *
*********************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see *
********************************************************************************/
#include "xincs.h"
#include "fxver.h"
#include "fxdefs.h"
#include "fxmath.h"
#include "fxcpuid.h"
/*
Notes:
- Obtain processor capabilities at runtime.
- Utility API's to discover CPU vendor and CPU instruction-set extensions.
- Only supported on x86 and x86-64 cpus.
- Consult AMD and Intel Programming Manuals for details.
*/
using namespace FX;
/*******************************************************************************/
namespace FX {
// Return number of levels of CPUID feature-requests supported
FXuint fxCPUCaps(FXuint level){
#if defined(WIN32) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_VER >= 1500)
FXint features[4];
level&=0x80000000;
__cpuid(features,level);
return features[0]+1;
#elif ((defined(__GNUC__) || defined(__INTEL_COMPILER)) && defined(__i686__))
FXuint eax,ebx,ecx,edx;
level&=0x80000000;
__asm__ __volatile__("xchgl %%ebx, %1 \n\t" \
"cpuid \n\t" \
"xchgl %%ebx, %1 \n\t" : "=a"(eax), "=r"(ebx), "=c"(ecx), "=d"(edx) : "0" (level) : "cc");
return eax+1;
#elif ((defined(__GNUC__) || defined(__INTEL_COMPILER)) && defined(__x86_64__))
FXuint eax,ebx,ecx,edx;
level&=0x80000000;
__asm__ __volatile__("cpuid \n\t" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "0" (level) : "cc");
return eax+1;
#endif
return 0;
}
// Get CPU info
FXbool fxCPUGetCaps(FXuint level,FXuint features[]){
#if defined(WIN32) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_VER >= 1500)
if(level= 1500)
if(level