[pypy-svn] r62297 - in pypy/branch/pyjitpl5/pypy/jit/backend/x86: . test

fijal at codespeak.net fijal at codespeak.net
Sun Mar 1 15:23:37 CET 2009


Author: fijal
Date: Sun Mar  1 15:23:36 2009
New Revision: 62297

Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/support.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_symbolic.py
   pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_slist.py
Log:
Progress with x86 backend. Support more or less all operations by now


Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py	Sun Mar  1 15:23:36 2009
@@ -182,6 +182,14 @@
             getattr(self.mc, asmop)(arglocs[0], arglocs[1])
         return genop_binary
 
+    def _binaryop_ovf(asmop, can_swap=False):
+        def genop_binary_ovf(self, op, arglocs, result_loc):
+            getattr(self.mc, asmop)(arglocs[0], arglocs[1])
+            # XXX think about CMOV instead of SETO, this would avoid
+            # a mess in detecting an exception
+            self.mc.SETO(heap8(self._exception_addr))
+        return genop_binary_ovf
+
     def _cmpop(cond, rev_cond):
         def genop_cmp(self, op, arglocs, result_loc):
             if isinstance(op.args[0], Const):
@@ -208,6 +216,15 @@
     genop_int_mul = _binaryop("IMUL", True)
     genop_int_and = _binaryop("AND", True)
 
+    genop_uint_add = genop_int_add
+    genop_uint_sub = genop_int_sub
+    genop_uint_mul = genop_int_mul
+    genop_uint_and = genop_int_and
+
+    genop_int_mul_ovf = _binaryop_ovf("IMUL", True)
+    genop_int_sub_ovf = _binaryop_ovf("SUB")
+    genop_int_add_ovf = _binaryop_ovf("ADD")
+
     genop_int_lt = _cmpop("L", "G")
     genop_int_le = _cmpop("LE", "GE")
     genop_int_eq = _cmpop("E", "NE")
@@ -215,6 +232,11 @@
     genop_int_gt = _cmpop("G", "L")
     genop_int_ge = _cmpop("GE", "LE")
 
+    genop_uint_gt = _cmpop("A", "B")
+    genop_uint_lt = _cmpop("B", "A")
+    genop_uint_le = _cmpop("BE", "AE")
+    genop_uint_ge = _cmpop("AE", "BE")
+
     # for now all chars are being considered ints, although we should make
     # a difference at some point
     genop_char_eq = genop_int_eq

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/regalloc.py	Sun Mar  1 15:23:36 2009
@@ -500,6 +500,13 @@
     consider_guard_true = consider_guard
     consider_guard_false = consider_guard
 
+    def consider_guard_nonvirtualized(self, op):
+        # XXX implement it
+        locs = self._locs_from_liveboxes(op)
+        self.eventually_free_var(op.args[0])
+        self.eventually_free_vars(op.liveboxes)
+        return []
+
     def consider_guard_no_exception(self, op):
         box = TempBox()
         loc, ops = self.force_allocate_reg(box, [])
@@ -585,11 +592,18 @@
     consider_int_mul = consider_binop
     consider_int_sub = consider_binop
     consider_int_and = consider_binop
-
+    consider_uint_add = consider_binop
+    consider_uint_mul = consider_binop
+    consider_uint_sub = consider_binop
+    consider_uint_and = consider_binop
+    
     def consider_binop_ovf(self, op):
-        xxx
+        return self.consider_binop(op)
 
     consider_int_mul_ovf = consider_binop_ovf
+    consider_int_sub_ovf = consider_binop_ovf
+    consider_int_add_ovf = consider_binop_ovf
+    # XXX ovf_neg op
 
     def consider_int_neg(self, op):
         res, ops = self.force_result_in_reg(op.results[0], op.args[0], [])
@@ -648,6 +662,7 @@
     consider_char_eq = consider_compop
     consider_int_ne = consider_compop
     consider_int_eq = consider_compop
+    consider_uint_gt = consider_compop
 
     def sync_var(self, v):
         ops = []
@@ -745,7 +760,7 @@
 
     def _unpack_fielddescr(self, fielddescr):
         if fielddescr < 0:
-            fielddescr = -fielddescr
+            fielddescr = ~fielddescr
         ofs_loc = imm(fielddescr & 0xffff)
         size_loc = imm(fielddescr >> 16)
         return ofs_loc, size_loc

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py	Sun Mar  1 15:23:36 2009
@@ -27,7 +27,6 @@
         self.stats = stats
         self.translate_support_code = translate_support_code
         if translate_support_code:
-            assert False, "need exception support"
             self.mixlevelann = MixLevelHelperAnnotator(rtyper)
         else:
             self.current_interpreter = LLInterpreter(self.rtyper)
