Author: David Schneider <david.schnei...@picle.org> Branch: arm-backend-2 Changeset: r47709:99de51bb629b Date: 2011-09-29 16:06 +0200 http://bitbucket.org/pypy/pypy/changeset/99de51bb629b/
Log: refactor and test regalloc_push diff --git a/pypy/jit/backend/arm/assembler.py b/pypy/jit/backend/arm/assembler.py --- a/pypy/jit/backend/arm/assembler.py +++ b/pypy/jit/backend/arm/assembler.py @@ -898,17 +898,18 @@ pushed = False if loc.is_reg(): assert prev_loc.type != FLOAT, 'trying to load from an incompatible location into a core register' + assert loc is not r.lr, 'lr is not supported as a target when moving from the stack' # unspill a core register offset = ConstInt(prev_loc.position*WORD) if not _check_imm_arg(offset, size=0xFFF): - self.mc.PUSH([r.ip.value], cond=cond) + self.mc.PUSH([r.lr.value], cond=cond) pushed = True - self.mc.gen_load_int(r.ip.value, -offset.value, cond=cond) - self.mc.LDR_rr(loc.value, r.fp.value, r.ip.value, cond=cond) + self.mc.gen_load_int(r.lr.value, -offset.value, cond=cond) + self.mc.LDR_rr(loc.value, r.fp.value, r.lr.value, cond=cond) else: self.mc.LDR_ri(loc.value, r.fp.value, imm=-offset.value, cond=cond) if pushed: - self.mc.POP([r.ip.value], cond=cond) + self.mc.POP([r.lr.value], cond=cond) elif loc.is_vfp_reg(): assert prev_loc.type == FLOAT, 'trying to load from an incompatible location into a float register' # load spilled value into vfp reg @@ -972,7 +973,6 @@ """Moves floating point values either as an immediate, in a vfp register or at a stack location to a pair of core registers""" assert reg1.value + 1 == reg2.value - temp = r.lr if vfp_loc.is_vfp_reg(): self.mc.VMOV_rc(reg1.value, reg2.value, vfp_loc.value, cond=cond) elif vfp_loc.is_imm_float(): @@ -1021,26 +1021,33 @@ else: assert 0, 'unsupported case' - def regalloc_push(self, loc): + def regalloc_push(self, loc, cond=c.AL): + """Pushes the value stored in loc to the stack + Can trash the current value of the IP register when pushing a stack + lock""" + if loc.is_stack(): + # XXX maybe push ip here to avoid trashing it and restore ip and + # the loc in regalloc pop. Also regalloc mov would not exclude + # stack -> lr, which is not a big issue anyway if loc.type != FLOAT: scratch_reg = r.ip else: scratch_reg = r.vfp_ip - self.regalloc_mov(loc, scratch_reg) - self.regalloc_push(scratch_reg) + self.regalloc_mov(loc, scratch_reg, cond) + self.regalloc_push(scratch_reg, cond) elif loc.is_reg(): - self.mc.PUSH([loc.value]) + self.mc.PUSH([loc.value], cond=cond) elif loc.is_vfp_reg(): - self.mc.VPUSH([loc.value]) + self.mc.VPUSH([loc.value], cond=cond) elif loc.is_imm(): self.regalloc_mov(loc, r.ip) - self.mc.PUSH([r.ip.value]) + self.mc.PUSH([r.ip.value], cond=cond) elif loc.is_imm_float(): - self.regalloc_mov(loc, r.d15) - self.mc.VPUSH([r.d15.value]) + self.regalloc_mov(loc, r.vfp_ip) + self.mc.VPUSH([r.vfp_ip.value], cond=cond) else: - assert 0, 'ffuu' + raise AssertionError('Trying to push an invalid location') def regalloc_pop(self, loc): if loc.is_stack(): diff --git a/pypy/jit/backend/arm/test/test_regalloc_mov.py b/pypy/jit/backend/arm/test/test_regalloc_mov.py --- a/pypy/jit/backend/arm/test/test_regalloc_mov.py +++ b/pypy/jit/backend/arm/test/test_regalloc_mov.py @@ -3,7 +3,7 @@ from pypy.jit.backend.arm.locations import imm, ImmLocation, ConstFloatLoc,\ RegisterLocation, StackLocation, \ VFPRegisterLocation -from pypy.jit.backend.arm.registers import lr, ip, fp +from pypy.jit.backend.arm.registers import lr, ip, fp, vfp_ip from pypy.jit.backend.arm.conditions import AL from pypy.jit.metainterp.history import INT, FLOAT, REF import py @@ -156,10 +156,10 @@ s = stack(8191) r6 = r(6) expected = [ - mi('PUSH', [ip.value], cond=AL), - mi('gen_load_int', ip.value, -32764, cond=AL), - mi('LDR_rr', r6.value, fp.value, ip.value, cond=AL), - mi('POP', [ip.value], cond=AL)] + mi('PUSH', [lr.value], cond=AL), + mi('gen_load_int', lr.value, -32764, cond=AL), + mi('LDR_rr', r6.value, fp.value, lr.value, cond=AL), + mi('POP', [lr.value], cond=AL)] self.mov(s, r6, expected) def test_mov_float_imm_to_vfp_reg(self): @@ -235,6 +235,7 @@ py.test.raises(AssertionError, 'self.asm.regalloc_mov(stack(1), stack(2))') py.test.raises(AssertionError, 'self.asm.regalloc_mov(stack(1), stack_float(2))') py.test.raises(AssertionError, 'self.asm.regalloc_mov(stack(1), vfp(2))') + py.test.raises(AssertionError, 'self.asm.regalloc_mov(stack(1), lr)') py.test.raises(AssertionError, 'self.asm.regalloc_mov(stack_float(1), imm(2))') py.test.raises(AssertionError, 'self.asm.regalloc_mov(stack_float(1), imm_float(2))') py.test.raises(AssertionError, 'self.asm.regalloc_mov(stack_float(1), r(2))') @@ -338,3 +339,74 @@ py.test.raises(AssertionError, 'self.asm.mov_from_vfp_loc(r(1), r(2), imm(2))') py.test.raises(AssertionError, 'self.asm.mov_from_vfp_loc(r(1), r(2), imm_float(2))') py.test.raises(AssertionError, 'self.asm.mov_from_vfp_loc(r(1), r(1), r(2))') + +class TestRegallocPush(BaseMovTest): + def push(self, v, e): + self.asm.regalloc_push(v) + self.validate(e) + + def test_push_imm(self): + i = imm(12) + e = [mi('gen_load_int', ip.value, 12, cond=AL), + mi('PUSH', [ip.value], cond=AL)] + self.push(i, e) + + def test_push_reg(self): + r7 = r(7) + e = [mi('PUSH', [r7.value], cond=AL)] + self.push(r7, e) + + def test_push_imm_float(self): + f = imm_float(7) + e = [mi('PUSH', [ip.value], cond=AL), + mi('gen_load_int', ip.value, 7, cond=AL), + mi('VLDR', vfp_ip.value, ip.value, cond=AL), + mi('POP', [ip.value], cond=AL), + mi('VPUSH', [vfp_ip.value], cond=AL) + ] + self.push(f, e) + + def test_push_stack(self): + s = stack(7) + e = [mi('LDR_ri', ip.value, fp.value, imm=-28, cond=AL), + mi('PUSH', [ip.value], cond=AL) + ] + self.push(s, e) + + def test_push_big_stack(self): + s = stack(1025) + e = [mi('PUSH', [lr.value], cond=AL), + mi('gen_load_int', lr.value, -4100, cond=AL), + mi('LDR_rr', ip.value, fp.value, lr.value, cond=AL), + mi('POP', [lr.value], cond=AL), + mi('PUSH', [ip.value], cond=AL) + ] + self.push(s, e) + + def test_push_vfp_reg(self): + v1 = vfp(1) + e = [mi('VPUSH', [v1.value], cond=AL)] + self.push(v1, e) + + def test_push_stack_float(self): + sf = stack_float(4) + e = [ + mi('PUSH', [ip.value], cond=AL), + mi('SUB_ri', ip.value, fp.value, 16, cond=AL), + mi('VLDR', vfp_ip.value, ip.value, cond=AL), + mi('POP', [ip.value], cond=AL), + mi('VPUSH', [vfp_ip.value], cond=AL), + ] + self.push(sf, e) + + def test_push_large_stackfloat(self): + sf = stack_float(100) + e = [ + mi('PUSH', [ip.value], cond=AL), + mi('gen_load_int', ip.value, 400, cond=AL), + mi('SUB_rr', ip.value, fp.value, ip.value, cond=AL), + mi('VLDR', vfp_ip.value, ip.value, cond=AL), + mi('POP', [ip.value], cond=AL), + mi('VPUSH', [vfp_ip.value], cond=AL), + ] + self.push(sf, e) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit