[pypy-commit] pypy s390x-backend: logical division for ufloor_div, added some methods for to get two registers next to each other from the reg alloc (not yet complete)

plan_rich noreply at buildbot.pypy.org
Wed Nov 11 09:46:05 EST 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80633:6db64d28c955
Date: 2015-11-11 13:08 +0100
http://bitbucket.org/pypy/pypy/changeset/6db64d28c955/

Log:	logical division for ufloor_div, added some methods for to get two
	registers next to each other from the reg alloc (not yet complete)
	started to write a test to explicitly stress division and
	multiplication

diff --git a/rpython/jit/backend/zarch/helper/regalloc.py b/rpython/jit/backend/zarch/helper/regalloc.py
--- a/rpython/jit/backend/zarch/helper/regalloc.py
+++ b/rpython/jit/backend/zarch/helper/regalloc.py
@@ -41,21 +41,20 @@
 def prepare_int_div(self, op):
     a0 = op.getarg(0)
     a1 = op.getarg(1)
-    l0,lr = self.ensure_even_odd_pair(a0)
+    lr,lq = self.ensure_even_odd_pair(a0)
     l1 = self.ensure_reg(a1)
-    xxx
-    self.force_result_in_reg(op, a0)
+    self.force_result_in_odd_reg(op, a0)
     self.free_op_vars()
-    return [l0, l1]
+    return [lr, lq, l1]
 
 def prepare_int_mod(self, op):
     a0 = op.getarg(0)
     a1 = op.getarg(1)
-    l0,lr = self.ensure_even_odd_pair(a0)
+    lr,lq = self.ensure_even_odd_pair(a0)
     l1 = self.ensure_reg(a1)
-    self.force_arg_to_(op, a0)
+    self.force_result_in_even_reg(op, a0)
     self.free_op_vars()
-    return [l0, l1]
+    return [lr, lq, l1]
 
 
 def prepare_int_sub(self, op):
diff --git a/rpython/jit/backend/zarch/instructions.py b/rpython/jit/backend/zarch/instructions.py
--- a/rpython/jit/backend/zarch/instructions.py
+++ b/rpython/jit/backend/zarch/instructions.py
@@ -27,6 +27,9 @@
     # div/mod
     'DSGR':    ('rre',   ['\xB9','\x0D'], 'eo,r'),
     'DSG':     ('rxy',   ['\xE3','\x0D'], 'eo,bidl'),
+    'DLGR':    ('rre',   ['\xB9','\x97'], 'eo,r'),
+    'DLG':     ('rxy',   ['\xE3','\x87'], 'eo,bidl'),
+
     # there is no immidiate divide
 
 
diff --git a/rpython/jit/backend/zarch/locations.py b/rpython/jit/backend/zarch/locations.py
--- a/rpython/jit/backend/zarch/locations.py
+++ b/rpython/jit/backend/zarch/locations.py
@@ -48,6 +48,12 @@
     def is_reg(self):
         return True
 
+    def is_even(self):
+        return self.value % 2 == 0
+
+    def is_odd(self):
+        return self.value % 2 == 1
+
     def as_key(self):       # 0 <= as_key <= 15
         return self.value
 
diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py
--- a/rpython/jit/backend/zarch/opassembler.py
+++ b/rpython/jit/backend/zarch/opassembler.py
@@ -10,7 +10,7 @@
     def emit_int_add(self, op, arglocs, regalloc):
         l0, l1 = arglocs
         if l1.is_imm():
-            self.mc.AGHI(l0, l1)
+            self.mc.AGFI(l0, l1)
         elif l1.is_in_pool():
             self.mc.AG(l0, l1)
         else:
@@ -19,11 +19,37 @@
     def emit_int_mul(self, op, arglocs, regalloc):
         l0, l1 = arglocs
         if l1.is_imm():
