[pypy-svn] r36615 - in pypy/dist/pypy/jit/codegen: ppc ppc/test test

mwh at codespeak.net mwh at codespeak.net
Fri Jan 12 20:11:12 CET 2007


Author: mwh
Date: Fri Jan 12 20:10:37 2007
New Revision: 36615

Modified:
   pypy/dist/pypy/jit/codegen/ppc/instruction.py
   pypy/dist/pypy/jit/codegen/ppc/regalloc.py
   pypy/dist/pypy/jit/codegen/ppc/rgenop.py
   pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py
   pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
(niko, mwh)

more headbanging on ppc code generation, with tests.
all bugs found by the test_timeshift test test_residual_red_call_with_exc,
which is quite impressive.


Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/instruction.py	(original)
+++ pypy/dist/pypy/jit/codegen/ppc/instruction.py	Fri Jan 12 20:10:37 2007
@@ -57,6 +57,9 @@
     def move_to_gpr(self, allocator, gpr):
         bit, negated = allocator.crfinfo[self.number]
         return _CRF2GPR(gpr, self.number*4 + bit, negated)
+    def move_from_gpr(self, allocator, gpr):
+        allocator.crfinfo[self.number] = (2, 1) # cmp2info['ne']
+        return _GPR2CRF(self, gpr)
 
 crfs = map(CRF, range(8))
 
@@ -169,6 +172,24 @@
                      self.result_reg.number,
                      self.imm.value)
 
+class MoveCRB2GPR(Insn):
+    def __init__(self, result, gv_condition):
+        Insn.__init__(self)
+        self.result = result
+        self.result_regclass = GP_REGISTER
+        self.reg_args = [gv_condition]
+        self.reg_arg_regclasses = [CR_FIELD]
+    def allocate(self, allocator):
+        self.targetreg = allocator.loc_of(self.result)
+        self.crf = allocator.loc_of(self.reg_args[0])
+        self.bit, self.negated = allocator.crfinfo[self.crf.number]
+        assert self.bit != -1 and self.negated != -1, "uninitialized crfinfo!"
+    def emit(self, asm):
+        asm.mfcr(self.targetreg.number)
+        asm.extrwi(self.targetreg.number, self.targetreg.number, 1, self.crf.number*4+self.bit)
+        if self.negated:
+            asm.xori(self.targetreg.number, self.targetreg.number, 1)
+
 class Insn_None__GPR_GPR_IMM(Insn):
     def __init__(self, methptr, args):
         Insn.__init__(self)
@@ -296,11 +317,13 @@
     def allocate(self, allocator):
         self.crf = allocator.loc_of(self.reg_args[0])
         self.bit, self.negated = allocator.crfinfo[self.crf.number]
+        assert self.bit != -1 and self.negated != -1, "uninitialized crfinfo!"
 
         assert self.targetbuilder.initial_var2loc is None
         self.targetbuilder.initial_var2loc = {}
         for gv_arg in self.jump_args_gv:
             self.targetbuilder.initial_var2loc[gv_arg] = allocator.var2loc[gv_arg]
+        self.targetbuilder.initial_crfinfo = allocator.crfinfo[:]
         allocator.builders_to_tell_spill_offset_to.append(self.targetbuilder)
     def emit(self, asm):
         if self.targetbuilder.start:
@@ -457,6 +480,14 @@
         if self.negated:
             asm.xori(self.targetreg, self.targetreg, 1)
 
+class _GPR2CRF(AllocTimeInsn):
+    def __init__(self, targetreg, fromreg):
+        AllocTimeInsn.__init__(self)
+        self.targetreg = targetreg
+        self.fromreg = fromreg
+    def emit(self, asm):
+        asm.cmpwi(self.targetreg.number, self.fromreg, 0)
+
 class _GPR2CTR(AllocTimeInsn):
     def __init__(self, fromreg):
         AllocTimeInsn.__init__(self)