@@ -50,6 +49,16 @@
         self.caught_exception = None
         if rtyper is not None: # for tests
             self.lltype2vtable = rtyper.lltype_to_vtable_mapping()
+            self._setup_ovf_error()
+
+    def _setup_ovf_error(self):
+        bk = self.rtyper.annotator.bookkeeper
+        clsdef = bk.getuniqueclassdef(OverflowError)
+        ovferror_repr = rclass.getclassrepr(self.rtyper, clsdef)
+        ll_inst = self.rtyper.exceptiondata.get_standard_ll_exc_instance(
+            self.rtyper, clsdef)
+        self._ovf_error_vtable = self.cast_ptr_to_int(ll_inst.typeptr)
+        self._ovf_error_inst = self.cast_ptr_to_int(ll_inst)
 
     def setup(self):
         self.assembler = Assembler386(self)
@@ -112,9 +121,17 @@
     def set_meta_interp(self, metainterp):
         self.metainterp = metainterp
 
+    def _get_overflow_error(self):
+        self.assembler._exception_data[1] = self._ovf_error_inst
+        return self._ovf_error_vtable
+
     def get_exception(self, frame):
         res = self.assembler._exception_data[0]
         self.assembler._exception_data[0] = 0
+        if res == 1:
+            # it's an overflow error, but we need to do all the dance
+            # to get a correct exception
+            return self._get_overflow_error()
         return res
 
     def get_exc_value(self, frame):
@@ -137,9 +154,9 @@
         if self.assembler._exception_data[0] != 0:
             TP = lltype.Ptr(rclass.OBJECT_VTABLE)
             TP_V = lltype.Ptr(rclass.OBJECT)
-            exc_t_a = self.cast_int_to_adr(self.assembler._exception_data[0])
+            exc_t_a = self.cast_int_to_adr(self.get_exception(None))
             exc_type = llmemory.cast_adr_to_ptr(exc_t_a, TP)
-            exc_v_a = self.cast_int_to_gcref(self.assembler._exception_data[1])
+            exc_v_a = self.get_exc_value(None)
             exc_val = lltype.cast_opaque_ptr(TP_V, exc_v_a)
             # clean up the exception
             self.assembler._exception_data[0] = 0

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/support.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/support.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/support.py	Sun Mar  1 15:23:36 2009
@@ -2,6 +2,7 @@
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib.objectmodel import we_are_translated
+from pypy.translator.c.test.test_genc import compile
 import ctypes
 
 GC_MALLOC = lltype.Ptr(lltype.FuncType([lltype.Signed], llmemory.Address))
@@ -27,3 +28,20 @@
         else:
             GC_malloc = boehmlib.GC_malloc
             return cast(GC_malloc, c_void_p).value
+
+def c_meta_interp(function, args, **kwds):
+    from pypy.translator.translator import TranslationContext
+    from pypy.jit.metainterp.warmspot import WarmRunnerDesc
+    from pypy.jit.backend.x86.runner import CPU386
+    
+    t = TranslationContext()
+    t.config.translation.gc = 'boehm'
+    t.buildannotator().build_types(function, [int] * len(args))
+    t.buildrtyper().specialize()
+    warmrunnerdesc = WarmRunnerDesc(t, translate_support_code=True,
+                                    CPUClass=CPU386,
+                                    **kwds)
+    warmrunnerdesc.state.set_param_threshold(3)          # for tests
+    warmrunnerdesc.state.set_param_trace_eagerness(2)    # for tests
+    warmrunnerdesc.finish()
+

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py	Sun Mar  1 15:23:36 2009
@@ -7,6 +7,7 @@
 from pypy.jit.backend.x86.regalloc import WORD
 from pypy.jit.backend.x86 import symbolic
 import ctypes
+import sys
 
 class FakeStats(object):
     pass
@@ -334,4 +335,31 @@
         assert c.value == 3
         
     def test_ovf_ops(self):
