[pypy-svn] pypy jit-longlong: LLONG_FROM_TWO_INTS, using the same technique.
arigo
commits-noreply at bitbucket.org
Sun Jan 9 19:35:44 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: jit-longlong
Changeset: r40537:435c1e142cf3
Date: 2011-01-09 19:35 +0100
http://bitbucket.org/pypy/pypy/changeset/435c1e142cf3/
Log: LLONG_FROM_TWO_INTS, using the same technique.
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
@@ -1130,18 +1130,23 @@
self.mc.PUNPCKLDQ_xx(resloc.value, loc2.value)
def genop_llong_from_two_ints(self, op, arglocs, resloc):
- assert isinstance(resloc, StackLoc)
- stackofs = resloc.value
- loc1, loc2 = arglocs
- if isinstance(loc1, ImmedLoc):
- self.mc.MOV_bi(stackofs, loc1.value)
+ assert isinstance(resloc, RegLoc)
+ loc1, loc2, loc3 = arglocs
+ #
+ if isinstance(loc1, ConstFloatLoc):
+ self.mc.MOVSD(resloc, loc1)
else:
- self.mc.MOV_br(stackofs, loc1.value)
- stackofs += 4
- if isinstance(loc2, ImmedLoc):
- self.mc.MOV_bi(stackofs, loc2.value)
- else:
- self.mc.MOV_br(stackofs, loc2.value)
+ assert isinstance(loc1, RegLoc)
+ self.mc.MOVD_xr(resloc.value, loc1.value)
+ #
+ if loc2 is not None:
+ assert isinstance(loc3, RegLoc)
+ if isinstance(loc2, ConstFloatLoc):
+ self.mc.MOVSD(loc3, loc2)
+ else:
+ assert isinstance(loc2, RegLoc)
+ self.mc.MOVD_xr(loc3.value, loc2.value)
+ self.mc.PUNPCKLDQ_xx(resloc.value, loc3.value)
def genop_new_with_vtable(self, op, arglocs, result_loc):
assert result_loc is eax
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
@@ -20,6 +20,7 @@
from pypy.jit.backend.llsupport.regalloc import FrameManager, RegisterManager,\
TempBox
from pypy.jit.backend.x86.arch import WORD, FRAME_FIXED_SIZE, IS_X86_32, IS_X86_64
+from pypy.rlib.rarithmetic import r_longlong, r_uint
class X86RegisterManager(RegisterManager):
@@ -646,17 +647,18 @@
self.PerformLLong(op, [loc1], loc0)
self.xrm.possibly_free_var(op.getarg(1))
+ def _loc_of_const_longlong(self, value64):
+ from pypy.rlib.longlong2float import longlong2float
+ c = ConstFloat(longlong2float(value64))
+ return self.xrm.convert_to_imm(c)
+
def _consider_llong_from_int(self, op):
assert IS_X86_32
loc0 = self.xrm.force_allocate_reg(op.result)
box = op.getarg(1)
if isinstance(box, ConstInt):
- from pypy.rlib.longlong2float import longlong2float
- from pypy.rlib.rarithmetic import r_longlong
- value = r_longlong(box.value)
- c = ConstFloat(longlong2float(value))
- loc1 = self.xrm.convert_to_imm(c)
- loc2 = loc0 # unused
+ loc1 = self._loc_of_const_longlong(r_longlong(box.value))
+ loc2 = None # unused
else:
# requires the argument to be in eax, and trash edx.
loc1 = self.rm.make_sure_var_in_reg(box, selected_reg=eax)
@@ -670,12 +672,36 @@
self.rm.possibly_free_var(box)
def _consider_llong_from_two_ints(self, op):
- # requires the arguments to be in registers or immediates.
- # requires the result to be in the stack.
- loc0 = self.fm.loc(op.result)
- loc1 = self.rm.make_sure_var_in_reg(op.getarg(1))
- loc2 = self.rm.make_sure_var_in_reg(op.getarg(2), [op.getarg(1)])
- self.PerformLLong(op, [loc1, loc2], loc0)
+ assert IS_X86_32
+ box1 = op.getarg(1)
+ box2 = op.getarg(2)
+ loc0 = self.xrm.force_allocate_reg(op.result)
+ #
+ if isinstance(box1, ConstInt) and isinstance(box2, ConstInt):
+ # all-constant arguments: load the result value in a single step
+ value64 = r_longlong(box2.value) << 32
+ value64 |= r_longlong(r_uint(box1.value))
+ loc1 = self._loc_of_const_longlong(value64)
+ loc2 = None # unused
+ loc3 = None # unused
+ #
+ else:
+ tmpxvar = TempBox()
+ loc3 = self.xrm.force_allocate_reg(tmpxvar, [op.result])
+ self.xrm.possibly_free_var(tmpxvar)
+ #
+ if isinstance(box1, ConstInt):
+ loc1 = self._loc_of_const_longlong(r_longlong(box1.value))
+ else:
+ loc1 = self.rm.make_sure_var_in_reg(box1, imm_fine=False)
+ #
+ if isinstance(box2, ConstInt):
+ loc2 = self._loc_of_const_longlong(r_longlong(box2.value))
+ else:
+ loc2 = self.rm.make_sure_var_in_reg(box2, [box1],
+ imm_fine=False)
+ #
+ self.PerformLLong(op, [loc1, loc2, loc3], loc0)
self.rm.possibly_free_vars_for_op(op)
def _call(self, op, arglocs, force_store=[], guard_not_forced_op=None):
More information about the Pypy-commit
mailing list