1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
"""
Processor auto-detection
"""
import sys, os
from rpython.rtyper.tool.rffi_platform import getdefined
from rpython.translator.platform import is_host_build
class ProcessorAutodetectError(Exception):
pass
MODEL_X86 = 'x86'
MODEL_X86_NO_SSE2 = 'x86-without-sse2'
MODEL_X86_64 = 'x86-64'
MODEL_ARM = 'arm'
MODEL_PPC_64 = 'ppc-64'
MODEL_S390_64 = 's390x'
# don't use '_' in the model strings; they are replaced by '-'
def detect_model_from_c_compiler():
# based on http://sourceforge.net/p/predef/wiki/Architectures/
# and http://msdn.microsoft.com/en-us/library/b0084kay.aspx
mapping = {
MODEL_X86_64: ['__amd64__', '__amd64', '__x86_64__', '__x86_64', '_M_X64', '_M_AMD64'],
MODEL_ARM: ['__arm__', '__thumb__','_M_ARM_EP'],
MODEL_X86: ['i386', '__i386', '__i386__', '__i686__','_M_IX86'],
MODEL_PPC_64: ['__powerpc64__'],
MODEL_S390_64:['__s390x__'],
}
for k, v in mapping.iteritems():
for macro in v:
if not getdefined(macro, ''):
continue
return k
raise ProcessorAutodetectError("Cannot detect processor using compiler macros")
def detect_model_from_host_platform():
mach = None
try:
import platform
mach = platform.machine()
except ImportError:
pass
if not mach:
platform = sys.platform.lower()
if platform.startswith('win'): # assume an Intel Windows
return MODEL_X86
# assume we have 'uname'
mach = os.popen('uname -m', 'r').read().strip()
if not mach:
raise ProcessorAutodetectError("cannot run 'uname -m'")
#
result ={'i386': MODEL_X86,
'i486': MODEL_X86,
'i586': MODEL_X86,
'i686': MODEL_X86,
'i686-AT386': MODEL_X86, # Hurd
'i86pc': MODEL_X86, # Solaris/Intel
'x86': MODEL_X86, # Apple
'Power Macintosh': MODEL_PPC_64,
'powerpc': MODEL_PPC_64, # freebsd
'ppc64': MODEL_PPC_64,
'ppc64le': MODEL_PPC_64,
'x86_64': MODEL_X86,
'amd64': MODEL_X86, # freebsd
'AMD64': MODEL_X86, # win64
'armv8l': MODEL_ARM, # 32-bit ARMv8
'armv7l': MODEL_ARM,
'armv6l': MODEL_ARM,
'arm': MODEL_ARM, # freebsd
's390x': MODEL_S390_64
}.get(mach)
if result is None:
raise ProcessorAutodetectError("unknown machine name %s" % mach)
#
if result.startswith('x86'):
from rpython.jit.backend.x86 import detect_feature as feature
if sys.maxint == 2**63-1:
result = MODEL_X86_64
else:
assert sys.maxint == 2**31-1
if feature.detect_sse2():
result = MODEL_X86
else:
result = MODEL_X86_NO_SSE2
if feature.detect_x32_mode():
raise ProcessorAutodetectError(
'JITting in x32 mode is not implemented')
#
if result.startswith('arm'):
from rpython.jit.backend.arm.detect import detect_float
if not detect_float():
raise ProcessorAutodetectError(
'the JIT-compiler requires a vfp unit')
#
return result
def autodetect():
if not is_host_build():
return detect_model_from_c_compiler()
else:
return detect_model_from_host_platform()
def getcpuclassname(backend_name="auto"):
if backend_name == "auto":
backend_name = autodetect()
backend_name = backend_name.replace('_', '-')
if backend_name == MODEL_X86:
return "rpython.jit.backend.x86.runner", "CPU"
elif backend_name == MODEL_X86_NO_SSE2:
return "rpython.jit.backend.x86.runner", "CPU386_NO_SSE2"
elif backend_name == MODEL_X86_64:
return "rpython.jit.backend.x86.runner", "CPU_X86_64"
elif backend_name == MODEL_ARM:
return "rpython.jit.backend.arm.runner", "CPU_ARM"
elif backend_name == MODEL_PPC_64:
return "rpython.jit.backend.ppc.runner", "PPC_CPU"
elif backend_name == MODEL_S390_64:
return "rpython.jit.backend.zarch.runner", "CPU_S390_64"
else:
raise ProcessorAutodetectError(
"we have no JIT backend for this cpu: '%s'" % backend_name)
def getcpuclass(backend_name="auto"):
modname, clsname = getcpuclassname(backend_name)
mod = __import__(modname, {}, {}, clsname)
return getattr(mod, clsname)
def getcpufeatures(backend_name="auto"):
if backend_name == "auto":
backend_name = autodetect()
return {
MODEL_X86: ['floats', 'singlefloats', 'longlong'],
MODEL_X86_NO_SSE2: ['longlong'],
MODEL_X86_64: ['floats', 'singlefloats'],
MODEL_ARM: ['floats', 'singlefloats', 'longlong'],
MODEL_PPC_64: ['floats'],
MODEL_S390_64: ['floats'],
}[backend_name]
if __name__ == '__main__':
if len(sys.argv) > 1:
name = sys.argv[1]
x = name
else:
name = 'auto'
x = autodetect()
x = (x, getcpuclassname(name), getcpufeatures(name))
print 'autodetect: ', x[0]
print 'getcpuclassname:', x[1]
print 'getcpufeatures: ', x[2]
|