[pypy-commit] pypy ppc-jit-backend: Implemented overflow operations.

hager noreply at buildbot.pypy.org
Thu Oct 20 11:02:49 CEST 2011


Author: hager <sven.hager at uni-duesseldorf.de>
Branch: ppc-jit-backend
Changeset: r48257:d2527483c5c3
Date: 2011-10-20 11:02 +0200
http://bitbucket.org/pypy/pypy/changeset/d2527483c5c3/

Log:	Implemented overflow operations.

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
@@ -32,6 +32,10 @@
         else:
             self.mc.add(res.value, l0.value, l1.value)
 
+    def emit_int_add_ovf(self, op, arglocs, regalloc):
+        l0, l1, res = arglocs
+        self.mc.addo(res.value, l0.value, l1.value)
+
     def emit_int_sub(self, op, arglocs, regalloc):
         l0, l1, res = arglocs
         if l0.is_imm():
@@ -42,10 +46,22 @@
         else:
             self.mc.sub(res.value, l0.value, l1.value)
  
+    def emit_int_sub_ovf(self, op, arglocs, regalloc):
+        l0, l1, res = arglocs
+        self.mc.subfo(res.value, l1.value, l0.value)
+
     def emit_int_mul(self, op, arglocs, regalloc):
         reg1, reg2, res = arglocs
         self.mc.mullw(res.value, reg1.value, reg2.value)
 
+    def emit_int_mul_ovf(self, op, arglocs, regalloc):
+        reg1, reg2, res = arglocs
+        self.mc.mullwo(res.value, reg1.value, reg2.value)
+
+    def emit_int_mul_ovf(self, op, arglocs, regalloc):
+        l0, l1, res = arglocs
+        self.mc.mullwo(res.value, l0.value, l1.value)
+
     def emit_int_floordiv(self, op, arglocs, regalloc):
         l0, l1, res = arglocs
         if IS_PPC_32:
@@ -158,6 +174,23 @@
         #                        #      ^^^^ If this condition is met,
         #                        #           then the guard fails.
 
+    # TODO - Evaluate whether this can be done with 
+    #        SO bit instead of OV bit => usage of CR
+    #        instead of XER could be more efficient
+    def _emit_ovf_guard(self, op, arglocs, cond):
+        # move content of XER to GPR
+        self.mc.mfspr(r.r0.value, 1)
+        # shift and mask to get comparison result
+        self.mc.rlwinm(r.r0.value, r.r0.value, 1, 0, 0)
+        self.mc.cmpi(r.r0.value, 0)
+        self._emit_guard(op, arglocs, cond)
+
+    def emit_guard_no_overflow(self, op, arglocs, regalloc):
+        self._emit_ovf_guard(op, arglocs, c.NE)
+
+    def emit_guard_overflow(self, op, arglocs, regalloc):
+        self._emit_ovf_guard(op, arglocs, c.EQ)
+
     def emit_finish(self, op, arglocs, regalloc):
         self.gen_exit_stub(op.getdescr(), op.getarglist(), arglocs)
 
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
@@ -193,6 +193,10 @@
     prepare_uint_rshift = prepare_binary_int_op()
     prepare_uint_floordiv = prepare_binary_int_op()
 
+    prepare_int_add_ovf = prepare_binary_int_op()
+    prepare_int_sub_ovf = prepare_binary_int_op()
+    prepare_int_mul_ovf = prepare_binary_int_op()
+
     prepare_int_neg = prepare_unary_int_op()
     prepare_int_invert = prepare_unary_int_op()
 
@@ -240,6 +244,13 @@
         self.possibly_free_vars(op.getfailargs())
         return args
 
+    def prepare_guard_no_overflow(self, op):
+        locs = self._prepare_guard(op)
+        self.possibly_free_vars(op.getfailargs())
+        return locs
+
+    prepare_guard_overflow = prepare_guard_no_overflow
+
     def prepare_jump(self, op):
         descr = op.getdescr()
         assert isinstance(descr, LoopToken)


More information about the pypy-commit mailing list