Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect AVX presence using algorithm specified in the Intel' SDM Volume 1 section 14.3 "DETECTION OF AVX INSTRUCTIONS". #3

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion pycpuid/_pycpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
};

Expand Down
19 changes: 17 additions & 2 deletions pycpuid/pycpuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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),
Expand Down