Author: hager <sven.ha...@uni-duesseldorf.de> Branch: ppc-jit-backend Changeset: r48211:eabb2cbd47c9 Date: 2011-10-18 18:06 +0200 http://bitbucket.org/pypy/pypy/changeset/eabb2cbd47c9/
Log: Implemented comparison operations and refactored existing code regarding comparison operations. diff --git a/pypy/jit/backend/ppc/ppcgen/condition.py b/pypy/jit/backend/ppc/ppcgen/condition.py --- a/pypy/jit/backend/ppc/ppcgen/condition.py +++ b/pypy/jit/backend/ppc/ppcgen/condition.py @@ -5,4 +5,9 @@ EQ = 12 GE = 33 +U_LT = 50 +U_LE = 60 +U_GT = 70 +U_GE = 80 + opposites = {LE: GT, NE: EQ, LT: GE, GE: LT, EQ: NE, GT: LE} diff --git a/pypy/jit/backend/ppc/ppcgen/helper/assembler.py b/pypy/jit/backend/ppc/ppcgen/helper/assembler.py --- a/pypy/jit/backend/ppc/ppcgen/helper/assembler.py +++ b/pypy/jit/backend/ppc/ppcgen/helper/assembler.py @@ -1,27 +1,49 @@ import pypy.jit.backend.ppc.ppcgen.condition as c from pypy.rlib.rarithmetic import r_uint, r_longlong, intmask -def gen_emit_cmp_op(condition): +def gen_emit_cmp_op(condition, signed=True): def f(self, op, arglocs, regalloc): l0, l1, res = arglocs # do the comparison - if l1.is_imm(): - self.mc.cmpwi(0, l0.value, l1.value) + if signed: + if l1.is_imm(): + self.mc.cmpwi(0, l0.value, l1.value) + else: + self.mc.cmpw(0, l0.value, l1.value) + + # After the comparison, place the result + # in the first bit of the CR + if condition == c.LT: + self.mc.cror(0, 0, 0) + elif condition == c.LE: + self.mc.cror(0, 0, 2) + elif condition == c.EQ: + self.mc.cror(0, 2, 2) + elif condition == c.GE: + self.mc.cror(0, 1, 2) + elif condition == c.GT: + self.mc.cror(0, 1, 1) + elif condition == c.NE: + self.mc.cror(0, 0, 1) + else: + assert 0, "condition not known" + else: - self.mc.cmpw(0, l0.value, l1.value) + if l1.is_imm(): + self.mc.cmpli(0, l0.value, l1.value) + else: + self.mc.cmpl(0, l0.value, l1.value) - # After the comparison, place the result - # in the first bit of the CR - if condition == c.LT: - self.mc.cror(0, 0, 0) - elif condition == c.LE: - self.mc.cror(0, 0, 2) - elif condition == c.EQ: - self.mc.cror(0, 2, 2) - elif condition == c.GE: - self.mc.cror(0, 1, 2) - elif condition == c.GT: - self.mc.cror(0, 1, 1) + if condition == c.U_LT: + self.mc.cror(0, 0, 0) + elif condition == c.U_LE: + self.mc.cror(0, 0, 2) + elif condition == c.U_GT: + self.mc.cror(0, 1, 1) + elif condition == c.U_GE: + self.mc.cror(0, 1, 2) + else: + assert 0, "condition not known" resval = res.value # move the content of the CR to resval diff --git a/pypy/jit/backend/ppc/ppcgen/helper/regalloc.py b/pypy/jit/backend/ppc/ppcgen/helper/regalloc.py --- a/pypy/jit/backend/ppc/ppcgen/helper/regalloc.py +++ b/pypy/jit/backend/ppc/ppcgen/helper/regalloc.py @@ -1,7 +1,14 @@ from pypy.jit.metainterp.history import ConstInt -def _check_imm_arg(arg): - return isinstance(arg, ConstInt) +def _check_imm_arg(arg, size=0xFF, allow_zero=True): + if isinstance(arg, ConstInt): + i = arg.getint() + if allow_zero: + lower_bound = i >= 0 + else: + lower_bound = i > 0 + return i <= size and lower_bound + return False def prepare_cmp_op(): def f(self, op): @@ -21,3 +28,45 @@ self.possibly_free_var(op.result) return [l0, l1, res] return f + +def prepare_binary_int_op_with_imm(): + def f(self, op): + boxes = op.getarglist() + b0, b1 = boxes + imm_b0 = _check_imm_arg(b0) + imm_b1 = _check_imm_arg(b1) + if not imm_b0 and imm_b1: + l0, box = self._ensure_value_is_boxed(b0) + l1 = self.make_sure_var_in_reg(b1, [b0]) + boxes.append(box) + elif imm_b0 and not imm_b1: + l0 = self.make_sure_var_in_reg(b0) + l1, box = self._ensure_value_is_boxed(b1, [b0]) + boxes.append(box) + else: + l0, box = self._ensure_value_is_boxed(b0) + boxes.append(box) + l1, box = self._ensure_value_is_boxed(b1, [box]) + boxes.append(box) + locs = [l0, l1] + self.possibly_free_vars(boxes) + res = self.force_allocate_reg(op.result) + return locs + [res] + return f + +def prepare_binary_int_op(): + def f(self, op): + boxes = list(op.getarglist()) + b0, b1 = boxes + + reg1, box = self._ensure_value_is_boxed(b0, forbidden_vars=boxes) + boxes.append(box) + reg2, box = self._ensure_value_is_boxed(b1, forbidden_vars=boxes) + boxes.append(box) + + self.possibly_free_vars(boxes) + self.possibly_free_vars_for_op(op) + res = self.force_allocate_reg(op.result) + self.possibly_free_var(op.result) + return [reg1, reg2, res] + return f diff --git a/pypy/jit/backend/ppc/ppcgen/opassembler.py b/pypy/jit/backend/ppc/ppcgen/opassembler.py --- a/pypy/jit/backend/ppc/ppcgen/opassembler.py +++ b/pypy/jit/backend/ppc/ppcgen/opassembler.py @@ -112,7 +112,17 @@ else: self.mc.divdu(res.value, l0.value, l1.value) - emit_int_le = gen_emit_cmp_op(c.LE) + emit_int_le = gen_emit_cmp_op(c.LE) + emit_int_lt = gen_emit_cmp_op(c.LT) + emit_int_gt = gen_emit_cmp_op(c.GT) + emit_int_ge = gen_emit_cmp_op(c.GE) + emit_int_eq = gen_emit_cmp_op(c.EQ) + emit_int_ne = gen_emit_cmp_op(c.NE) + + emit_uint_lt = gen_emit_cmp_op(c.U_LT, signed=False) + emit_uint_le = gen_emit_cmp_op(c.U_LE, signed=False) + emit_uint_gt = gen_emit_cmp_op(c.U_GT, signed=False) + emit_uint_ge = gen_emit_cmp_op(c.U_GE, signed=False) def _emit_guard(self, op, arglocs, fcond, save_exc=False, is_guard_not_invalidated=False): diff --git a/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py b/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py --- a/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py +++ b/pypy/jit/backend/ppc/ppcgen/ppc_assembler.py @@ -399,7 +399,7 @@ self._make_prologue(regalloc_head, frame_depth) self.write_pending_failure_recoveries() - loop_start = self.materialize_loop(looptoken, True) + loop_start = self.materialize_loop(looptoken, False) looptoken.ppc_code = loop_start + start_pos self.process_pending_guards(loop_start) self._teardown() diff --git a/pypy/jit/backend/ppc/ppcgen/regalloc.py b/pypy/jit/backend/ppc/ppcgen/regalloc.py --- a/pypy/jit/backend/ppc/ppcgen/regalloc.py +++ b/pypy/jit/backend/ppc/ppcgen/regalloc.py @@ -5,7 +5,9 @@ from pypy.jit.backend.ppc.ppcgen.jump import remap_frame_layout_mixed from pypy.jit.backend.ppc.ppcgen.locations import imm from pypy.jit.backend.ppc.ppcgen.helper.regalloc import (_check_imm_arg, - prepare_cmp_op) + prepare_cmp_op, + prepare_binary_int_op, + prepare_binary_int_op_with_imm) from pypy.jit.metainterp.history import (INT, REF, FLOAT, Const, ConstInt, ConstPtr, LoopToken) from pypy.jit.metainterp.resoperation import rop @@ -175,73 +177,31 @@ # * P R E P A R E O P E R A T I O N S * # ****************************************************** - def prepare_int_add(self, op): - boxes = op.getarglist() - b0, b1 = boxes - imm_b0 = _check_imm_arg(b0) - imm_b1 = _check_imm_arg(b1) - if not imm_b0 and imm_b1: - l0, box = self._ensure_value_is_boxed(b0) - l1 = self.make_sure_var_in_reg(b1, [b0]) - boxes.append(box) - elif imm_b0 and not imm_b1: - l0 = self.make_sure_var_in_reg(b0) - l1, box = self._ensure_value_is_boxed(b1, [b0]) - boxes.append(box) - else: - l0, box = self._ensure_value_is_boxed(b0) - boxes.append(box) - l1, box = self._ensure_value_is_boxed(b1, [box]) - boxes.append(box) - locs = [l0, l1] - self.possibly_free_vars(boxes) - res = self.force_allocate_reg(op.result) - return locs + [res] + prepare_int_add = prepare_binary_int_op_with_imm() + prepare_int_sub = prepare_binary_int_op_with_imm() + prepare_int_floordiv = prepare_binary_int_op_with_imm() - def prepare_int_sub(self, op): - return self.prepare_int_add(op) + prepare_int_mul = prepare_binary_int_op() + prepare_int_mod = prepare_binary_int_op() + prepare_int_and = prepare_binary_int_op() + prepare_int_or = prepare_binary_int_op() + prepare_int_xor = prepare_binary_int_op() + prepare_int_lshift = prepare_binary_int_op() + prepare_int_rshift = prepare_binary_int_op() + prepare_uint_rshift = prepare_binary_int_op() + prepare_uint_floordiv = prepare_binary_int_op() - def prepare_int_floordiv(self, op): - return self.prepare_int_add(op) + prepare_int_le = prepare_cmp_op() + prepare_int_lt = prepare_cmp_op() + prepare_int_ge = prepare_cmp_op() + prepare_int_gt = prepare_cmp_op() + prepare_int_eq = prepare_cmp_op() + prepare_int_ne = prepare_cmp_op() - def prepare_int_mul(self, op): - boxes = list(op.getarglist()) - b0, b1 = boxes - - reg1, box = self._ensure_value_is_boxed(b0, forbidden_vars=boxes) - boxes.append(box) - reg2, box = self._ensure_value_is_boxed(b1, forbidden_vars=boxes) - boxes.append(box) - - self.possibly_free_vars(boxes) - self.possibly_free_vars_for_op(op) - res = self.force_allocate_reg(op.result) - self.possibly_free_var(op.result) - return [reg1, reg2, res] - - def prepare_int_mod(self, op): - return self.prepare_int_mul(op) - - def prepare_int_and(self, op): - return self.prepare_int_mul(op) - - def prepare_int_or(self, op): - return self.prepare_int_mul(op) - - def prepare_int_xor(self, op): - return self.prepare_int_mul(op) - - def prepare_int_lshift(self, op): - return self.prepare_int_mul(op) - - def prepare_int_rshift(self, op): - return self.prepare_int_mul(op) - - def prepare_uint_rshift(self, op): - return self.prepare_int_mul(op) - - def prepare_uint_floordiv(self, op): - return self.prepare_int_mul(op) + prepare_uint_lt = prepare_cmp_op() + prepare_uint_le = prepare_cmp_op() + prepare_uint_gt = prepare_cmp_op() + prepare_uint_ge = prepare_cmp_op() def prepare_finish(self, op): args = [locations.imm(self.frame_manager.frame_depth)] @@ -287,8 +247,6 @@ [], [], None) return [] - prepare_int_le = prepare_cmp_op() - def make_operation_list(): def not_implemented(self, op, *args): raise NotImplementedError, op _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit