[pypy-commit] pypy ppc-jit-backend: Add support for int_force_ge_zero, raw_load, raw_store.

edelsohn noreply at buildbot.pypy.org
Sun Aug 26 21:51:23 CEST 2012


Author: edelsohn
Branch: ppc-jit-backend
Changeset: r56873:314c637d6c26
Date: 2012-08-26 15:50 -0400
http://bitbucket.org/pypy/pypy/changeset/314c637d6c26/

Log:	Add support for int_force_ge_zero, raw_load, raw_store.

diff --git a/pypy/jit/backend/ppc/opassembler.py b/pypy/jit/backend/ppc/opassembler.py
--- a/pypy/jit/backend/ppc/opassembler.py
+++ b/pypy/jit/backend/ppc/opassembler.py
@@ -170,6 +170,17 @@
         l0, res = arglocs
         self.mc.not_(res.value, l0.value)
 
+    def emit_int_force_ge_zero(self, op, arglocs, regalloc):
+        arg, res = arglocs
+        with scratch_reg(self.mc):
+            self.mc.nor(r.SCRATCH.value, arg.value, arg.value)
+            if IS_PPC_32:
+                self.mc.srawi(r.SCRATCH.value, r.SCRATCH.value, 31)
+            else:
+                # sradi (scratch, scratch, 63)
+                self.mc.sradi(r.SCRATCH.value, r.SCRATCH.value, 1, 31)
+            self.mc.and_(res.value, arg.value, r.SCRATCH.value)
+
 class FloatOpAssembler(object):
     _mixin_ = True
 
@@ -739,6 +750,26 @@
 
     emit_setarrayitem_raw = emit_setarrayitem_gc
 
+    def _write_to_mem(self, value_loc, base_loc, ofs_loc, scale):
+        if scale.value == 3:
+            if value_loc.is_fp_reg():
+                self.mc.stfdx(value_loc.value, base_loc.value, ofs_loc.value)
+            else:
+                self.mc.stdx(value_loc.value, base_loc.value, ofs_loc.value)
+        elif scale.value == 2:
+            self.mc.stwx(value_loc.value, base_loc.value, ofs_loc.value)
+        elif scale.value == 1:
+            self.mc.sthx(value_loc.value, base_loc.value, ofs_loc.value)
+        elif scale.value == 0:
+            self.mc.stbx(value_loc.value, base_loc.value, ofs_loc.value)
+        else:
+            assert 0
+
+    def emit_raw_store(self, op, arglocs, regalloc):
+        value_loc, base_loc, ofs_loc, scale, ofs = arglocs
+        assert ofs_loc.is_reg()
+        self._write_to_mem(value_loc, base_loc, ofs_loc, scale)
+
     def emit_getarrayitem_gc(self, op, arglocs, regalloc):
         res, base_loc, ofs_loc, scratch_loc, scale, ofs = arglocs
         assert ofs_loc.is_reg()
@@ -781,6 +812,34 @@
     emit_getarrayitem_raw = emit_getarrayitem_gc
     emit_getarrayitem_gc_pure = emit_getarrayitem_gc
 
+    def _load_from_mem(self, res_loc, base_loc, ofs_loc, scale, signed=False):
+        if scale.value == 3:
+            if res_loc.is_fp_reg():
+                self.mc.lfdx(res_loc.value, base_loc.value, ofs_loc.value)
+            else:
+                self.mc.ldx(res_loc.value, base_loc.value, ofs_loc.value)
+        elif scale.value == 2:
+            self.mc.lwzx(res_loc.value, base_loc.value, ofs_loc.value)
+            if signed:
+                self.mc.extsw(res_loc.value, res_loc.value)
+        elif scale.value == 1:
+            self.mc.lhzx(res_loc.value, base_loc.value, ofs_loc.value)
+            if signed:
+                self.mc.extsh(res_loc.value, res_loc.value)
+        elif scale.value == 0:
+            self.mc.lbzx(res_loc.value, base_loc.value, ofs_loc.value)
+            if signed:
+                self.mc.extsb(res_loc.value, res_loc.value)
+        else:
+            assert 0
+
+    def emit_raw_load(self, op, arglocs, regalloc):
+        res_loc, base_loc, ofs_loc, scale, ofs = arglocs
+        assert ofs_loc.is_reg()
+        # no base offset
+        assert ofs.value == 0
+        signed = op.getdescr().is_item_signed()
+        self._load_from_mem(res_loc, base_loc, ofs_loc, scale, signed)
 
 class StrOpAssembler(object):
 
