[pypy-svn] pypy jit-longlong: These are the two easiest long long operations: add and sub,

arigo commits-noreply at bitbucket.org
Sat Jan 8 18:19:56 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: jit-longlong
Changeset: r40498:0ce72bff8f90
Date: 2011-01-08 18:19 +0100
http://bitbucket.org/pypy/pypy/changeset/0ce72bff8f90/

Log:	These are the two easiest long long operations: add and sub, which
	directly correspond to PADDQ and PSUBQ between the xmm registers.

diff --git a/pypy/jit/backend/x86/rx86.py b/pypy/jit/backend/x86/rx86.py
--- a/pypy/jit/backend/x86/rx86.py
+++ b/pypy/jit/backend/x86/rx86.py
@@ -545,6 +545,9 @@
     CVTTSD2SI_rx = xmminsn('\xF2', rex_w, '\x0F\x2C', register(1, 8), register(2), '\xC0')
     CVTTSD2SI_rb = xmminsn('\xF2', rex_w, '\x0F\x2C', register(1, 8), stack_bp(2))
 
+    PADDQ_xx = xmminsn('\x66', rex_nw, '\x0F\xD4', register(1, 8), register(2), '\xC0')
+    PSUBQ_xx = xmminsn('\x66', rex_nw, '\x0F\xFB', register(1, 8), register(2), '\xC0')
+
     # ------------------------------------------------------------
 
 Conditions = {

diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -37,6 +37,7 @@
 from pypy.rlib import rgc
 from pypy.jit.backend.x86.jump import remap_frame_layout
 from pypy.jit.metainterp.history import ConstInt, BoxInt
+from pypy.jit.codewriter.effectinfo import EffectInfo
 
 # darwin requires the stack to be 16 bytes aligned on calls. Same for gcc 4.5.0,
 # better safe than sorry
@@ -767,6 +768,11 @@
     def regalloc_perform_discard(self, op, arglocs):
         genop_discard_list[op.getopnum()](self, op, arglocs)
 
+    def regalloc_perform_llong(self, op, arglocs, resloc):
+        effectinfo = op.getdescr().get_extra_info()
+        oopspecindex = effectinfo.oopspecindex
+        genop_llong_list[oopspecindex](self, op, arglocs, resloc)
+
     def regalloc_perform_with_guard(self, op, guard_op, faillocs,
                                     arglocs, resloc, current_depths):
         faildescr = guard_op.getdescr()
@@ -980,6 +986,8 @@
     genop_float_sub = _binaryop('SUBSD')
     genop_float_mul = _binaryop('MULSD', True)
     genop_float_truediv = _binaryop('DIVSD')
+    genop_llong_add = _binaryop("PADDQ", True)
+    genop_llong_sub = _binaryop("PSUBQ", True)
 
     genop_int_lt = _cmpop("L", "G")
     genop_int_le = _cmpop("LE", "GE")
@@ -1938,6 +1946,7 @@
         
 genop_discard_list = [Assembler386.not_implemented_op_discard] * rop._LAST
 genop_list = [Assembler386.not_implemented_op] * rop._LAST
+genop_llong_list = {}
 genop_guard_list = [Assembler386.not_implemented_op_guard] * rop._LAST
 
 for name, value in Assembler386.__dict__.iteritems():
@@ -1949,6 +1958,10 @@
         opname = name[len('genop_guard_'):]
         num = getattr(rop, opname.upper())
         genop_guard_list[num] = value
+    elif name.startswith('genop_llong_'):
+        opname = name[len('genop_llong_'):]
+        num = getattr(EffectInfo, 'OS_LLONG_' + opname.upper())
+        genop_llong_list[num] = value
     elif name.startswith('genop_'):
         opname = name[len('genop_'):]
         num = getattr(rop, opname.upper())

diff --git a/pypy/jit/backend/x86/regloc.py b/pypy/jit/backend/x86/regloc.py
--- a/pypy/jit/backend/x86/regloc.py
+++ b/pypy/jit/backend/x86/regloc.py
@@ -457,6 +457,9 @@
     ANDPD = _binaryop('ANDPD')
     XORPD = _binaryop('XORPD')
 
+    PADDQ = _binaryop('PADDQ')
+    PSUBQ = _binaryop('PSUBQ')
+
     CALL = _relative_unaryop('CALL')
     JMP = _relative_unaryop('JMP')
 

diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -13,6 +13,7 @@
 from pypy.jit.backend.llsupport import symbolic
 from pypy.jit.backend.x86.jump import remap_frame_layout
 from pypy.jit.codewriter import heaptracker
+from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.metainterp.resoperation import rop
 from pypy.jit.backend.llsupport.descr import BaseFieldDescr, BaseArrayDescr
 from pypy.jit.backend.llsupport.descr import BaseCallDescr, BaseSizeDescr
@@ -281,6 +282,11 @@
             self.assembler.dump('%s <- %s(%s)' % (result_loc, op, arglocs))
         self.assembler.regalloc_perform(op, arglocs, result_loc)
 
+    def PerformLLong(self, op, arglocs, result_loc):
+        if not we_are_translated():
+            self.assembler.dump('%s <- %s(%s)' % (result_loc, op, arglocs))
+        self.assembler.regalloc_perform_llong(op, arglocs, result_loc)
+
     def locs_for_fail(self, guard_op):
         return [self.loc(v) for v in guard_op.getfailargs()]
 
@@ -624,6 +630,15 @@
         self.Perform(op, [loc0], loc1)
         self.rm.possibly_free_var(op.getarg(0))
 
+    def _consider_llong_binop(self, op):
+        # must force both arguments into registers, because we don't
+        # know if they will be suitably aligned
+        args = [op.getarg(1), op.getarg(2)]
+        loc1 = self.xrm.make_sure_var_in_reg(args[1], imm_fine=False)
+        loc0 = self.xrm.force_result_in_reg(op.result, args[0], args)
+        self.PerformLLong(op, [loc0, loc1], loc0)
+        self.xrm.possibly_free_vars(args)
+
     def _call(self, op, arglocs, force_store=[], guard_not_forced_op=None):
         save_all_regs = guard_not_forced_op is not None
         self.rm.before_call(force_store, save_all_regs=save_all_regs)
@@ -655,6 +670,13 @@
                    guard_not_forced_op=guard_not_forced_op)
 
     def consider_call(self, op):
+        effectinfo = op.getdescr().get_extra_info()
+        if effectinfo is not None:
+            oopspecindex = effectinfo.oopspecindex
+            if oopspecindex in (EffectInfo.OS_LLONG_ADD,
+                                EffectInfo.OS_LLONG_SUB):
+                return self._consider_llong_binop(op)
+        #
         self._consider_call(op)
 
     def consider_call_may_force(self, op, guard_op):


More information about the Pypy-commit mailing list