diff options
author | Nick Foster <nick@ettus.com> | 2012-04-15 16:03:27 -0700 |
---|---|---|
committer | Johnathan Corgan <jcorgan@corganenterprises.com> | 2012-04-16 08:25:23 -0700 |
commit | c3f2c30a54c75575f464afdd7cd11a017fb07695 (patch) | |
tree | 6889936b1b11ae77fbdcdfb6da17cb7ea840422f /volk | |
parent | 04e2ebb979942cada74f10ea022342716c6851bf (diff) |
Volk: add support for checking AVX enable state of OS.
Some systems (notably Xen hypervisor) appear to use XSETBV to disable AVX. This causes SIGILL when running AVX instructions. This commit makes Volk check XCR0 on the AVX arch before proceeding.
Diffstat (limited to 'volk')
-rw-r--r-- | volk/gen/archs.xml | 2 | ||||
-rw-r--r-- | volk/gen/make_cpuid_c.py | 40 | ||||
-rw-r--r-- | volk/lib/gcc_x86_cpuid.h | 12 |
3 files changed, 42 insertions, 12 deletions
diff --git a/volk/gen/archs.xml b/volk/gen/archs.xml index effd90d331..53db3e577b 100644 --- a/volk/gen/archs.xml +++ b/volk/gen/archs.xml @@ -148,6 +148,8 @@ <reg>c</reg> <shift>28</shift> <flag>mavx</flag> + <check>xgetbv</check> + <checkval>7</checkval> <alignment>32</alignment> </arch> diff --git a/volk/gen/make_cpuid_c.py b/volk/gen/make_cpuid_c.py index 2be1123a80..4bd1ce5b1b 100644 --- a/volk/gen/make_cpuid_c.py +++ b/volk/gen/make_cpuid_c.py @@ -90,20 +90,26 @@ def make_cpuid_c(dom) : no_test = False; else: no_test = False; - arch = str(domarch.attributes["name"].value); - op = domarch.getElementsByTagName("op"); + arch = str(domarch.attributes["name"].value) + op = domarch.getElementsByTagName("op") if op: - op = str(op[0].firstChild.data); - reg = domarch.getElementsByTagName("reg"); + op = str(op[0].firstChild.data) + reg = domarch.getElementsByTagName("reg") if reg: - reg = str(reg[0].firstChild.data); - shift = domarch.getElementsByTagName("shift"); + reg = str(reg[0].firstChild.data) + shift = domarch.getElementsByTagName("shift") if shift: - shift = str(shift[0].firstChild.data); - val = domarch.getElementsByTagName("val"); + shift = str(shift[0].firstChild.data) + val = domarch.getElementsByTagName("val") if val: - val = str(val[0].firstChild.data); - + val = str(val[0].firstChild.data) + check = domarch.getElementsByTagName("check") + if check: + check = str(check[0].firstChild.data) + checkval = domarch.getElementsByTagName("checkval") + if checkval: + checkval = str(checkval[0].firstChild.data) + if no_test: tempstring = tempstring + """\ int i_can_has_%s () { @@ -121,13 +127,23 @@ int i_can_has_%s () { int i_can_has_%s () { #if defined(VOLK_CPU_x86) unsigned int e%sx = cpuid_e%sx (%s); - return ((e%sx >> %s) & 1) == %s; + int hwcap = (((e%sx >> %s) & 1) == %s); +""" % (arch, reg, reg, op, reg, shift, val) + + if check and checkval: + tempstring += """\ + if (hwcap == 0) return 0; + hwcap &= (%s() == %s); +""" % (check, checkval) + + tempstring += """\ + return hwcap; #else return 0; #endif } -""" % (arch, reg, reg, op, reg, shift, val) +""" elif op == "0x80000001": tempstring = tempstring + """\ diff --git a/volk/lib/gcc_x86_cpuid.h b/volk/lib/gcc_x86_cpuid.h index 2d0916fb36..95a6722f29 100644 --- a/volk/lib/gcc_x86_cpuid.h +++ b/volk/lib/gcc_x86_cpuid.h @@ -176,3 +176,15 @@ __get_cpuid (unsigned int __level, __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx); return 1; } + +/* Return Intel AVX extended CPU capabilities register. + * This function will bomb on non-AVX-capable machines, so + * check for AVX capability before executing. + */ +static __inline unsigned int +xgetbv(void) +{ + unsigned int index, __eax, __edx; + __asm__ ("xgetbv" : "=a"(__eax), "=d"(__edx) : "c" (index)); + return __eax; +} |