[pypy-svn] r13388 - in pypy/dist/pypy/translator/llvm: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Jun 14 18:05:53 CEST 2005


Author: cfbolz
Date: Tue Jun 14 18:05:53 2005
New Revision: 13388

Modified:
   pypy/dist/pypy/translator/llvm/build_llvm_module.py
   pypy/dist/pypy/translator/llvm/llvmbc.py
   pypy/dist/pypy/translator/llvm/test/llvmsnippet.py
   pypy/dist/pypy/translator/llvm/test/test_genllvm.py
   pypy/dist/pypy/translator/llvm/typerepr.py
Log:
fix the handling of shifts.
there is a fundamental problem at the moment: since LLVM bytecode strives to
be platform independent, int is always 32 bit, genllvm has to use long on
64 bit machines.


Modified: pypy/dist/pypy/translator/llvm/build_llvm_module.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/build_llvm_module.py	(original)
+++ pypy/dist/pypy/translator/llvm/build_llvm_module.py	Tue Jun 14 18:05:53 2005
@@ -14,7 +14,7 @@
 from pypy.translator.tool.buildpyxmodule import make_c_from_pyxfile
 from pypy.translator.tool import stdoutcapture
 
-debug = False
+debug = True
 
 class CompileError(exceptions.Exception):
     pass

Modified: pypy/dist/pypy/translator/llvm/llvmbc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/llvmbc.py	(original)
+++ pypy/dist/pypy/translator/llvm/llvmbc.py	Tue Jun 14 18:05:53 2005
@@ -97,8 +97,7 @@
     #Shift instructions
     def shift_instruction(self, instr, l_target, l_a, l_b):
         self.phi_done = True
-        assert l_target.llvmtype() == l_a.llvmtype()
-        #assert l_b.llvmtype() == 'ubyte'   #or cast to ubyte or assuma nothing goes wrong
+        # XXX hack: just assume that l_b is of the appropriate type
         s = "%s = %s %s, ubyte %s" % (l_target.llvmname(), instr,
                                       l_a.typed_name(), l_b.llvmname())
         self.instructions.append(s)

Modified: pypy/dist/pypy/translator/llvm/test/llvmsnippet.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/llvmsnippet.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/llvmsnippet.py	Tue Jun 14 18:05:53 2005
@@ -62,6 +62,13 @@
 def return_none():
     pass
 
+def shiftleft(i, j):
+    return i << j
+
+def shiftright(i, j):
+    return i << j
+
+
 #float snippets
 
 def float_f1(x):

Modified: pypy/dist/pypy/translator/llvm/test/test_genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/test_genllvm.py	Tue Jun 14 18:05:53 2005
@@ -1,5 +1,7 @@
 from __future__ import division
 import autopath
+import sys
+
 import py
 
 from pypy.translator.translator import Translator
@@ -97,6 +99,14 @@
         f = compile_function(llvmsnippet.return_none, [])
         assert f() is None
 
+    def test_shift(self):
+        shl = compile_function(llvmsnippet.shiftleft, [int, int])
+        shr = compile_function(llvmsnippet.shiftright, [int, int])
+        for i in [1, 2, 3, 100000, 2000000, sys.maxint - 1]:
+            for j in [1, 2, 3, 100000, 2000000, sys.maxint - 1]:
+                assert shl(i, j) == i << j
+                assert shr(i, j) == i >> j
+
 class TestFloat(object):
     def setup_method(self, method):
         if not llvm_found:

Modified: pypy/dist/pypy/translator/llvm/typerepr.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/typerepr.py	(original)
+++ pypy/dist/pypy/translator/llvm/typerepr.py	Tue Jun 14 18:05:53 2005
@@ -85,8 +85,6 @@
         "int_mod": "rem",
         "int_xor": "xor",
         "int_and": "and",