-            self.mc.AGHI(l0, l1)
-        elif l1.is_in_pool():
-            self.mc.AG(l0, l1)
+            self.mc.MSFI(l0, l1)
+        if l1.is_in_pool():
+            self.mc.MSG(l0, l1)
         else:
-            self.mc.AGR(l0, l1)
+            self.mc.MSGR(l0, l1)
+
+    def emit_int_floordiv(self, op, arglocs, regalloc):
+        lr, lq, l1 = arglocs # lr == remainer, lq == quotient
+        # when entering the function lr contains the dividend
+        # after this operation either lr or lq is used further
+        assert not l1.is_imm() , "imm divider not supported"
+        # remainer is always a even register r0, r2, ... , r14
+        assert lr.is_even()
+        assert lq.is_odd()
+        if l1.is_in_pool():
+            self.mc.DSG(lr, l1)
+        else:
+            self.mc.DSGR(lr, l1)
+
+    def emit_int_ufloordiv(self, op, arglocs, regalloc):
+        lr, lq, l1 = arglocs # lr == remainer, lq == quotient
+        # when entering the function lr contains the dividend
+        # after this operation either lr or lq is used further
+        assert not l1.is_imm() , "imm divider not supported"
+        # remainer is always a even register r0, r2, ... , r14
+        assert lr.is_even()
+        assert lq.is_odd()
+        if l1.is_in_pool():
+            self.mc.DLG(lr, l1)
+        else:
+            self.mc.DLGR(lr, l1)
 
     def emit_int_sub(self, op, arglocs, regalloc):
         l0, l1 = arglocs
diff --git a/rpython/jit/backend/zarch/regalloc.py b/rpython/jit/backend/zarch/regalloc.py
--- a/rpython/jit/backend/zarch/regalloc.py
+++ b/rpython/jit/backend/zarch/regalloc.py
@@ -135,6 +135,30 @@
         self.temp_boxes.append(box)
         return reg
 
+    def ensure_even_odd_pair(self, var):
+        self.rm.ensure__check_type(var)
+        prev_loc = self.loc(var, must_exist=True)
+        if prev_loc is self.frame_reg:
+            return prev_loc
+        if not prev_loc.is_even():
+            # we need to move it ...
+            pass
+        loc = self.force_allocate_reg(v, forbidden_vars, selected_reg,
+                                      need_lower_byte=need_lower_byte)
+        if prev_loc is not loc:
+            self.assembler.regalloc_mov(prev_loc, loc)
+        return loc
+
+
+    def force_result_in_even_reg(self, result_v, loc, forbidden_vars=[]):
+        xxx
+        pass
+
+    def force_result_in_odd_reg(self, result_v, loc, forbidden_vars=[]):
+        xxx
+        pass
+
+
 
 class ZARCHFrameManager(FrameManager):
     def __init__(self, base_ofs):
diff --git a/rpython/jit/backend/zarch/test/test_runner.py b/rpython/jit/backend/zarch/test/test_runner.py
--- a/rpython/jit/backend/zarch/test/test_runner.py
+++ b/rpython/jit/backend/zarch/test/test_runner.py
@@ -23,3 +23,20 @@
         cpu = CPU_S390_64(rtyper=None, stats=FakeStats())
         cpu.setup_once()
         return cpu
+
+    @py.test.parametrize('input,opcode,result',
+        [30,'i1 = int_mul(i0, 2)',60]
+    )
+    def test_int_arithmetic_and_logic(self, input, opcode, result):
+        loop = parse("""
+        [i0]
+        {opcode}
+        finish(i1, descr=faildescr)
+        """.format(opcode=opcode),namespace={"faildescr": BasicFinalDescr(1)})
+        looptoken = JitCellToken()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        deadframe = self.cpu.execute_token(looptoken, input)
+        fail = self.cpu.get_latest_descr(deadframe)
+        res = self.cpu.get_int_value(deadframe, 0)
+        assert res == result
+        assert fail.identifier == 1 


More information about the pypy-commit mailing list