diff options
-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 effd90d33..53db3e577 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 2be1123a8..4bd1ce5b1 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 2d0916fb3..95a6722f2 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; +} |