-        "int_lshift": "shl",
-        "int_rshift": "shr",
         "int_or": "or",
         "int_eq": "seteq",
         "int_ne": "setne",
@@ -105,15 +103,51 @@
             assert len(args) == 2
             l_args = [self.gen.get_repr(arg) for arg in args]
             l_func.dependencies.update(l_args)
-            l_op = SignedTypeRepr.directly_supported_binary_ops[opname]
-            if l_op in ('shl', 'shr'):  #feel free to refactor this
-                lblock.shift_instruction(
-                    l_op, l_target,
-                    l_args[0], l_args[1])
-            else:
-                lblock.binary_instruction(
-                    l_op, l_target,
-                    l_args[0], l_args[1])
+            lblock.binary_instruction(
+                SignedTypeRepr.directly_supported_binary_ops[opname], l_target,
+                l_args[0], l_args[1])
+
+    def t_op_int_lshift(self, l_target, args, lblock, l_func):
+        # XXX hack: llvm only supports shifts by ubyte args
+        # so we have to jump through some loops
+        # someone on the LLVM list said this would change in the future
+        assert len(args) == 2
+        l_tmp1 = self.gen.get_local_tmp(None, l_func) #using only the name
+        l_tmp2 = self.gen.get_local_tmp(None, l_func)
+        l_tmp3 = self.gen.get_local_tmp(None, l_func)
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        lblock.instruction("%s = setge %s, %s" % (l_tmp1.llvmname(),
+                                                  l_args[1].typed_name(),
+                                                  8 * BYTES_IN_INT))
+        lblock.instruction("%s = cast int %s to ubyte" %
+                           (l_tmp2.llvmname(), l_args[1].llvmname()))
+        lblock.shift_instruction("shl", l_tmp3, l_args[0], l_tmp2)
+        lblock.instruction("%s = select bool %s, int 0, int %s" %
+                           (l_target.llvmname(), l_tmp1.llvmname(),
+                            l_tmp3.llvmname()))
+        lblock.phi_done = True
+
+    def t_op_int_rshift(self, l_target, args, lblock, l_func):
+        # XXX hack: llvm only supports shifts by ubyte args
+        # so we have to jump through some loops
+        # someone on the LLVM list said this would change in the future
+        assert len(args) == 2
+        l_tmp1 = self.gen.get_local_tmp(None, l_func) #using only the name
+        l_tmp2 = self.gen.get_local_tmp(None, l_func)
+        l_tmp3 = self.gen.get_local_tmp(None, l_func)
+        l_args = [self.gen.get_repr(arg) for arg in args]
+        l_func.dependencies.update(l_args)
+        lblock.instruction("%s = setge %s, %s" % (l_tmp1.llvmname(),
+                                                  l_args[1].typed_name(),
+                                                  8 * BYTES_IN_INT))
+        lblock.instruction("%s = cast int %s to ubyte" % (l_tmp2.llvmname(),
+                                                      l_args[1].llvmname()))
+        lblock.shift_instruction("shr", l_tmp3, l_args[0], l_tmp2)
+        lblock.instruction("%s = select bool %s, int 0, int %s" %
+                           (l_target.llvmname(), l_tmp1.llvmname(),
+                            l_tmp3.llvmname()))
+        lblock.phi_done = True
 
     def t_op_int_pos(self, l_target, args, lblock, l_func):
         pass
@@ -133,8 +167,9 @@
     def t_op_int_abs(self, l_target, args, lblock, l_func):
         l_arg = self.gen.get_repr(args[0])
         l_func.dependencies.add(l_arg)
-        lblock.instruction("%s = and int 2147483647, %s" % (l_target.llvmname(),
-                                                            l_arg.llvmname()))
+        lblock.instruction("%s = and int %s, %s" % (l_target.llvmname(),
+                                                    sys.maxint - 1,
+                                                    l_arg.llvmname()))
 
     def typename(self):
         return "int"



More information about the Pypy-commit mailing list