Skip to content
forked from BOINC/boinc

Commit

Permalink
Fixed avx detection on GCC windows compiles
Browse files Browse the repository at this point in the history
More windows library detection added to configure.ac
Additional cross compile fixes for libboinc and client.
  • Loading branch information
SETIguy committed Jun 20, 2014
1 parent 77dbcfd commit ce37b73
Show file tree
Hide file tree
Showing 7 changed files with 391 additions and 111 deletions.
14 changes: 7 additions & 7 deletions client/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,16 @@ switcher_LDADD = $(LIBBOINC)

## since we are using libtool we need some magic to get boinc and boinc_client
## to both be installed properly. The next two rules do that...
all-local: boinc
all-local: boinc$(EXEEXT)

boinc: boinc_client
rm -f boinc .libs/boinc
$(LN) boinc_client boinc
if test -f .libs/boinc_client ; then $(LN) .libs/boinc_client .libs/boinc ; fi
boinc$(EXEEXT): boinc_client$(EXEEXT)
rm -f boinc$(EXEEXT) .libs/boinc$(EXEEXT)
$(LN) boinc_client$(EXEEXT) boinc$(EXEEXT)
if test -f .libs/boinc_client$(EXEEXT) ; then $(LN) .libs/boinc_client$(EXEEXT) .libs/boinc$(EXEEXT) ; fi

install-exec-hook:
rm -f $(DESTDIR)$(exec_prefix)/bin/boinc
$(LN) $(DESTDIR)$(exec_prefix)/bin/boinc_client $(DESTDIR)$(exec_prefix)/bin/boinc
rm -f $(DESTDIR)$(exec_prefix)/bin/boinc$(EXEEXT)
$(LN) $(DESTDIR)$(exec_prefix)/bin/boinc_client$(EXEEXT) $(DESTDIR)$(exec_prefix)/bin/boinc$(EXEEXT)

## these source files need to be specified because no rule uses them.

Expand Down
121 changes: 94 additions & 27 deletions client/hostinfo_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#define snprintf _snprintf
#endif

#ifndef __CYGWIN__
#ifdef HAVE_INTRIN_H
#include <intrin.h>
#endif

Expand Down Expand Up @@ -140,17 +140,94 @@
#define PRODUCT_CLOUD_STORAGE_SERVER 0x0000006E
#endif

/* HAVE_DECL__XGETBV should be set by autoconf or in boinc_win.h */
#if !defined(HAVE_DECL__XGETBV) || !HAVE_DECL__XGETBV
#if HAVE_DECL_XGETBV
#define _xgetbv(x) xgetbv(x)
#elif HAVE_DECL___XGETBV
#define _xgetbv(x) __xgetbv(x)
#else
static unsigned long long _xgetbv(unsigned int index){
unsigned int A=0, D=0;

#ifdef __GNUC__
#ifdef ASM_SUPPORTS_XGETBV
__asm__ __volatile__("xgetbv" : "=a"(A), "=d"(D) : "c"(index));
#else
__asm__ __volatile__(".byte 0x0f, 0x01, 0xd0": "=a"(A), "=d"(D) : "c"(index));
#endif
#elif defined(_MSC_VER)
#ifdef _M_IX86
__asm {
mov ecx,index
__emit 00fh
__emit 001h
__emit 0d0h
mov D,edx
mov A,eax
}
#elif defined(_M_AMD64)
// damn Microsoft for not having inline assembler in 64-bit code
// so this is in an NASM compiled library
return asm_xgetbv(index);
#endif
#endif
return ((unsigned long long)D << 32) | A;
}
#endif
#endif

/* HAVE_DECL___CPUID should be set by autoconf or in boinc_win.h */
#if !defined(HAVE_DECL___CPUID) || !HAVE_DECL___CPUID
#if HAVE_DECL_CPUID
#define __cpuid(x,y) cpuid(x,y)
#elif HAVE_DECL__CPUID
#define __cpuid(x,y) _cpuid(x,y)
#else
static void __cpuid(unsigned int cpuinfo[4], unsigned int type) {
#ifdef __GNUC__
#ifdef ASM_SUPPORTS_CPUID
__asm__ __volatile__("cpuid"
: "=a" (cpuinfo[0]), "=b" (cpuinfo[1]),
"=c" (cpuinfo[2]), "=d" (cpuinfo[3])
: "a" (type));
#else
__asm__ __volatile__(".byte 0x0f, 0xa2"
: "=a" (cpuinfo[0]), "=b" (cpuinfo[1]),
"=c" (cpuinfo[2]), "=d" (cpuinfo[3])
: "a" (type));
#endif
#elif defined(_MSC_VER)
#ifdef _M_IX86
__asm {
mov eax,type
__emit 00fh
__emit 0a2h
mov cpuinfo[0],eax
mov cpuinfo[1],ebx
mov cpuinfo[2],ecx
mov cpuinfo[3],edx
}
#elif defined(_M_AMD64)
// damn Microsoft for not having inline assembler in 64-bit code
// so this is in an NASM compiled library
asm_cpuid(cpuinfo,type);
#endif
#endif
}
#endif
#endif

