summaryrefslogtreecommitdiff
path: root/volk
diff options
context:
space:
mode:
Diffstat (limited to 'volk')
-rw-r--r--volk/gen/archs.xml2
-rw-r--r--volk/gen/make_cpuid_c.py40
-rw-r--r--volk/lib/gcc_x86_cpuid.h12
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;
+}