Author: Richard Plangger <planri...@gmail.com>
Branch: s390x-backend
Changeset: r80634:5a93f832d42a
Date: 2015-11-11 15:46 +0100
http://bitbucket.org/pypy/pypy/changeset/5a93f832d42a/

Log:    implemented int_mul, int_floordiv, uint_floordiv and int_mod added
        test case to ensure the correct register allocation (e.g. division
        takes a pair of even odd registers) not yet all cases covered for
        pair allocation

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,18 +41,18 @@
 def prepare_int_div(self, op):
     a0 = op.getarg(0)
     a1 = op.getarg(1)
-    lr,lq = self.ensure_even_odd_pair(a0)
+    lr,lq = self.rm.ensure_even_odd_pair(a0, bind_first=False)
     l1 = self.ensure_reg(a1)
-    self.force_result_in_odd_reg(op, a0)
+    self.rm.force_result_in_reg(op, a0)
     self.free_op_vars()
     return [lr, lq, l1]
 
 def prepare_int_mod(self, op):
     a0 = op.getarg(0)
     a1 = op.getarg(1)
-    lr,lq = self.ensure_even_odd_pair(a0)
+    lr,lq = self.rm.ensure_even_odd_pair(a0, bind_first=True)
     l1 = self.ensure_reg(a1)
-    self.force_result_in_even_reg(op, a0)
+    self.rm.force_result_in_reg(op, a0)
     self.free_op_vars()
     return [lr, lq, l1]
 
diff --git a/rpython/jit/backend/zarch/instruction_builder.py 
b/rpython/jit/backend/zarch/instruction_builder.py
--- a/rpython/jit/backend/zarch/instruction_builder.py
+++ b/rpython/jit/backend/zarch/instruction_builder.py
@@ -185,7 +185,7 @@
         self.writechar(opcode)
         byte = (reg_or_mask & 0xf) << 4 | (ord(halfopcode) & 0xf)
         self.writechar(chr(byte))
-        if br or mnemonic == 'LARL':
+        if br:
             imm32 = imm32 >> 1
         # half word boundary, addressing bytes
         self.write_i32(imm32 & BIT_MASK_32)
@@ -350,7 +350,7 @@
         for i,arg in enumerate(unrolling_iterable(func._arguments_)):
             if arg == '-':
                 newargs[i] = 0
-            elif arg == 'r' or arg == 'r/m' or arg == 'f':
+            elif arg == 'r' or arg == 'r/m' or arg == 'f' or arg == 'eo':
                 newargs[i] = args[i].value
             elif arg.startswith('i') or arg.startswith('u') or 
arg.startswith('h'):
                 newargs[i] = args[i].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
@@ -19,8 +19,8 @@
     def emit_int_mul(self, op, arglocs, regalloc):
         l0, l1 = arglocs
         if l1.is_imm():
-            self.mc.MSFI(l0, l1)
-        if l1.is_in_pool():
+            self.mc.MSGFI(l0, l1)
+        elif l1.is_in_pool():
             self.mc.MSG(l0, l1)
         else:
             self.mc.MSGR(l0, l1)
@@ -29,7 +29,7 @@
         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"
+        assert l1.is_in_pool() or 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()
@@ -38,18 +38,32 @@
         else:
             self.mc.DSGR(lr, l1)
 
-    def emit_int_ufloordiv(self, op, arglocs, regalloc):
+    def emit_uint_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"
+        assert l1.is_in_pool() or 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()
+        self.mc.XGR(lr, lr)
+        if l1.is_in_pool():
+            self.mc.DLG(lr, l1)
+        else:
+            self.mc.DLGR(lr, l1)
+
+    def emit_int_mod(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 l1.is_in_pool() or 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)
+            self.mc.DSG(lr, l1)
         else:
-            self.mc.DLGR(lr, l1)
+            self.mc.DSGR(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,27 +135,73 @@
         self.temp_boxes.append(box)
         return reg
 
-    def ensure_even_odd_pair(self, var):
-        self.rm.ensure__check_type(var)
+    def ensure_even_odd_pair(self, var, bind_first=True):
+        self._check_type(var)
         prev_loc = self.loc(var, must_exist=True)
+        var2 = TempVar()
+        self.temp_boxes.append(var2)
         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)