Modified: pypy/dist/pypy/jit/codegen/ppc/regalloc.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/regalloc.py	(original)
+++ pypy/dist/pypy/jit/codegen/ppc/regalloc.py	Fri Jan 12 20:10:37 2007
@@ -9,7 +9,8 @@
 DEBUG_PRINT = option.debug_print
 
 class RegisterAllocation:
-    def __init__(self, freeregs, initial_mapping, initial_spill_offset):
+    def __init__(self, freeregs, initial_mapping,
+                 initial_spill_offset, initial_crfinfo):
         if DEBUG_PRINT:
             print
             print "RegisterAllocation __init__", initial_mapping.items()
@@ -39,7 +40,7 @@
 
         # crfinfo is a bit of a hack used to transmit which bit a compare
         # instruction set to the branch instruction
-        self.crfinfo = [(0, 0)] * 8
+        self.crfinfo = initial_crfinfo[:]
         self.builders_to_tell_spill_offset_to = []
 
     def set(self, var, loc):

Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py	Fri Jan 12 20:10:37 2007
@@ -104,15 +104,21 @@
 
 class JumpPatchupGenerator(object):
 
-    def __init__(self, insns, min_offset):
+    def __init__(self, insns, min_offset, allocator):
         self.insns = insns
         self.min_offset = min_offset
+        self.allocator = allocator
 
     def emit_move(self, tarloc, srcloc):
         if tarloc == srcloc: return
         emit = self.insns.append
         if tarloc.is_register and srcloc.is_register:
-            emit(insn.Move(tarloc, srcloc))
+            assert isinstance(tarloc, insn.GPR)
+            if isinstance(srcloc, insn.GPR):
+                emit(insn.Move(tarloc, srcloc))
+            else:
+                assert isinstance(srcloc, insn.CRF)
+                emit(srcloc.move_to_gpr(self.allocator, tarloc.number))
         elif tarloc.is_register and not srcloc.is_register:
             emit(insn.Unspill(None, tarloc, srcloc))
             #self.asm.lwz(tarloc.number, rFP, srcloc.offset)
@@ -130,7 +136,7 @@
         self.min_offset -= 4
         return insn.stack_slot(r)
 
-def prepare_for_jump(insns, min_offset, sourcevars, src2loc, target):
+def prepare_for_jump(insns, min_offset, sourcevars, src2loc, target, allocator):
 
     tar2src = {}     # tar var -> src var
     tar2loc = {}
@@ -147,7 +153,7 @@
         else:
             insns.append(insn.Load(tloc, src))
 
-    gen = JumpPatchupGenerator(insns, min_offset)
+    gen = JumpPatchupGenerator(insns, min_offset, allocator)
     emit_moves(gen, tar2src, tar2loc, src2loc)
     return gen.min_offset
 
@@ -198,6 +204,7 @@
         self.stack_adj_addr = 0
         self.initial_spill_offset = 0
         self.initial_var2loc = None
+        self.initial_crfinfo = [(-1, -1)] * 8
         self.max_param_space = -1
         self.final_jump_addr = 0
 
@@ -340,7 +347,29 @@
         vars_gv = [v for v in args_gv if isinstance(v, Var)]
         #print 'initial_var2loc.keys():', [id(v) for v in self.initial_var2loc.keys()]
         #print 'initial_var2loc.values():', [id(v) for v in self.initial_var2loc.values()]
-        var2loc = self.allocate_and_emit(vars_gv).var2loc
+        allocator = self.allocate_and_emit(vars_gv)
+        self.initial_crfinfo = allocator.crfinfo
+        var2loc = allocator.var2loc
+
+        #print '!!!!', args_gv, var2loc
+
+        self.insns = []
+
+        reallocate = False
+        for i in range(len(args_gv)):
+            v = args_gv[i]
+            if isinstance(v, Var) and isinstance(var2loc[v], insn.CRF):
+                reallocate = True
+                nv = Var()
+                self.insns.append(insn.MoveCRB2GPR(nv, v))
+                args_gv[i] = nv
+        self.initial_var2loc = var2loc
+        if reallocate:
+            allocator = self.allocate_and_emit([v for v in args_gv if isinstance(v, Var)])
+            self.initial_crfinfo = allocator.crfinfo
+            var2loc = allocator.var2loc
+            self.insns = []
+
         #print 'var2loc.keys():', [id(v) for v in var2loc.keys()]
         #print 'var2loc.values():', [id(v) for v in var2loc.values()]
         #print 'args_gv', [id(v) for v in args_gv]