diff --git a/pypy/jit/backend/ppc/regalloc.py b/pypy/jit/backend/ppc/regalloc.py
--- a/pypy/jit/backend/ppc/regalloc.py
+++ b/pypy/jit/backend/ppc/regalloc.py
@@ -484,6 +484,11 @@
     prepare_guard_float_ge = prepare_float_op(guard=True,
                             float_result=False, name='prepare_guard_float_ge')
 
+    def prepare_int_force_ge_zero(self, op):
+        argloc = self._ensure_value_is_boxed(op.getarg(0))
+        resloc = self.force_allocate_reg(op.result, [op.getarg(0)])
+        return [argloc, resloc]
+
     def prepare_math_sqrt(self, op):
         loc = self._ensure_value_is_boxed(op.getarg(1))
         self.possibly_free_vars_for_op(op)
@@ -759,6 +764,7 @@
         self.possibly_free_var(op.result)
         return [base_loc, index_loc, result_loc, ofs_loc, imm(ofs),
                                     imm(itemsize), imm(fieldsize)]
+
     prepare_getinteriorfield_raw = prepare_getinteriorfield_gc
 
     def prepare_setinteriorfield_gc(self, op):
@@ -775,6 +781,7 @@
             self.assembler.load(ofs_loc, imm(ofs))
         return [base_loc, index_loc, value_loc, ofs_loc, imm(ofs),
                                         imm(itemsize), imm(fieldsize)]
+
     prepare_setinteriorfield_raw = prepare_setinteriorfield_gc
 
     def prepare_arraylen_gc(self, op):
@@ -798,8 +805,19 @@
         scratch_loc = self.rm.get_scratch_reg(INT, args)
         assert _check_imm_arg(ofs)
         return [value_loc, base_loc, ofs_loc, scratch_loc, imm(scale), imm(ofs)]
+
     prepare_setarrayitem_raw = prepare_setarrayitem_gc
 
+    def prepare_raw_store(self, op):
+        size, ofs, _ = unpack_arraydescr(op.getdescr())
+        scale = get_scale(size)
+        args = op.getarglist()
+        base_loc = self._ensure_value_is_boxed(args[0], args)
+        ofs_loc = self._ensure_value_is_boxed(args[1], args)
+        value_loc = self._ensure_value_is_boxed(args[2], args)
+        assert _check_imm_arg(ofs)
+        return [value_loc, base_loc, ofs_loc, imm(scale), imm(ofs)]
+
     def prepare_getarrayitem_gc(self, op):
         boxes = op.getarglist()
         size, ofs, _ = unpack_arraydescr(op.getdescr())
@@ -816,6 +834,18 @@
     prepare_getarrayitem_raw = prepare_getarrayitem_gc
     prepare_getarrayitem_gc_pure = prepare_getarrayitem_gc
 
+    def prepare_raw_load(self, op):
+        boxes = op.getarglist()
+        size, ofs, _ = unpack_arraydescr(op.getdescr())
+        scale = get_scale(size)
+        base_loc = self._ensure_value_is_boxed(boxes[0], boxes)
+        ofs_loc = self._ensure_value_is_boxed(boxes[1], boxes)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
+        res = self.force_allocate_reg(op.result)
+        assert _check_imm_arg(ofs)
+        return [res, base_loc, ofs_loc, imm(scale), imm(ofs)]
+
     def prepare_strlen(self, op):
         args = op.getarglist()
         l0 = self._ensure_value_is_boxed(op.getarg(0))


More information about the pypy-commit mailing list