[pypy-commit] pypy default: Issue1068: in a pypy translated for x86-32 with SSE2, detect at run-time

arigo noreply at buildbot.pypy.org
Wed Feb 22 16:30:24 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r52759:4320ef8d1ab2
Date: 2012-02-22 16:29 +0100
http://bitbucket.org/pypy/pypy/changeset/4320ef8d1ab2/

Log:	Issue1068: in a pypy translated for x86-32 with SSE2, detect at run-
	time if we really have SSE2, and if not, abort with a nice error
	message.

diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -33,7 +33,7 @@
 from pypy.jit.backend.x86.support import values_array
 from pypy.jit.backend.x86 import support
 from pypy.rlib.debug import (debug_print, debug_start, debug_stop,
-                             have_debug_prints)
+                             have_debug_prints, fatalerror_notb)
 from pypy.rlib import rgc
 from pypy.rlib.clibffi import FFI_DEFAULT_ABI
 from pypy.jit.backend.x86.jump import remap_frame_layout
@@ -104,6 +104,7 @@
         self._debug = v
 
     def setup_once(self):
+        self._check_sse2()
         # the address of the function called by 'new'
         gc_ll_descr = self.cpu.gc_ll_descr
         gc_ll_descr.initialize()
@@ -161,6 +162,28 @@
                 debug_print(prefix + ':' + str(struct.i))
             debug_stop('jit-backend-counts')
 
+    _CHECK_SSE2_FUNC_PTR = lltype.Ptr(lltype.FuncType([], lltype.Signed))
+
+    def _check_sse2(self):
+        if WORD == 8:
+            return     # all x86-64 CPUs support SSE2
+        if not self.cpu.supports_floats:
+            return     # the CPU doesn't support float, so we don't need SSE2
+        #
+        from pypy.jit.backend.x86.detect_sse2 import INSNS
+        mc = codebuf.MachineCodeBlockWrapper()
+        for c in INSNS:
+            mc.writechar(c)
+        rawstart = mc.materialize(self.cpu.asmmemmgr, [])
+        fnptr = rffi.cast(self._CHECK_SSE2_FUNC_PTR, rawstart)
+        features = fnptr()
+        if bool(features & (1<<25)) and bool(features & (1<<26)):
+            return     # CPU supports SSE2
+        fatalerror_notb(
+          "This version of PyPy was compiled for a x86 CPU supporting SSE2.\n"
+          "Your CPU is too old.  Please translate a PyPy with the option:\n"
+          "--jit-backend=x86-without-sse2")
+
     def _build_float_constants(self):
         datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, [])
         float_constants = datablockwrapper.malloc_aligned(32, alignment=16)
diff --git a/pypy/jit/backend/x86/detect_sse2.py b/pypy/jit/backend/x86/detect_sse2.py
--- a/pypy/jit/backend/x86/detect_sse2.py
+++ b/pypy/jit/backend/x86/detect_sse2.py
@@ -1,17 +1,18 @@
 import autopath
-from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.rlib.rmmap import alloc, free
 
+INSNS = ("\xB8\x01\x00\x00\x00"     # MOV EAX, 1
+         "\x53"                     # PUSH EBX
+         "\x0F\xA2"                 # CPUID
+         "\x5B"                     # POP EBX
+         "\x92"                     # XCHG EAX, EDX
+         "\xC3")                    # RET
 
 def detect_sse2():
+    from pypy.rpython.lltypesystem import lltype, rffi
+    from pypy.rlib.rmmap import alloc, free
     data = alloc(4096)
     pos = 0
-    for c in ("\xB8\x01\x00\x00\x00"     # MOV EAX, 1
-              "\x53"                     # PUSH EBX
-              "\x0F\xA2"                 # CPUID
-              "\x5B"                     # POP EBX
-              "\x92"                     # XCHG EAX, EDX
-              "\xC3"):                   # RET
+    for c in INSNS:
         data[pos] = c
         pos += 1
     fnptr = rffi.cast(lltype.Ptr(lltype.FuncType([], lltype.Signed)), data)


More information about the pypy-commit mailing list