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:
Jakub Zawadzki 2014-06-09 23:18:24 +02:00 committed by Anders Broman
parent 8878d7778e
commit 4571283379
3 changed files with 31 additions and 15 deletions

View File

@ -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_)

View File

@ -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));
}

View File

@ -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