Author: Richard Plangger <planri...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit