[pypy-commit] pypy s390x-backend: logical division for ufloor_div, added some methods for to get two registers next to each other from the reg alloc (not yet complete)
plan_rich
noreply at buildbot.pypy.org
Wed Nov 11 09:46:05 EST 2015
Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80633:6db64d28c955
Date: 2015-11-11 13:08 +0100
http://bitbucket.org/pypy/pypy/changeset/6db64d28c955/
Log: logical division for ufloor_div, added some methods for to get two
registers next to each other from the reg alloc (not yet complete)
started to write a test to explicitly stress division and
multiplication
diff --git a/rpython/jit/backend/zarch/helper/regalloc.py b/rpython/jit/backend/zarch/helper/regalloc.py
--- a/rpython/jit/backend/zarch/helper/regalloc.py
+++ b/rpython/jit/backend/zarch/helper/regalloc.py
@@ -41,21 +41,20 @@
def prepare_int_div(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
- l0,lr = self.ensure_even_odd_pair(a0)
+ lr,lq = self.ensure_even_odd_pair(a0)
l1 = self.ensure_reg(a1)
- xxx
- self.force_result_in_reg(op, a0)
+ self.force_result_in_odd_reg(op, a0)
self.free_op_vars()
- return [l0, l1]
+ return [lr, lq, l1]
def prepare_int_mod(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
- l0,lr = self.ensure_even_odd_pair(a0)
+ lr,lq = self.ensure_even_odd_pair(a0)
l1 = self.ensure_reg(a1)
- self.force_arg_to_(op, a0)
+ self.force_result_in_even_reg(op, a0)
self.free_op_vars()
- return [l0, l1]
+ return [lr, lq, l1]
def prepare_int_sub(self, op):
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
@@ -27,6 +27,9 @@
# div/mod
'DSGR': ('rre', ['\xB9','\x0D'], 'eo,r'),
'DSG': ('rxy', ['\xE3','\x0D'], 'eo,bidl'),
+ 'DLGR': ('rre', ['\xB9','\x97'], 'eo,r'),
+ 'DLG': ('rxy', ['\xE3','\x87'], 'eo,bidl'),
+
# there is no immidiate divide
diff --git a/rpython/jit/backend/zarch/locations.py b/rpython/jit/backend/zarch/locations.py
--- a/rpython/jit/backend/zarch/locations.py
+++ b/rpython/jit/backend/zarch/locations.py
@@ -48,6 +48,12 @@
def is_reg(self):
return True
+ def is_even(self):
+ return self.value % 2 == 0
+
+ def is_odd(self):
+ return self.value % 2 == 1
+
def as_key(self): # 0 <= as_key <= 15
return self.value
diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py
--- a/rpython/jit/backend/zarch/opassembler.py
+++ b/rpython/jit/backend/zarch/opassembler.py
@@ -10,7 +10,7 @@
def emit_int_add(self, op, arglocs, regalloc):
l0, l1 = arglocs
if l1.is_imm():
- self.mc.AGHI(l0, l1)
+ self.mc.AGFI(l0, l1)
elif l1.is_in_pool():
self.mc.AG(l0, l1)
else:
@@ -19,11 +19,37 @@
def emit_int_mul(self, op, arglocs, regalloc):
l0, l1 = arglocs
if l1.is_imm():
- self.mc.AGHI(l0, l1)
- elif l1.is_in_pool():
- self.mc.AG(l0, l1)
+ self.mc.MSFI(l0, l1)
+ if l1.is_in_pool():
+ self.mc.MSG(l0, l1)
else:
- self.mc.AGR(l0, l1)
+ self.mc.MSGR(l0, l1)
+
+ def emit_int_floordiv(self, op, arglocs, regalloc):
+ lr, lq, l1 = arglocs # lr == remainer, lq == quotient
+ # when entering the function lr contains the dividend
+ # after this operation either lr or lq is used further
+ assert not l1.is_imm() , "imm divider not supported"
+ # remainer is always a even register r0, r2, ... , r14
+ assert lr.is_even()
+ assert lq.is_odd()
+ if l1.is_in_pool():
+ self.mc.DSG(lr, l1)
+ else:
+ self.mc.DSGR(lr, l1)
+
+ def emit_int_ufloordiv(self, op, arglocs, regalloc):
+ lr, lq, l1 = arglocs # lr == remainer, lq == quotient
+ # when entering the function lr contains the dividend
+ # after this operation either lr or lq is used further
+ assert not l1.is_imm() , "imm divider not supported"
+ # remainer is always a even register r0, r2, ... , r14
+ assert lr.is_even()
+ assert lq.is_odd()
+ if l1.is_in_pool():
+ self.mc.DLG(lr, l1)
+ else:
+ self.mc.DLGR(lr, l1)
def emit_int_sub(self, op, arglocs, regalloc):
l0, l1 = arglocs
diff --git a/rpython/jit/backend/zarch/regalloc.py b/rpython/jit/backend/zarch/regalloc.py
--- a/rpython/jit/backend/zarch/regalloc.py
+++ b/rpython/jit/backend/zarch/regalloc.py
@@ -135,6 +135,30 @@
self.temp_boxes.append(box)
return reg
+ def ensure_even_odd_pair(self, var):
+ self.rm.ensure__check_type(var)
+ prev_loc = self.loc(var, must_exist=True)
+ if prev_loc is self.frame_reg:
+ return prev_loc
+ if not prev_loc.is_even():
+ # we need to move it ...
+ pass
+ loc = self.force_allocate_reg(v, forbidden_vars, selected_reg,
+ need_lower_byte=need_lower_byte)
+ if prev_loc is not loc:
+ self.assembler.regalloc_mov(prev_loc, loc)
+ return loc
+
+
+ def force_result_in_even_reg(self, result_v, loc, forbidden_vars=[]):
+ xxx
+ pass
+
+ def force_result_in_odd_reg(self, result_v, loc, forbidden_vars=[]):
+ xxx
+ pass
+
+
class ZARCHFrameManager(FrameManager):
def __init__(self, base_ofs):
diff --git a/rpython/jit/backend/zarch/test/test_runner.py b/rpython/jit/backend/zarch/test/test_runner.py
--- a/rpython/jit/backend/zarch/test/test_runner.py
+++ b/rpython/jit/backend/zarch/test/test_runner.py
@@ -23,3 +23,20 @@
cpu = CPU_S390_64(rtyper=None, stats=FakeStats())
cpu.setup_once()
return cpu
+
+ @py.test.parametrize('input,opcode,result',
+ [30,'i1 = int_mul(i0, 2)',60]
+ )
+ def test_int_arithmetic_and_logic(self, input, opcode, result):
+ loop = parse("""
+ [i0]
+ {opcode}
+ finish(i1, descr=faildescr)
+ """.format(opcode=opcode),namespace={"faildescr": BasicFinalDescr(1)})
+ looptoken = JitCellToken()
+ self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+ deadframe = self.cpu.execute_token(looptoken, input)
+ fail = self.cpu.get_latest_descr(deadframe)
+ res = self.cpu.get_int_value(deadframe, 0)
+ assert res == result
+ assert fail.identifier == 1
More information about the pypy-commit
mailing list