[pypy-svn] r73889 - in pypy/branch/blackhole-improvement/pypy/jit/codewriter: . test

arigo at codespeak.net arigo at codespeak.net
Mon Apr 19 18:03:05 CEST 2010


Author: arigo
Date: Mon Apr 19 18:03:04 2010
New Revision: 73889

Modified:
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/blackhole.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_blackhole.py
Log:
Add a few more opcodes.


Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/blackhole.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/blackhole.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/blackhole.py	Mon Apr 19 18:03:04 2010
@@ -1,4 +1,5 @@
 from pypy.rlib.unroll import unrolling_iterable
+from pypy.rlib.rarithmetic import intmask, LONG_BIT
 from pypy.tool.sourcetools import func_with_new_name
 
 
@@ -14,6 +15,11 @@
 class LeaveFrame(Exception):
     pass
 
+def signedord(c):
+    value = ord(c)
+    value = intmask(value << (LONG_BIT-8)) >> (LONG_BIT-8)
+    return value
+
 
 class BlackholeInterpreter(object):
 
@@ -35,46 +41,65 @@
             all_funcs.append(self._get_method(name, argcodes))
         all_funcs = unrolling_iterable(enumerate(all_funcs))
         #
-        def dispatch(code, position):
-            opcode = ord(code[position])
-            position += 1
-            for i, func in all_funcs:
-                if opcode == i:
-                    return func(code, position)
-            else:
-                raise AssertionError("bad opcode")
-        self.dispatch = dispatch
+        def dispatch_loop(code, position):
+            while True:
+                opcode = ord(code[position])
+                position += 1
+                for i, func in all_funcs:
+                    if opcode == i:
+                        position = func(code, position)
+                        break
+                else:
+                    raise AssertionError("bad opcode")
+        self.dispatch_loop = dispatch_loop
 
     def _get_method(self, name, argcodes):
         #
         def handler(code, position):
             args = ()
-            for argcode, argtype in arg_codes_and_types:
-                if argcode == 'i':
-                    value = self.registers_i[ord(code[position])]
+            next_argcode = 0
+            for argtype in argtypes:
+                if argtype == 'i':
+                    # argcode can be 'i' or 'c'; 'c' stands for a single
+                    # signed byte that gives the value of a small constant.
+                    argcode = argcodes[next_argcode]
+                    next_argcode = next_argcode + 1
+                    if argcode == 'i':
+                        value = self.registers_i[ord(code[position])]
+                    elif argcode == 'c':
+                        value = signedord(code[position])
+                    else:
+                        raise AssertionError("bad argcode")
                     position += 1
-                    args += (value,)
-                    assert argtype == 'i'
+                elif argtype == 'L':
+                    # argcode should be 'L' too
+                    assert argcodes[next_argcode] == 'L'
+                    next_argcode = next_argcode + 1
+                    value = ord(code[position]) | (ord(code[position+1])<<8)
+                    position += 2
+                elif argtype == 'pc':
+                    value = position
                 else:
-                    raise AssertionError("bad arg code: %r" % (argcode,))
+                    raise AssertionError("bad argtype")
+                args += (value,)
             result = boundmethod(*args)
             if resulttype == 'i':
-                assert type(result) is int
+                # argcode should be 'i' too
+                assert argcodes[next_argcode] == 'i'
+                next_argcode = next_argcode + 1
                 self.registers_i[ord(code[position])] = result
                 position += 1
+            elif resulttype == 'L':
+                position = result
             else:
                 assert resulttype is None
                 assert result is None
+            assert next_argcode == len(argcodes)
             return position
         #
         boundmethod = getattr(self, 'opimpl_' + name)
-        argtypes = boundmethod.argtypes
+        argtypes = unrolling_iterable(boundmethod.argtypes)
         resulttype = boundmethod.resulttype
-        if resulttype is not None:
-            assert argcodes[-1] == 'i'
-            argcodes = argcodes[:-1]
-        assert len(argcodes) == len(argtypes)
-        arg_codes_and_types = unrolling_iterable(zip(argcodes, argtypes))
         handler = func_with_new_name(handler, 'handler_' + name)
         return handler
 
@@ -85,8 +110,7 @@
         code = jitcode.code
         constants = jitcode.constants
         try:
-            while True:
-                position = self.dispatch(code, position)
+            self.dispatch_loop(code, position)
         except LeaveFrame:
             pass
 
@@ -96,7 +120,22 @@
     def opimpl_int_add(self, a, b):
         return a + b
 
+    @arguments("i", "i", returns="i")
+    def opimpl_int_sub(self, a, b):
+        return a - b
+
     @arguments("i")
     def opimpl_int_return(self, a):
         self.result_i = a
         raise LeaveFrame
+
+    @arguments("L", "i", "i", "pc", returns="L")
+    def opimpl_goto_if_not_int_gt(self, target, a, b, pc):
+        if a > b:
+            return pc
+        else:
+            return target
+
+    @arguments("L", returns="L")
+    def opimpl_goto(self, target):
+        return target

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_blackhole.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_blackhole.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_blackhole.py	Mon Apr 19 18:03:04 2010
@@ -14,3 +14,34 @@
     blackholeinterp.setarg_i(1, 2)
     blackholeinterp.run(jitcode, 0)
     assert blackholeinterp.result_i == 42
+
+def test_simple_const():
+    jitcode = JitCode("test")
+    jitcode.setup("\x00\x30\x01\x02"
+                  "\x01\x02",
+                  [])
+    blackholeinterp = BlackholeInterpreter()
+    blackholeinterp.setup_insns({'int_sub/cii': 0,
+                                 'int_return/i': 1})
+    blackholeinterp.setarg_i(1, 6)
+    blackholeinterp.run(jitcode, 0)
+    assert blackholeinterp.result_i == 42
+
+def test_simple_loop():
+    jitcode = JitCode("test")
+    jitcode.setup("\x00\x10\x00\x16\x02"  # L1: goto_if_not_int_gt L2, %i0, 2
+                  "\x01\x17\x16\x17"      #     int_add %i1, %i0, %i1
+                  "\x02\x16\x01\x16"      #     int_sub %i0, $1, %i0
+                  "\x03\x00\x00"          #     goto L1
+                  "\x04\x17",             # L2: int_return %i1
+                  [])
+    blackholeinterp = BlackholeInterpreter()
+    blackholeinterp.setup_insns({'goto_if_not_int_gt/Lic': 0,
+                                 'int_add/iii': 1,
+                                 'int_sub/ici': 2,
+                                 'goto/L': 3,
+                                 'int_return/i': 4})
+    blackholeinterp.setarg_i(0x16, 6)
+    blackholeinterp.setarg_i(0x17, 100)
+    blackholeinterp.run(jitcode, 0)
+    assert blackholeinterp.result_i == 100+6+5+4+3



More information about the Pypy-commit mailing list