@@ -385,7 +414,6 @@
 
         #print livevar2loc
 
-        self.insns = []
         self.initial_var2loc = livevar2loc
         #print 'final initial_var2loc.keys():', [id(v) for v in self.initial_var2loc.keys()]
         #print 'final initial_var2loc.values():', [id(v) for v in self.initial_var2loc.values()]
@@ -427,7 +455,7 @@
         allocator = self.allocate(outputargs_gv)
         min_offset = min(allocator.spill_offset, target.min_stack_offset)
         allocator.spill_offset = prepare_for_jump(
-            self.insns, min_offset, outputargs_gv, allocator.var2loc, target)
+            self.insns, min_offset, outputargs_gv, allocator.var2loc, target, allocator)
         self.emit(allocator)
         self.asm.load_word(rSCRATCH, target.startaddr)
         self.asm.mtctr(rSCRATCH)
@@ -575,7 +603,8 @@
         allocator = RegisterAllocation(
             self.rgenop.freeregs,
             self.initial_var2loc,
-            self.initial_spill_offset)
+            self.initial_spill_offset,
+            self.initial_crfinfo)
         self.insns = allocator.allocate_for_insns(self.insns)
         return allocator
 

Modified: pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py	Fri Jan 12 20:10:37 2007
@@ -102,9 +102,6 @@
         res = fnptr(2)
         assert res == 101010
 
-    def test_longwinded_and_direct(self):
-        py.test.skip("failing right now")
-
 class TestRPPCGenopNoRegs(TestRPPCGenop):
     RGenOp = FewRegisters
 

Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py	(original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py	Fri Jan 12 20:10:37 2007
@@ -405,6 +405,28 @@
 
     return gv_f
 
+def make_condition_result_cross_link(rgenop):
+
+    signed_kind = rgenop.kindToken(lltype.Signed)
+    sigtoken = rgenop.sigToken(FUNC)
+    builder, gv_f, [gv_y] = rgenop.newgraph(sigtoken, "foo")
+
+    gv_result = builder.genop2("int_eq", gv_y, rgenop.genconst(0))
+    target1 = builder.jump_if_false(gv_result, [gv_result])
+
+    builder.finish_and_return(sigtoken, rgenop.genconst(1))
+
+    target1.start_writing()
+    target2 = target1.jump_if_false(gv_result, [])
+
+    # this return should be unreachable:
+    target1.finish_and_return(sigtoken, rgenop.genconst(2))
+
+    target2.start_writing()
+    target2.finish_and_return(sigtoken, rgenop.genconst(3))
+
+    return gv_f
+
 class AbstractRGenOpTests(test_boehm.AbstractGCTestClass):
     RGenOp = None
 
@@ -609,6 +631,8 @@
         gv_fn = make_longwinded_and(rgenop)
         fnptr = self.cast(gv_fn, 1)
 
+        print map(fnptr, range(6))
+
         res = fnptr(1)
         assert res == 0
 
@@ -623,3 +647,17 @@
 
         res = fnptr(5)
         assert res == 0
+
+    def test_condition_result_cross_link_direct(self):
+        rgenop = self.RGenOp()
+        gv_fn = make_condition_result_cross_link(rgenop)
+        fnptr = self.cast(gv_fn, 1)
+
+        res = fnptr(-1)
+        assert res == 3
+
+        res = fnptr(0)
+        assert res == 1
+
+        res = fnptr(1)
+        assert res == 3



More information about the Pypy-commit mailing list