+        if bind_first:
+            loc, loc2 = self.force_allocate_reg_pair(var, var2, 
self.temp_boxes)
+        else:
+            loc, loc2 = self.force_allocate_reg_pair(var2, var, 
self.temp_boxes)
+        assert loc.is_even() and loc2.is_odd()
+        if prev_loc is not loc2:
+            # TODO is this true for each op?
+            # works for division -> if not parametrize
+            self.assembler.regalloc_mov(prev_loc, loc2)
+        return loc, loc2
+
+    def force_allocate_reg_pair(self, var, var2, forbidden_vars=[], 
selected_reg=None):
+        """ Forcibly allocate a register for the new variable v.
+        It must not be used so far.  If we don't have a free register,
+        spill some other variable, according to algorithm described in
+        '_pick_variable_to_spill'.
+
+        Will not spill a variable from 'forbidden_vars'.
+        """
+        self._check_type(var)
+        self._check_type(var2)
+        if isinstance(var, TempVar):
+            self.longevity[var] = (self.position, self.position)
+        if isinstance(var2, TempVar):
+            self.longevity[var2] = (self.position, self.position)
+        even, odd = None, None
+        REGS = r.registers
+        i = len(self.free_regs)-1
+        while i >= 0:
+            even = self.free_regs[i]
+            if even.is_even():
+                odd = REGS[even.value+1]
+                print even, "is even", odd
+                if odd not in self.free_regs:
+                    print odd, "is NOT free"
+                    continue
+                print odd, "is free"
+                self.reg_bindings[var] = even
+                self.reg_bindings[var2] = odd
+                del self.free_regs[i]
+                i = self.free_regs.index(odd)
+                del self.free_regs[i]
+                return even, odd
+            i += 1
+
+        import pdb; pdb.set_trace()
+        xxx
+        loc = self._spill_var(v, forbidden_vars, selected_reg,
+                              need_lower_byte=need_lower_byte)
+        prev_loc = self.reg_bindings.get(v, None)
+        if prev_loc is not None:
+            self.free_regs.append(prev_loc)
+        self.reg_bindings[v] = 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
 
 
@@ -490,9 +536,9 @@
     prepare_int_add = helper.prepare_int_add
     prepare_int_sub = helper.prepare_int_sub
     prepare_int_mul = helper.prepare_int_mul
-    prepare_int_floordiv = helper.prepare_div
-    prepare_uint_floordiv = helper.prepare_div
-    prepare_int_mod = helper.prepare_mod
+    prepare_int_floordiv = helper.prepare_int_div
+    prepare_uint_floordiv = helper.prepare_int_div
+    prepare_int_mod = helper.prepare_int_mod
 
     prepare_int_le = helper.prepare_cmp_op
     prepare_int_lt = helper.prepare_cmp_op
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
@@ -24,10 +24,18 @@
         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):
+    @py.test.mark.parametrize('value,opcode,result',
+        [ (30,'i1 = int_mul(i0, 2)',60),
+          (30,'i1 = int_floordiv(i0, 2)',15),
+          (2**31,'i1 = int_floordiv(i0, 15)',2**31//15),
+          (0,'i1 = int_floordiv(i0, 1)', 0),
+          (1,'i1 = int_floordiv(i0, 1)', 1),
+          (0,'i1 = uint_floordiv(i0, 1)', 0),
+          (1,'i1 = uint_floordiv(i0, 1)', 1),
+          (30,'i1 = int_mod(i0, 2)', 0),
+          (1,'i1 = int_mod(i0, 2)', 1),
+        ])
+    def test_int_arithmetic_and_logic(self, value, opcode, result):
         loop = parse("""
         [i0]
         {opcode}
@@ -35,7 +43,7 @@
         """.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)
+        deadframe = self.cpu.execute_token(looptoken, value)
         fail = self.cpu.get_latest_descr(deadframe)
         res = self.cpu.get_int_value(deadframe, 0)
         assert res == result
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to