// Returns the number of seconds difference from UTC
//
int get_timezone(int& timezone) {
int get_timezone(int& tz) {
TIME_ZONE_INFORMATION tzi;
memset(&tzi, 0, sizeof(TIME_ZONE_INFORMATION));
DWORD result = GetTimeZoneInformation(&tzi);
if (result == TIME_ZONE_ID_DAYLIGHT) {
timezone = -(tzi.Bias + tzi.DaylightBias) * 60;
tz = -(tzi.Bias + tzi.DaylightBias) * 60;
} else {
timezone = -(tzi.Bias + tzi.StandardBias) * 60;
tz = -(tzi.Bias + tzi.StandardBias) * 60;
}
return 0;
}
Expand Down Expand Up @@ -648,13 +725,12 @@ int get_os_information(
//
int get_cpuid(unsigned int info_type, unsigned int& a, unsigned int& b, unsigned int& c, unsigned int& d) {

#ifdef _MSC_VER

// Microsoft compiler - use intrinsic
int retval = 1;
int CPUInfo[4] = {0,0,0,0};

unsigned int CPUInfo[4] = {0,0,0,0};
#ifdef _MSC_VER
__try {
#endif
__cpuid(CPUInfo, info_type);

a = CPUInfo[0];
Expand All @@ -663,19 +739,11 @@ int get_cpuid(unsigned int info_type, unsigned int& a, unsigned int& b, unsigned
d = CPUInfo[3];

retval = 0;
#ifdef _MSC_VER
}
__except (EXCEPTION_EXECUTE_HANDLER) {}
return retval;

#elif defined(__GNUC__)

// GCC compiler
__asm__ __volatile__ ("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (info_type));
return 0;

#else
return 1;
#endif
return retval;
}


Expand Down Expand Up @@ -785,7 +853,9 @@ int get_processor_cache(int& cache) {
return 0;
}


#ifndef _XCR_XFEATURE_ENABLED_MASK
#define _XCR_XFEATURE_ENABLED_MASK 0
#endif
// Returns true if the AVX instruction set is supported with the current
// combination of OS and CPU.
// see: http://insufficientlycomplicated.wordpress.com/2011/11/07/detecting-intel-advanced-vector-extensions-avx-in-visual-studio/
Expand All @@ -794,9 +864,7 @@ bool is_avx_supported() {

bool supported = false;

// If Visual Studio 2010 SP1 or later
#if (_MSC_FULL_VER >= 160040219)
// Checking for AVX requires 3 things:
// Checking for AVX on Windows requires 3 things:
// 1) CPUID indicates that the OS uses XSAVE and XRSTORE
// instructions (allowing saving YMM registers on context
// switch)
Expand All @@ -806,19 +874,18 @@ bool is_avx_supported() {
//
// Note that XGETBV is only available on 686 or later CPUs, so
// the instruction needs to be conditionally run.
int cpuInfo[4];
__cpuid(cpuInfo, 1);
unsigned int a,b,c,d;
get_cpuid(1, a, b, c, d);

bool osUsesXSAVE_XRSTORE = cpuInfo[2] & (1 << 27) || false;
bool cpuAVXSuport = cpuInfo[2] & (1 << 28) || false;
bool osUsesXSAVE_XRSTORE = c & (1 << 27) || false;
bool cpuAVXSuport = c & (1 << 28) || false;

if (osUsesXSAVE_XRSTORE && cpuAVXSuport)
{
// Check if the OS will save the YMM registers
unsigned long long xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
supported = (xcrFeatureMask & 0x6) || false;
}
#endif

return supported;
}
Expand Down
2 changes: 1 addition & 1 deletion client/time_stats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
#define CONNECTED_STATE_UNKNOWN 2

#ifndef SIM
#ifdef _WIN32
#if defined(_WIN32) && ( !defined(__MINGW32__) || defined(HAVE_LIBSENSAPI) )
#include <sensapi.h>

int get_connected_state() {
Expand Down
Loading

0 comments on commit ce37b73

Please sign in to comment.