[pypy-commit] pypy arm-backend-2: refactor and test regalloc_push
bivab
noreply at buildbot.pypy.org
Fri Sep 30 12:00:22 CEST 2011
Author: David Schneider <david.schneider at 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)
More information about the pypy-commit
mailing list