[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