Author: David Schneider <[email protected]>
Branch: jitframe-on-heap
Changeset: r61340:413242473067
Date: 2013-02-17 02:56 +0100
http://bitbucket.org/pypy/pypy/changeset/413242473067/
Log: refactor load, store and move helper methods.
Use imm offsets for VLDR and VSTR if possible
diff --git a/rpython/jit/backend/arm/assembler.py
b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -949,47 +949,8 @@
faildescr._arm_failure_recovery_block = 0
# regalloc support
- def load_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip):
- if target.is_vfp_reg():
- return self._load_vfp_reg(mc, target, base, ofs, cond)
- elif target.is_reg():
- return self._load_core_reg(mc, target, base, ofs, cond)
-
- def _load_vfp_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip):
- if check_imm_arg(ofs):
- mc.VLDR(target.value, base.value, imm=ofs, cond=cond)
- else:
- mc.gen_load_int(helper.value, ofs)
- mc.VLDR(target.value, base.value, helper.value, cond=cond)
-
- def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip):
- if check_imm_arg(ofs):
- mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond)
- else:
- mc.gen_load_int(helper.value, ofs)
- mc.LDR_rr(target.value, base.value, helper.value, cond=cond)
-
- def store_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip):
- if source.is_vfp_reg():
- return self._store_vfp_reg(mc, source, base, ofs, cond)
- else:
- return self._store_core_reg(mc, source, base, ofs, cond)
-
- def _store_vfp_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip):
- if check_imm_arg(ofs):
- mc.VSTR(source.value, base.value, imm=ofs, cond=cond)
- else:
- mc.gen_load_int(helper.value, ofs)
- mc.VSTR(source.value, base.value, helper.value, cond=cond)
-
- def _store_core_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip):
- if check_imm_arg(ofs):
- mc.STR_ri(source.value, base.value, imm=ofs, cond=cond)
- else:
- gen_load_int(helper.value, ofs)
- mc.STR_rr(source.value, base.value, helper.value, cond=cond)
-
def load(self, loc, value):
+ """load an immediate value into a register"""
assert (loc.is_reg() and value.is_imm()
or loc.is_vfp_reg() and value.is_imm_float())
if value.is_imm():
@@ -998,6 +959,48 @@
self.mc.gen_load_int(r.ip.value, value.getint())
self.mc.VLDR(loc.value, r.ip.value)
+ def load_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip):
+ if target.is_vfp_reg():
+ return self._load_vfp_reg(mc, target, base, ofs, cond, helper)
+ elif target.is_reg():
+ return self._load_core_reg(mc, target, base, ofs, cond, helper)
+
+ def _load_vfp_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip):
+ if check_imm_arg(ofs):
+ mc.VLDR(target.value, base.value, imm=ofs, cond=cond)
+ else:
+ mc.gen_load_int(helper.value, ofs, cond=cond)
+ mc.ADD_rr(helper.value, base.value, helper.value, cond=cond)
+ mc.VLDR(target.value, helper.value, cond=cond)
+
+ def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip):
+ if check_imm_arg(ofs):
+ mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond)
+ else:
+ mc.gen_load_int(helper.value, ofs, cond=cond)
+ mc.LDR_rr(target.value, base.value, helper.value, cond=cond)
+
+ def store_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip):
+ if source.is_vfp_reg():
+ return self._store_vfp_reg(mc, source, base, ofs, cond, helper)
+ else:
+ return self._store_core_reg(mc, source, base, ofs, cond, helper)
+
+ def _store_vfp_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip):
+ if check_imm_arg(ofs):
+ mc.VSTR(source.value, base.value, imm=ofs, cond=cond)
+ else:
+ mc.gen_load_int(helper.value, ofs, cond=cond)
+ mc.ADD_rr(helper.value, base.value, helper.value, cond=cond)
+ mc.VSTR(source.value, helper.value, cond=cond)
+
+ def _store_core_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip):
+ if check_imm_arg(ofs):
+ mc.STR_ri(source.value, base.value, imm=ofs, cond=cond)
+ else:
+ mc.gen_load_int(helper.value, ofs, cond=cond)
+ mc.STR_rr(source.value, base.value, helper.value, cond=cond)
+
def _mov_imm_to_loc(self, prev_loc, loc, cond=c.AL):
if not loc.is_reg() and not (loc.is_stack() and loc.type != FLOAT):
raise AssertionError("invalid target for move from imm value")
@@ -1025,15 +1028,12 @@
else:
temp = r.ip
offset = loc.value
- if not check_imm_arg(offset, size=0xFFF):
+ is_imm = check_imm_arg(offset, size=0xFFF)
+ if not is_imm:
self.mc.PUSH([temp.value], cond=cond)
- self.mc.gen_load_int(temp.value, offset, cond=cond)
- self.mc.STR_rr(prev_loc.value, r.fp.value,
- temp.value, cond=cond)
+ self.store_reg(self.mc, prev_loc, r.fp, offset, helper=temp,
cond=cond)
+ if not is_imm:
self.mc.POP([temp.value], cond=cond)
- else:
- self.mc.STR_ri(prev_loc.value, r.fp.value,
- imm=offset, cond=cond)
else:
assert 0, 'unsupported case'
@@ -1046,29 +1046,22 @@
when moving from the stack'
# unspill a core register
offset = prev_loc.value
- if not check_imm_arg(offset, size=0xFFF):
+ is_imm = check_imm_arg(offset, size=0xFFF)
+ if not is_imm:
self.mc.PUSH([r.lr.value], cond=cond)
- pushed = True
- self.mc.gen_load_int(r.lr.value, offset, 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, cond=cond)
- if pushed:
+ self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.lr)
+ if not is_imm:
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
offset = prev_loc.value
- self.mc.PUSH([r.ip.value], cond=cond)
- pushed = True
- if not check_imm_arg(offset):
- self.mc.gen_load_int(r.ip.value, offset, cond=cond)
- self.mc.ADD_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond)
- else:
- self.mc.ADD_ri(r.ip.value, r.fp.value, offset, cond=cond)
- self.mc.VLDR(loc.value, r.ip.value, cond=cond)
- if pushed:
+ is_imm = check_imm_arg(offset)
+ if not is_imm:
+ self.mc.PUSH([r.ip.value], cond=cond)
+ self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.ip)
+ if not is_imm:
self.mc.POP([r.ip.value], cond=cond)
else:
assert 0, 'unsupported case'
@@ -1077,7 +1070,7 @@
if loc.is_vfp_reg():
self.mc.PUSH([r.ip.value], cond=cond)
self.mc.gen_load_int(r.ip.value, prev_loc.getint(), cond=cond)
- self.mc.VLDR(loc.value, r.ip.value, cond=cond)
+ self.load_reg(self.mc, loc, r.ip, 0, cond=cond)
self.mc.POP([r.ip.value], cond=cond)
elif loc.is_stack():
self.regalloc_push(r.vfp_ip)
@@ -1094,15 +1087,13 @@
assert loc.type == FLOAT, 'trying to store to an \
incompatible location from a float register'
# spill vfp register
- self.mc.PUSH([r.ip.value], cond=cond)
offset = loc.value
- if not check_imm_arg(offset):
- self.mc.gen_load_int(r.ip.value, offset, cond=cond)
- self.mc.ADD_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond)
- else:
- self.mc.ADD_ri(r.ip.value, r.fp.value, offset, cond=cond)
- self.mc.VSTR(prev_loc.value, r.ip.value, cond=cond)
- self.mc.POP([r.ip.value], cond=cond)
+ is_imm = check_imm_arg(offset)
+ if not is_imm:
+ self.mc.PUSH([r.ip.value], cond=cond)
+ self.store_reg(self.mc, prev_loc, r.fp, offset, cond=cond)
+ if not is_imm:
+ self.mc.POP([r.ip.value], cond=cond)
else:
assert 0, 'unsupported case'
@@ -1162,7 +1153,7 @@
elif vfp_loc.is_stack():
# move from two core registers to a float stack location
offset = vfp_loc.value
- if not check_imm_arg(offset, size=0xFFF):
+ if not check_imm_arg(offset + WORD, size=0xFFF):
self.mc.PUSH([r.ip.value], cond=cond)
self.mc.gen_load_int(r.ip.value, offset, cond=cond)
self.mc.STR_rr(reg1.value, r.fp.value, r.ip.value, cond=cond)
@@ -1170,7 +1161,6 @@
self.mc.STR_rr(reg2.value, r.fp.value, r.ip.value, cond=cond)
self.mc.POP([r.ip.value], cond=cond)
else:
- assert 0, 'verify this code'
self.mc.STR_ri(reg1.value, r.fp.value, imm=offset, cond=cond)
self.mc.STR_ri(reg2.value, r.fp.value,
imm=offset + WORD, cond=cond)
diff --git a/rpython/jit/backend/arm/test/test_regalloc_mov.py
b/rpython/jit/backend/arm/test/test_regalloc_mov.py
--- a/rpython/jit/backend/arm/test/test_regalloc_mov.py
+++ b/rpython/jit/backend/arm/test/test_regalloc_mov.py
@@ -43,11 +43,11 @@
def stack(i, **kwargs):
- return StackLocation(i, get_fp_offset(i), **kwargs)
+ return StackLocation(i, get_fp_offset(0, i), **kwargs)
def stack_float(i, **kwargs):
- return StackLocation(i, get_fp_offset(i + 1), type=FLOAT)
+ return StackLocation(i, get_fp_offset(0, i + 1), type=FLOAT)
def imm_float(value):
@@ -100,7 +100,7 @@
expected = [
mi('PUSH', [lr.value], cond=AL),
mi('gen_load_int', lr.value, 100, cond=AL),
- mi('STR_ri', lr.value, fp.value, imm=-s.value, cond=AL),
+ mi('STR_ri', lr.value, fp.value, imm=s.value, cond=AL),
mi('POP', [lr.value], cond=AL)]
self.mov(val, s, expected)
@@ -110,7 +110,7 @@
expected = [
mi('PUSH', [lr.value], cond=AL),
mi('gen_load_int', lr.value, 65536, cond=AL),
- mi('STR_ri', lr.value, fp.value, imm=-s.value, cond=AL),
+ mi('STR_ri', lr.value, fp.value, imm=s.value, cond=AL),
mi('POP', [lr.value], cond=AL)]
self.mov(val, s, expected)
@@ -121,7 +121,7 @@
expected = [mi('PUSH', [lr.value], cond=AL),
mi('gen_load_int', lr.value, 100, cond=AL),
mi('PUSH', [ip.value], cond=AL),
- mi('gen_load_int', ip.value, -s.value, cond=AL),
+ mi('gen_load_int', ip.value, s.value, cond=AL),
mi('STR_rr', lr.value, fp.value, ip.value, cond=AL),
mi('POP', [ip.value], cond=AL),
mi('POP', [lr.value], cond=AL)]
@@ -133,7 +133,7 @@
expected = [mi('PUSH', [lr.value], cond=AL),
mi('gen_load_int', lr.value, 65536, cond=AL),
mi('PUSH', [ip.value], cond=AL),
- mi('gen_load_int', ip.value, -s.value, cond=AL),
+ mi('gen_load_int', ip.value, s.value, cond=AL),
mi('STR_rr', lr.value, fp.value, ip.value, cond=AL),
mi('POP', [ip.value], cond=AL),
mi('POP', [lr.value], cond=AL)]
@@ -148,14 +148,14 @@
def test_mov_reg_to_stack(self):
s = stack(10)
r6 = r(6)
- expected = [mi('STR_ri', r6.value, fp.value, imm=-s.value, cond=AL)]
+ expected = [mi('STR_ri', r6.value, fp.value, imm=s.value, cond=AL)]
self.mov(r6, s, expected)
def test_mov_reg_to_big_stackloc(self):
s = stack(8191)
r6 = r(6)
expected = [mi('PUSH', [ip.value], cond=AL),
- mi('gen_load_int', ip.value, -s.value, cond=AL),
+ mi('gen_load_int', ip.value, s.value, cond=AL),
mi('STR_rr', r6.value, fp.value, ip.value, cond=AL),
mi('POP', [ip.value], cond=AL)]
self.mov(r6, s, expected)
@@ -163,7 +163,7 @@
def test_mov_stack_to_reg(self):
s = stack(10)
r6 = r(6)
- expected = [mi('LDR_ri', r6.value, fp.value, imm=-s.value, cond=AL)]
+ expected = [mi('LDR_ri', r6.value, fp.value, imm=s.value, cond=AL)]
self.mov(s, r6, expected)
def test_mov_big_stackloc_to_reg(self):
@@ -171,7 +171,7 @@
r6 = r(6)
expected = [
mi('PUSH', [lr.value], cond=AL),
- mi('gen_load_int', lr.value, -s.value, cond=AL),
+ mi('gen_load_int', lr.value, s.value, cond=AL),
mi('LDR_rr', r6.value, fp.value, lr.value, cond=AL),
mi('POP', [lr.value], cond=AL)]
self.mov(s, r6, expected)
@@ -182,7 +182,7 @@
expected = [
mi('PUSH', [ip.value], cond=AL),
mi('gen_load_int', ip.value, f.value, cond=AL),
- mi('VLDR', 5, ip.value, cond=AL),
+ mi('VLDR', 5, ip.value, imm=0, cond=AL),
mi('POP', [ip.value], cond=AL)]
self.mov(f, reg, expected)
@@ -195,10 +195,7 @@
def test_mov_vfp_reg_to_stack(self):
reg = vfp(7)
s = stack_float(3)
- expected = [mi('PUSH', [ip.value], cond=AL),
- mi('SUB_ri', ip.value, fp.value, s.value, cond=AL),
- mi('VSTR', reg.value, ip.value, cond=AL),
- mi('POP', [ip.value], cond=AL)]
+ expected = [mi('VSTR', reg.value, fp.value, imm=188, cond=AL)]
self.mov(reg, s, expected)
def test_mov_vfp_reg_to_large_stackloc(self):
@@ -206,7 +203,7 @@
s = stack_float(800)
expected = [mi('PUSH', [ip.value], cond=AL),
mi('gen_load_int', ip.value, s.value, cond=AL),
- mi('SUB_rr', ip.value, fp.value, ip.value, cond=AL),
+ mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL),
mi('VSTR', reg.value, ip.value, cond=AL),
mi('POP', [ip.value], cond=AL)]
self.mov(reg, s, expected)
@@ -214,10 +211,7 @@
def test_mov_stack_to_vfp_reg(self):
reg = vfp(7)
s = stack_float(3)
- expected = [mi('PUSH', [ip.value], cond=AL),
- mi('SUB_ri', ip.value, fp.value, s.value, cond=AL),
- mi('VLDR', reg.value, ip.value, cond=AL),
- mi('POP', [ip.value], cond=AL)]
+ expected = [mi('VLDR', reg.value, fp.value, imm=188, cond=AL)]
self.mov(s, reg, expected)
def test_mov_big_stackloc_to_vfp_reg(self):
@@ -225,7 +219,7 @@
s = stack_float(800)
expected = [mi('PUSH', [ip.value], cond=AL),
mi('gen_load_int', ip.value, s.value, cond=AL),
- mi('SUB_rr', ip.value, fp.value, ip.value, cond=AL),
+ mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL),
mi('VSTR', reg.value, ip.value, cond=AL),
mi('POP', [ip.value], cond=AL)]
self.mov(reg, s, expected)
@@ -304,8 +298,8 @@
r1 = r(1)
r2 = r(2)
e = [
- mi('LDR_ri', r1.value, fp.value, imm=-s.value, cond=AL),
- mi('LDR_ri', r2.value, fp.value, imm=-s.value + WORD, cond=AL)]
+ mi('LDR_ri', r1.value, fp.value, imm=s.value, cond=AL),
+ mi('LDR_ri', r2.value, fp.value, imm=s.value + WORD, cond=AL)]
self.mov(s, r1, r2, e)
def test_from_big_vfp_stack(self):
@@ -314,7 +308,7 @@
r2 = r(2)
e = [
mi('PUSH', [ip.value], cond=AL),
- mi('gen_load_int', ip.value, -s.value, cond=AL),
+ mi('gen_load_int', ip.value, s.value, cond=AL),
mi('LDR_rr', r1.value, fp.value, ip.value, cond=AL),
mi('ADD_ri', ip.value, ip.value, imm=WORD, cond=AL),
mi('LDR_rr', r2.value, fp.value, ip.value, cond=AL),
@@ -361,8 +355,8 @@
r1 = r(1)
r2 = r(2)
e = [
- mi('STR_ri', r1.value, fp.value, imm=-s.value, cond=AL),
- mi('STR_ri', r2.value, fp.value, imm=-s.value + WORD, cond=AL)]
+ mi('STR_ri', r1.value, fp.value, imm=s.value, cond=AL),
+ mi('STR_ri', r2.value, fp.value, imm=s.value + WORD, cond=AL)]
self.mov(r1, r2, s, e)
def test_from_big_vfp_stack(self):
@@ -371,7 +365,7 @@
r2 = r(2)
e = [
mi('PUSH', [ip.value], cond=AL),
- mi('gen_load_int', ip.value, -s.value, cond=AL),
+ mi('gen_load_int', ip.value, s.value, cond=AL),
mi('STR_rr', r1.value, fp.value, ip.value, cond=AL),
mi('ADD_ri', ip.value, ip.value, imm=4, cond=AL),
mi('STR_rr', r2.value, fp.value, ip.value, cond=AL),
@@ -411,7 +405,7 @@
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('VLDR', vfp_ip.value, ip.value, imm=0, cond=AL),
mi('POP', [ip.value], cond=AL),
mi('VPUSH', [vfp_ip.value], cond=AL)
]
@@ -419,7 +413,7 @@
def test_push_stack(self):
s = stack(7)
- e = [mi('LDR_ri', ip.value, fp.value, imm=-s.value, cond=AL),
+ e = [mi('LDR_ri', ip.value, fp.value, imm=s.value, cond=AL),
mi('PUSH', [ip.value], cond=AL)
]
self.push(s, e)
@@ -427,7 +421,7 @@
def test_push_big_stack(self):
s = stack(1025)
e = [mi('PUSH', [lr.value], cond=AL),
- mi('gen_load_int', lr.value, -s.value, cond=AL),
+ mi('gen_load_int', lr.value, s.value, 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)
@@ -442,10 +436,7 @@
def test_push_stack_float(self):
sf = stack_float(4)
e = [
- mi('PUSH', [ip.value], cond=AL),
- mi('SUB_ri', ip.value, fp.value, sf.value, cond=AL),
- mi('VLDR', vfp_ip.value, ip.value, cond=AL),
- mi('POP', [ip.value], cond=AL),
+ mi('VLDR', vfp_ip.value, fp.value, imm=192, cond=AL),
mi('VPUSH', [vfp_ip.value], cond=AL),
]
self.push(sf, e)
@@ -455,7 +446,7 @@
e = [
mi('PUSH', [ip.value], cond=AL),
mi('gen_load_int', ip.value, sf.value, cond=AL),
- mi('SUB_rr', ip.value, fp.value, ip.value, cond=AL),
+ mi('ADD_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),
@@ -482,7 +473,7 @@
s = stack(12)
e = [
mi('POP', [ip.value], cond=AL),
- mi('STR_ri', ip.value, fp.value, imm=-s.value, cond=AL)]
+ mi('STR_ri', ip.value, fp.value, imm=s.value, cond=AL)]
self.pop(s, e)
def test_pop_big_stackloc(self):
@@ -490,7 +481,7 @@
e = [
mi('POP', [ip.value], cond=AL),
mi('PUSH', [lr.value], cond=AL),
- mi('gen_load_int', lr.value, -s.value, cond=AL),
+ mi('gen_load_int', lr.value, s.value, cond=AL),
mi('STR_rr', ip.value, fp.value, lr.value, cond=AL),
mi('POP', [lr.value], cond=AL)
]
@@ -500,10 +491,8 @@
s = stack_float(12)
e = [
mi('VPOP', [vfp_ip.value], cond=AL),
- mi('PUSH', [ip.value], cond=AL),
- mi('SUB_ri', ip.value, fp.value, s.value, cond=AL),
- mi('VSTR', vfp_ip.value, ip.value, cond=AL),
- mi('POP', [ip.value], cond=AL)]
+ mi('VSTR', vfp_ip.value, fp.value, imm=s.value, cond=AL),
+ ]
self.pop(s, e)
def test_pop_big_float_stackloc(self):
@@ -512,7 +501,7 @@
mi('VPOP', [vfp_ip.value], cond=AL),
mi('PUSH', [ip.value], cond=AL),
mi('gen_load_int', ip.value, s.value, cond=AL),
- mi('SUB_rr', ip.value, fp.value, ip.value, cond=AL),
+ mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL),
mi('VSTR', vfp_ip.value, ip.value, cond=AL),
mi('POP', [ip.value], cond=AL)]
self.pop(s, e)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit