pypy /rpython/jit/backend/detect_cpu.py

Language Python Lines 164
MD5 Hash 0adffc942b33f3af59e6e6ee5b097cfa Estimated Cost $3,274 (why?)
Repository https://bitbucket.org/pypy/pypy/ View Raw File View Project SPDX
  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
159
160
161
162
163
"""
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_X86_64_SSE4 = 'x86-64-sse4'
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,
            'i86pc': MODEL_X86,    # Solaris/Intel
            'x86': MODEL_X86,      # Apple
            'Power Macintosh': MODEL_PPC_64,
            '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
            # has sse 2 at least
            if feature.detect_sse4_1():
                result = MODEL_X86_64_SSE4
        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_X86_64_SSE4:
        return "rpython.jit.backend.x86.runner", "CPU_X86_64_SSE4"
    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_X86_64_SSE4: ['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]
Back to Top