diff --git a/pycpuid/_pycpuid.c b/pycpuid/_pycpuid.c index 757d1b8..de522f0 100644 --- a/pycpuid/_pycpuid.c +++ b/pycpuid/_pycpuid.c @@ -47,11 +47,29 @@ static PyObject* _pycpuid_cpuid(PyObject* module, PyObject* args) return Py_BuildValue("IIII", cpuinfo[0], cpuinfo[1], cpuinfo[2], cpuinfo[3]); } - +static PyObject* _pycpuid_xgetbv(PyObject* module, PyObject* args) +{ + unsigned regs[2] = { 0, 0 }; + unsigned ecx; + if (!PyArg_ParseTuple(args, "I:ecx", &ecx)) + { + return 0; + } +#ifdef _MSC_VER + regs[0] = regs[1] = 0; /* XXX */ +#else + __asm__ __volatile__( + "xgetbv" + : "=a"(regs[0]), "=d"(regs[1]) + : "c"(ecx)); +#endif + return Py_BuildValue("II", regs[0], regs[1]); +} static PyMethodDef _pycpuid_methods[] = { { "cpuid", _pycpuid_cpuid, METH_VARARGS, "cpuid(eax) -> (eax, ebx, ecx, edx)"}, + { "xgetbv", _pycpuid_xgetbv, METH_VARARGS, "xgetbv(ecx) -> (eax, edx)"}, { 0, 0, 0, 0 }, }; diff --git a/pycpuid/pycpuid.py b/pycpuid/pycpuid.py index 46f6f03..9141b65 100644 --- a/pycpuid/pycpuid.py +++ b/pycpuid/pycpuid.py @@ -11,13 +11,24 @@ EXTENDED_OFFSET = 0x80000000 - def cpuid(infotype): ''' cpuid(infotype) -> (eax, ebx, ecx, edx) ''' return _pycpuid.cpuid(infotype) +def xgetbv(reg): + ''' + ''' + info = cpuid(1) + if (info[2] & (1 << 27)) != 0: + return _pycpuid.xgetbv(reg) + return 0 + +def xcr0(): + ''' + ''' + return xgetbv(0) def vendor(): a, b, c, d = cpuid(0) @@ -63,7 +74,11 @@ def features(): returns sequence of available features ''' info = cpuid(1) - return [key for key, reg, bit in _feat_table if info[reg] & (1 << bit)] + res = [key for key, reg, bit in _feat_table if info[reg] & (1 << bit)] + rxcr0 = xcr0() + if (rxcr0[0] & 0x5) == 0x5 and (info[2] & (1 << 28)) != 0: + res.append("AVX") + return res _feat_table = [ ("FPU", 3, 0),