Author: Richard Plangger <planri...@gmail.com>
Branch: s390x-backend
Changeset: r82063:621a42ebea23
Date: 2016-02-03 20:19 +0100
http://bitbucket.org/pypy/pypy/changeset/621a42ebea23/

Log:    cond_call_gc_wb_array can now not trash a volatile register. wrong
        allocation now takes a non volatile register!

diff --git a/rpython/jit/backend/zarch/assembler.py 
b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -241,7 +241,7 @@
             self._restore_exception(mc, RCS2, RCS3)
 
         if withcards:
-            # A final andix before the blr, for the caller.  Careful to
+            # A final NILL before the return to the caller.  Careful to
             # not follow this instruction with another one that changes
             # the status of the condition code
             card_marking_mask = descr.jit_wb_cards_set_singlebyte
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
@@ -495,7 +495,7 @@
         mc.NILL(r.SCRATCH, l.imm(mask & 0xFF))
 
         jz_location = mc.get_relative_pos()
-        mc.reserve_cond_jump()  # patched later with 'EQ'
+        mc.reserve_cond_jump(short=True)  # patched later with 'EQ'
 
         # for cond_call_gc_wb_array, also add another fast path:
         # if GCFLAG_CARDS_SET, then we can just set one bit and be done
@@ -535,7 +535,7 @@
             # So here, we can simply write again a beq, which will be
             # taken if GCFLAG_CARDS_SET is still not set.
             jns_location = mc.get_relative_pos()
-            mc.reserve_cond_jump()
+            mc.reserve_cond_jump(short=True)
             #
             # patch the 'NE' above
             currpos = mc.currpos()
@@ -547,6 +547,8 @@
             # directly the card flag setting
             loc_index = arglocs[1]
             if loc_index.is_reg():
+                # must a register that is preserved across function calls
+                assert loc_index.value >= 6
                 tmp_loc = arglocs[2]
                 n = descr.jit_wb_card_page_shift
 
@@ -562,15 +564,16 @@
                 # 0x80 sets zero flag. will store 0 into all not selected bits
                 mc.RISBGN(r.SCRATCH, loc_index, l.imm(61), l.imm(0x80 | 63), 
l.imm(64-n))
 
+                # set SCRATCH2 to 1 << r1
                 # invert the bits of tmp_loc
-                mc.LCGR(tmp_loc, tmp_loc)
                 #mc.XIHF(tmp_loc, l.imm(0xffffFFFF))
                 #mc.XILF(tmp_loc, l.imm(0xffffFFFF))
-
-                # set SCRATCH2 to 1 << r1
+                mc.LG(r.SCRATCH2, l.pool(self.pool.constant_64_ones))
+                mc.XGR(tmp_loc, r.SCRATCH2)
                 mc.LGHI(r.SCRATCH2, l.imm(1))
                 mc.SLAG(r.SCRATCH2, r.SCRATCH2, l.addr(0,r.SCRATCH))
 
+
                 # set this bit inside the byte of interest
                 addr = l.addr(0, loc_base, tmp_loc)
                 mc.LLGC(r.SCRATCH, addr)
@@ -591,13 +594,13 @@
             # patch the beq just above
             currpos = mc.currpos()
             pmc = OverwritingBuilder(mc, jns_location, 1)
-            pmc.BRCL(c.EQ, l.imm(currpos - jns_location))
+            pmc.BRC(c.EQ, l.imm(currpos - jns_location))
             pmc.overwrite()
 
         # patch the JZ above
         currpos = mc.currpos()
         pmc = OverwritingBuilder(mc, jz_location, 1)
-        pmc.BRCL(c.EQ, l.imm(currpos - jz_location))
+        pmc.BRC(c.EQ, l.imm(currpos - jz_location))
         pmc.overwrite()
 
     def emit_cond_call_gc_wb(self, op, arglocs, regalloc):
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
@@ -99,9 +99,9 @@
                     forbidden_vars=self.temp_boxes)
         return loc
 
-    def get_scratch_reg(self,):
+    def get_scratch_reg(self, selected_reg=None):
         box = TempFloat()
-        reg = self.force_allocate_reg(box, forbidden_vars=self.temp_boxes)
+        reg = self.force_allocate_reg(box, forbidden_vars=self.temp_boxes, 
selected_reg=selected_reg)
         self.temp_boxes.append(box)
         return reg
 
@@ -151,9 +151,9 @@
                     selected_reg=selected_reg)
         return loc
 
-    def get_scratch_reg(self):
+    def get_scratch_reg(self, selected_reg=None):
         box = TempInt()
-        reg = self.force_allocate_reg(box, forbidden_vars=self.temp_boxes)
+        reg = self.force_allocate_reg(box, forbidden_vars=self.temp_boxes, 
selected_reg=selected_reg)
         self.temp_boxes.append(box)
         return reg
 
@@ -583,13 +583,13 @@
         else:
             return self.rm.ensure_reg(box, force_in_reg)
 
-    def ensure_reg_or_16bit_imm(self, box):
+    def ensure_reg_or_16bit_imm(self, box, selected_reg=None):
         if box.type == FLOAT:
             return self.fprm.ensure_reg(box, True)
         else:
             if helper.check_imm(box):
                 return imm(box.getint())
-            return self.rm.ensure_reg(box, force_in_reg=True)
+            return self.rm.ensure_reg(box, force_in_reg=True, 
selected_reg=selected_reg)
 
     def ensure_reg_or_any_imm(self, box):
         if box.type == FLOAT:
@@ -599,11 +599,11 @@
                 return imm(box.getint())
             return self.rm.ensure_reg(box, force_in_reg=True)
 
-    def get_scratch_reg(self, type):
+    def get_scratch_reg(self, type, selected_reg=None):
         if type == FLOAT:
             return self.fprm.get_scratch_reg()
         else:
-            return self.rm.get_scratch_reg()
+            return self.rm.get_scratch_reg(selected_reg=selected_reg)
 
     def free_op_vars(self):
         # free the boxes in the 'temp_boxes' lists, which contain both
@@ -984,8 +984,11 @@
         return arglocs
 
     def prepare_cond_call_gc_wb_array(self, op):
+        # just calling ensure_reg may return a register r2->r6.
+        # but in the assembly a sub routine is called that trashes r2->r6.
+        # thus select two registers that are preserved
         arglocs = [self.ensure_reg(op.getarg(0), force_in_reg=True),
-                   self.ensure_reg_or_16bit_imm(op.getarg(1)),
+                   self.ensure_reg_or_16bit_imm(op.getarg(1), 
selected_reg=r.r7),
                    None]
         if arglocs[1].is_reg():
             arglocs[2] = self.get_scratch_reg(INT)
diff --git a/rpython/jit/backend/zarch/test/test_assembler.py 
b/rpython/jit/backend/zarch/test/test_assembler.py
--- a/rpython/jit/backend/zarch/test/test_assembler.py
+++ b/rpython/jit/backend/zarch/test/test_assembler.py
@@ -202,6 +202,13 @@
         self.a.mc.BCR(con.ANY, r.r14)
         assert run_asm(self.a) == 0
 
+    def test_complement(self):
+        self.a.mc.load_imm(r.r2, 0)
+        #self.a.mc.LCGR(r.r2, r.r2)
+        self.a.mc.XIHF(r.r2, loc.imm(0xffffFFFF))
+        self.a.mc.XILF(r.r2, loc.imm(0xffffFFFF))
+        self.a.mc.BCR(con.ANY, r.r14)
+        assert run_asm(self.a) == -1
 
     def test_load_small_int_to_reg(self):
         self.a.mc.LGHI(r.r2, loc.imm(123))
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to