Armin Rigo avatar Armin Rigo committed 4320ef8

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.

Comments (0)

Files changed (2)

pypy/jit/backend/x86/assembler.py

 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
         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()
                 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)

pypy/jit/backend/x86/detect_sse2.py

 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)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.