-        xxx
+        arg0 = BoxInt(12)
+        arg1 = BoxInt(13)
+        res = self.execute_operation('int_mul_ovf', [arg0, arg1], 'int')
+        assert res.value == 12*13
+        arg0 = BoxInt(sys.maxint/2)
+        arg1 = BoxInt(2222)
+        self.execute_operation('int_mul_ovf', [arg0, arg1], 'int')
+        assert self.cpu.assembler._exception_data[0] == 1
+        self.cpu.assembler._exception_data[0] = 0
+
+    def test_uint_ops(self):
+        from pypy.rlib.rarithmetic import r_uint, intmask
+
+        arg0 = BoxInt(intmask(r_uint(sys.maxint + 3)))
+        arg1 = BoxInt(intmask(r_uint(4)))
+        res = self.execute_operation('uint_add', [arg0, arg1], 'int')
+        assert res.value == intmask(r_uint(sys.maxint + 3) + r_uint(4))
+
+        arg0 = BoxInt(intmask(sys.maxint + 10))
+        arg1 = BoxInt(10)
+        res = self.execute_operation('uint_mul', [arg0, arg1], 'int')
+        assert res.value == intmask((sys.maxint + 10) * 10)
+
+        arg0 = BoxInt(intmask(r_uint(sys.maxint + 3)))
+        arg1 = BoxInt(intmask(r_uint(4)))
+
+        res = self.execute_operation('uint_gt', [arg0, arg1], 'int')
+        assert res.value == 1

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_symbolic.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_symbolic.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_symbolic.py	Sun Mar  1 15:23:36 2009
@@ -59,7 +59,8 @@
 def test_methods_of_cpu():
     cpu = CPU386(rtyper=None, stats=FakeStats())
     assert cpu.sizeof(S) == get_size(S)
-    assert cpu.offsetof(S, 'y') == get_field_token(S, 'y')[0]
+    assert cpu.fielddescrof(S, 'y') & 0xffff == get_field_token(S, 'y')[0]
+    assert cpu.fielddescrof(S, 'y') >> 16 == get_field_token(S, 'y')[1]
     A = lltype.GcArray(lltype.Char)
     assert cpu.itemoffsetof(A) == get_array_token(A)[0]
     assert cpu.arraylengthoffset(A) == get_array_token(A)[2]

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_slist.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_slist.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_zrpy_slist.py	Sun Mar  1 15:23:36 2009
@@ -1,73 +1,12 @@
 
 import py
-from codegen386.runner import CPU386
-from test.test_zrpy_basic import LLInterpJitMixin
-from pypy.jit.hintannotator.policy import StopAtXPolicy
-from test.test_slist import ListTests
-from pypy.rpython.lltypesystem import lltype
-from pyjitpl import build_meta_interp
-from rpyjitpl import set_ll_helper
-from pypy.translator.c.genc import CStandaloneBuilder as CBuilder
-from pypy.annotation.listdef import s_list_of_strings
-from pypy.annotation import model as annmodel
-from history import log
+from pypy.jit.metainterp.test.test_slist import ListTests
+from pypy.jit.backend.x86.support import c_meta_interp
 
-_cache = (None,)
-
-def rpython_ll_meta_interp(function, args, loops=None, **kwds):
-    global _cache
-    key = (function, tuple([lltype.typeOf(arg) for arg in args]))
-    lgt = len(args)
-
-    src = py.code.Source("""
-    def entry_point(argv):
-        args = (%s,)
-        res, num_loops = boot1(*args)
-        print "%%d,%%d" %% (res, num_loops)
-        return 0
-    """ % (", ".join(['int(argv[%d])' % (i + 1) for i in range(lgt)]),))
-
-    if key != _cache[0]:
-        _cache = (None,)
-        type_system = 'lltype'
-        kwds['translate_support_code'] = True
-        metainterp = build_meta_interp(function, args, type_system, **kwds)
-        boot_graph = set_ll_helper(metainterp,
-                                   [lltype.typeOf(arg) for arg in args])
-        boot1 = boot_graph.func
-        exec src.compile() in locals()
-        mixlevelann = metainterp.cpu.mixlevelann
-        entry_point_graph = mixlevelann.getgraph(entry_point,
-                                                 [s_list_of_strings],
-                                                 annmodel.SomeInteger())
-        metainterp.cpu.mixlevelann.finish()
-        del metainterp.cpu.mixlevelann
-        _cache = (key, metainterp, boot_graph)
-    
-    metainterp = _cache[1]
-    boot_graph = _cache[2]
-    t = metainterp.cpu.rtyper.annotator.translator
-    t.config.translation.gc = 'boehm'
-    cbuilder = CBuilder(t, entry_point, config=t.config)
-    cbuilder.generate_source()
-    exe_name = cbuilder.compile()
-    log('---------- Test starting ----------')
-    stdout = cbuilder.cmdexec(" ".join([str(arg) for arg in args]))
-    stdout.split(',')
-    res_s, loops_s = stdout.split(',')
-    res = int(res_s)
-    actual_loops = int(loops_s)
-    log('---------- Test done ----------')
-    if loops is not None:
-        actual_loops = results.item1
-        assert actual_loops == loops
-    return res
-
-
-class Jit386Mixin(LLInterpJitMixin):
+class Jit386Mixin(object):
     @staticmethod
     def meta_interp(fn, args, **kwds):
-        return rpython_ll_meta_interp(fn, args, CPUClass=CPU386, **kwds)
+        return c_meta_interp(fn, args, **kwds)
 
 class TestSList(Jit386Mixin, ListTests):
     # for the individual tests see



More information about the Pypy-commit mailing list