diff options
author | David Cournapeau <cournape@gmail.com> | 2009-03-28 08:38:08 +0000 |
---|---|---|
committer | David Cournapeau <cournape@gmail.com> | 2009-03-28 08:38:08 +0000 |
commit | 8774fa4996ea57d6b81b7fc30204a0ddd6dd7782 (patch) | |
tree | 665ae2a0e345a623d5a3fe3e7d9c0f45bc71a07e | |
parent | f29ca7fe5bc789bce868f26f53f1ef037c360a1c (diff) | |
download | numpy-8774fa4996ea57d6b81b7fc30204a0ddd6dd7782.tar.gz |
Add the x86analysis.py script to check instructions set in win binaries.
-rw-r--r-- | tools/win32build/misc/x86analysis.py | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/tools/win32build/misc/x86analysis.py b/tools/win32build/misc/x86analysis.py new file mode 100644 index 000000000..552b086d5 --- /dev/null +++ b/tools/win32build/misc/x86analysis.py @@ -0,0 +1,161 @@ +#! /usr/bin/env python +# Last Change: Sat Mar 28 02:00 AM 2009 J + +# Try to identify instruction set used in binary (x86 only). This works by +# checking the assembly for instructions specific to sse, etc... Obviously, +# this won't work all the times (for example, if some instructions are used +# only after proper detection of the running CPU, this will give false alarm). + +import sys +import re +import os +import subprocess +import popen2 +import optparse + +I486_SET = ["cmpxchg", "xadd", "bswap", "invd", "wbinvd", "invlpg"] +I586_SET = ["rdmsr", "wrmsr", "rdtsc", "cmpxch8B", "rsm"] +PPRO_SET = ["cmovcc", "fcmovcc", "fcomi", "fcomip", "fucomi", "fucomip", "rdpmc", "ud2"] +MMX_SET = ["emms", "movd", "movq", "packsswb", "packssdw", "packuswb", "paddb", + "paddw", "paddd", "paddsb", "paddsw", "paddusb", "paddusw", "pand", + "pandn", "pcmpeqb", "pcmpeqw", "pcmpeqd", "pcmpgtb", "pcmpgtw", + "pcmpgtd", "pmaddwd", "pmulhw", "pmullw", "por", "psllw", "pslld", + "psllq", "psraw", "psrad", "psrlw", "psrld", "psrlq", "psubb", "psubw", + "psubd", "psubsb", "psubsw", "psubusb", "psubusw", "punpckhbw", + "punpckhwd", "punpckhdq", "punpcklbw", "punpcklwd", "punpckldq", + "pxor"] +SSE_SET = ["addps", "addss", "andnps", "andps", "cmpps", "cmpss", "comiss", + "cvtpi2ps", "cvtps2pi", "cvtsi2ss", "cvtss2si", "cvttps2pi", + "cvttss2si", "divps", "divss", "fxrstor", "fxsave", "ldmxcsr", "maxps", + "maxss", "minps", "minss", "movaps", "movhlps", "movhps", "movlhps", + "movlps", "movmskps", "movss", "movups", "mulps", "mulss", "orps", + "pavgb", "pavgw", "psadbw", "rcpps", "rcpss", "rsqrtps", "rsqrtss", + "shufps", "sqrtps", "sqrtss", "stmxcsr", "subps", "subss", "ucomiss", + "unpckhps", "unpcklps", "xorps", "pextrw", "pinsrw", "pmaxsw", + "pmaxub", "pminsw", "pminub", "pmovmskb", "pmulhuw", "pshufw", + "maskmovq", "movntps", "movntq", "prefetch", "sfence"] + +SSE2_SET = ["addpd", "addsd", "andnpd", "andpd", "clflush", "cmppd", "cmpsd", + "comisd", "cvtdq2pd", "cvtdq2ps", "cvtpd2pi", "cvtpd2pq", "cvtpd2ps", + "cvtpi2pd", "cvtps2dq", "cvtps2pd", "cvtsd2si", "cvtsd2ss", "cvtsi2sd", + "cvtss2sd", "cvttpd2pi", "cvttpd2dq", "cvttps2dq", "cvttsd2si", + "divpd", "divsd", "lfence", "maskmovdqu", "maxpd", "maxsd", "mfence", + "minpd", "minsd", "movapd", "movd", "movdq2q", "movdqa", "movdqu", + "movhpd", "movlpd", "movmskpd", "movntdq", "movnti", "movntpd", "movq", + "movq2dq", "movsd", "movupd", "mulpd", "mulsd", "orpd", "packsswb", + "packssdw", "packuswb", "paddb", "paddw", "paddd", "paddq", "paddq", + "paddsb", "paddsw", "paddusb", "paddusw", "pand", "pandn", "pause", + "pavgb", "pavgw", "pcmpeqb", "pcmpeqw", "pcmpeqd", "pcmpgtb", + "pcmpgtw", "pcmpgtd", "pextrw", "pinsrw", "pmaddwd", "pmaxsw", + "pmaxub", "pminsw", "pminub", "pmovmskb", "pmulhw", "pmulhuw", + "pmullw", "pmuludq", "pmuludq", "por", "psadbw", "pshufd", "pshufhw", + "pshuflw", "pslldq", "psllw", "pslld", "psllq", "psraw", "psrad", + "psrldq", "psrlw", "psrld", "psrlq", "psubb", "psubw", "psubd", + "psubq", "psubq", "psubsb", "psubsw", "psubusb", "psubusw", "psubsb", + "punpckhbw", "punpckhwd", "punpckhdq", "punpckhqdq", "punpcklbw", + "punpcklwd", "punpckldq", "punpcklqdq", "pxor", "shufpd", "sqrtpd", + "sqrtsd", "subpd", "subsd", "ucomisd", "unpckhpd", "unpcklpd", "xorpd"] + +SSE3_SET = [ "addsubpd", "addsubps", "haddpd", "haddps", "hsubpd", "hsubps", + "lddqu", "movddup", "movshdup", "movsldup", "fisttp"] + +def get_vendor_string(): + """Return the vendor string reading cpuinfo.""" + try: + a = open('/proc/cpuinfo').readlines() + b = re.compile('^vendor_id.*') + c = [i for i in a if b.match(i)] + except IOError: + raise ValueError("Could not read cpuinfo") + + + int = re.compile("GenuineIntel") + amd = re.compile("AuthenticAMD") + cyr = re.compile("CyrixInstead") + tra = re.compile("GenuineTMx86") + if int.search(c[0]): + return "intel" + elif amd.search(c[0]): + return "amd" + elif cyr.search(c[0]): + return "cyrix" + elif tra.search(c[0]): + return "tra" + else: + raise ValueError("Unknown vendor") + +def disassemble(filename): + """From a filename, returns a list of all asm instructions.""" + cmd = "i586-mingw32msvc-objdump -d %s " % filename + o, i = popen2.popen2(cmd) + def floupi(line): + line1 = line.split('\t') + if len(line1) > 2: + line2 = line1[2] + else: + line2 = line1[0] + line3 = line2.split(' ') + if len(line3) > 1: + inst = line3[0] + else: + inst = line3[0] + return inst + inst = [floupi(i) for i in o.readlines()] + return inst + +def has_set(seq, asm_set): + a = dict([(i, 0) for i in asm_set]) + for i in asm_set: + a[i] = seq.count(i) + return a + +def has_sse(seq): + return has_set(seq, SSE_SET) + +def has_sse2(seq): + return has_set(seq, SSE2_SET) + +def has_sse3(seq): + return has_set(seq, SSE3_SET) + +def has_mmx(seq): + return has_set(seq, MMX_SET) + +def has_ppro(seq): + return has_set(seq, PPRO_SET) + +def cntset(seq): + cnt = 0 + for i in seq.values(): + cnt += i + return cnt + +def main(): + #parser = optparse.OptionParser() + #parser.add_option("-f", "--filename + args = sys.argv[1:] + filename = args[0] + analyse(filename) + +def analyse(filename): + print get_vendor_string() + print "Getting instructions..." + inst = disassemble(filename) + print "Counting instructions..." + sse = has_sse(inst) + sse2 = has_sse2(inst) + sse3 = has_sse3(inst) + #mmx = has_mmx(inst) + #ppro = has_ppro(inst) + #print sse + #print sse2 + #print sse3 + print "SSE3 inst %d" % cntset(sse3) + print "SSE2 inst %d" % cntset(sse2) + print "SSE inst %d" % cntset(sse) + print "Analysed %d instructions" % len(inst) + +if __name__ == '__main__': + main() + #filename = "/usr/lib/sse2/libatlas.a" + ##filename = "/usr/lib/sse2/libcblas.a" |