[pypy-commit] pypy s390x-backend: assembler recursion: testing if it the assembler can correctly invoke a recursive function. added helper functions to label positions (in the test suite)
plan_rich
noreply at buildbot.pypy.org
Wed Oct 21 20:07:55 EDT 2015
Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80377:aa2a464734d2
Date: 2015-10-21 13:58 +0200
http://bitbucket.org/pypy/pypy/changeset/aa2a464734d2/
Log: assembler recursion: testing if it the assembler can correctly
invoke a recursive function. added helper functions to label
positions (in the test suite)
diff --git a/rpython/jit/backend/zarch/assembler.py b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -50,14 +50,17 @@
return clt.asmmemmgr_blocks
def gen_func_prolog(self):
- self.mc.STMG(reg.r11, reg.r15, loc.addr(-96, reg.sp))
- self.mc.AHI(reg.sp, loc.imm(-96))
+ STACK_FRAME_SIZE = 40
+ self.mc.STMG(reg.r11, reg.r15, loc.addr(-STACK_FRAME_SIZE, reg.sp))
+ self.mc.AHI(reg.sp, loc.imm(-STACK_FRAME_SIZE))
def gen_func_epilog(self):
self.mc.LMG(reg.r11, reg.r15, loc.addr(0, reg.sp))
self.jmpto(reg.r14)
def jmpto(self, register):
+ # TODO, manual says this is a performance killer, there
+ # might be another operation for unconditional JMP?
self.mc.BCR_rr(0xf, register.value)
def _build_failure_recovery(self, exc, withfloats=False):
diff --git a/rpython/jit/backend/zarch/instruction_builder.py b/rpython/jit/backend/zarch/instruction_builder.py
--- a/rpython/jit/backend/zarch/instruction_builder.py
+++ b/rpython/jit/backend/zarch/instruction_builder.py
@@ -76,9 +76,9 @@
| ... | base | length[0:11] | length[12:20] | ... |
+-------------------------------------------------+
"""
- displace = basedisp.displace & 0xfffff
+ displace = basedisp.displace & BIT_MASK_20
base = basedisp.base & 0xf
- byte = displace >> 8 & 0xf | base << 4
+ byte = (displace >> 8) & 0xf | base << 4
mc.writechar(chr(byte))
mc.writechar(chr(displace & 0xff))
byte = displace >> 12 & 0xff
diff --git a/rpython/jit/backend/zarch/instructions.py b/rpython/jit/backend/zarch/instructions.py
--- a/rpython/jit/backend/zarch/instructions.py
+++ b/rpython/jit/backend/zarch/instructions.py
@@ -29,7 +29,7 @@
# and one byte and store it back at the op2 position
'NI': ('si', ['\x94']),
'NIY': ('siy', ['\xEB','\x54']),
- 'NC': ('ssa', ['\xD4']),
+ 'NC': ('ssa', ['\xD4']),
# AND immediate
'NIHH': ('ri_u', ['\xA5', '\x04']),
diff --git a/rpython/jit/backend/zarch/test/test_assembler.py b/rpython/jit/backend/zarch/test/test_assembler.py
--- a/rpython/jit/backend/zarch/test/test_assembler.py
+++ b/rpython/jit/backend/zarch/test/test_assembler.py
@@ -110,4 +110,65 @@
self.a.gen_func_epilog()
assert run_asm(self.a) == 0x0807060504030201
+ def label(self, name, func=False):
+ self.mc.mark_op(name)
+ class ctxmgr(object):
+ def __enter__(_self):
+ if func:
+ self.a.gen_func_prolog()
+ def __exit__(_self, a, b, c):
+ if func:
+ self.a.gen_func_epilog()
+ self.mc.mark_op(name + '.end')
+ return ctxmgr()
+ def patch_branch_imm16(self, base, imm):
+ print "branch to", imm, "base", base, self.cur(), self.pos('lit.end'), self.pos('lit')
+ imm = (imm & 0xffff) >> 1
+ self.mc.overwrite(base, chr((imm >> 8) & 0xFF))
+ self.mc.overwrite(base+1, chr(imm & 0xFF))
+
+ def pos(self, name):
+ return self.mc.ops_offset[name]
+ def cur(self):
+ return self.mc.get_relative_pos()
+
+ def jump_here(self, func, name):
+ if func.__name__ == 'BRAS':
+ self.patch_branch_imm16(self.pos(name)+2, self.cur() - self.pos(name))
+ else:
+ raise NotImplementedError
+
+ def jump_to(self, reg, label):
+ val = (self.pos(label) - self.cur())
+ print "val", val
+ self.mc.BRAS(reg, loc.imm(val))
+
+ def test_stmg(self):
+ self.mc.LGR(reg.r2, reg.r15)
+ self.a.jmpto(reg.r14)
+ print hex(run_asm(self.a))
+
+ def test_recursion(self):
+ with self.label('func', func=True):
+ with self.label('lit'):
+ self.mc.BRAS(reg.r13, loc.imm(0))
+ self.mc.write('\x00\x00\x00\x00\x00\x00\x00\x00')
+ self.jump_here(self.mc.BRAS, 'lit')
+ # recurse X times
+ self.mc.XGR(reg.r2, reg.r2)
+ self.mc.LGHI(reg.r9, loc.imm(15))
+ with self.label('L1'):
+ self.mc.BRAS(reg.r14, loc.imm(0))
+ with self.label('rec', func=True):
+ self.mc.AGR(reg.r2, reg.r9)
+ self.mc.AHI(reg.r9, loc.imm(-1))
+ # if not entered recursion, return from activation record
+ # implicitly generated here by with statement
+ self.mc.BRC(con.GT, loc.imm(self.pos('rec') - self.cur()))
+ self.jump_here(self.mc.BRAS, 'L1')
+ # call rec... recursivly
+ self.jump_to(reg.r14, 'rec')
+ self.a.jmpto(reg.r14)
+ assert run_asm(self.a) == 120
+
More information about the pypy-commit
mailing list