CPUID improvements
- Make ws_cpuid() return boolean when CPUID is support or no, this way it's easier for caller to determinate if it works (and can use cpuinfo[X] or no). - Add function ws_cpuid_sse42(), use it in ws_mempbrk() [cached] & version information. Change-Id: I4e77699f9f3d11bb9b2e8ea599e48d3c5ad84ed7 Reviewed-on: https://code.wireshark.org/review/2088 Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
8878d7778e
commit
4571283379
|
@ -629,7 +629,8 @@ static void get_cpu_info(GString *str _U_)
|
|||
|
||||
/* Calling __cpuid with 0x80000000 as the InfoType argument*/
|
||||
/* gets the number of valid extended IDs.*/
|
||||
ws_cpuid(CPUInfo, 0x80000000);
|
||||
if (!ws_cpuid(CPUInfo, 0x80000000))
|
||||
return;
|
||||
nExIds = CPUInfo[0];
|
||||
|
||||
if( nExIds<0x80000005)
|
||||
|
@ -646,6 +647,8 @@ static void get_cpu_info(GString *str _U_)
|
|||
|
||||
g_string_append_printf(str, "\n%s", CPUBrandString);
|
||||
|
||||
if (ws_cpuid_sse42())
|
||||
g_string_append(str, " (with SSE4.2)");
|
||||
}
|
||||
|
||||
static void get_mem_info(GString *str _U_)
|
||||
|
|
|
@ -23,20 +23,23 @@
|
|||
/*
|
||||
* Get CPU info on platforms where the cpuid instruction can be used skip 32 bit versions for GCC
|
||||
* http://www.intel.com/content/dam/www/public/us/en/documents/application-notes/processor-identification-cpuid-instruction-note.pdf
|
||||
* the ws_cpuid() routine will return 0 in CPUInfo[0] if cpuinfo isn't available.
|
||||
* the ws_cpuid() routine will return 0 if cpuinfo isn't available.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) /* MSVC */
|
||||
static void
|
||||
static int
|
||||
ws_cpuid(guint32 *CPUInfo, guint32 selector)
|
||||
{
|
||||
CPUInfo[0] = CPUInfo[1] = CPUInfo[2] = CPUInfo[3] = 0;
|
||||
__cpuid((int *) CPUInfo, selector);
|
||||
/* XXX, how to check if it's supported on MSVC? just in case clear all flags above */
|
||||
return 1;
|
||||
}
|
||||
|
||||
#elif defined(__GNUC__) /* GCC/clang */
|
||||
|
||||
#if defined(__x86_64__)
|
||||
static inline void
|
||||
static inline int
|
||||
ws_cpuid(guint32 *CPUInfo, int selector)
|
||||
{
|
||||
__asm__ __volatile__("cpuid"
|
||||
|
@ -45,22 +48,35 @@ ws_cpuid(guint32 *CPUInfo, int selector)
|
|||
"=c" (CPUInfo[2]),
|
||||
"=d" (CPUInfo[3])
|
||||
: "a"(selector));
|
||||
return 1;
|
||||
}
|
||||
#else /* (__i386__) */
|
||||
|
||||
static void
|
||||
static int
|
||||
ws_cpuid(guint32 *CPUInfo, int selector _U_)
|
||||
{
|
||||
/* TODO: need a test if older proccesors have the cpuid instruction */
|
||||
CPUInfo[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* Other compilers */
|
||||
|
||||
static void
|
||||
static int
|
||||
ws_cpuid(guint32 *CPUInfo, int selector _U_)
|
||||
{
|
||||
CPUInfo[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ws_cpuid_sse42(void)
|
||||
{
|
||||
guint32 CPUInfo[4];
|
||||
|
||||
if (!ws_cpuid(CPUInfo, 1))
|
||||
return 0;
|
||||
|
||||
/* in ECX bit 20 toggled on */
|
||||
return (CPUInfo[2] & (1 << 20));
|
||||
}
|
||||
|
|
|
@ -51,19 +51,16 @@ WS_DLL_PUBLIC const guint8 *
|
|||
ws_mempbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles)
|
||||
{
|
||||
#ifdef HAVE_SSE42
|
||||
guint32 CPUInfo[4];
|
||||
guint32 bSSE42Extensions;
|
||||
|
||||
static int have_sse42 = -1;
|
||||
#endif
|
||||
if (*needles == 0)
|
||||
return NULL;
|
||||
|
||||
#ifdef HAVE_SSE42
|
||||
ws_cpuid(CPUInfo, 1);
|
||||
if G_UNLIKELY(have_sse42 < 0)
|
||||
have_sse42 = ws_cpuid_sse42();
|
||||
|
||||
bSSE42Extensions = (CPUInfo[2] & 0x100000);
|
||||
|
||||
if (haystacklen >= 16 && bSSE42Extensions)
|
||||
if (haystacklen >= 16 && have_sse42)
|
||||
return _ws_mempbrk_sse42(haystack, haystacklen, needles);
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue