[pypy-commit] pypy int-tag-untag-as-operations: (arigo, cfbolz): implement int_tag, int_tag_ovf and int_untag in the x86 backend
cfbolz
noreply at buildbot.pypy.org
Mon Oct 24 12:41:57 CEST 2011
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: int-tag-untag-as-operations
Changeset: r48370:30319db8738f
Date: 2011-10-24 12:41 +0200
http://bitbucket.org/pypy/pypy/changeset/30319db8738f/
Log: (arigo, cfbolz): implement int_tag, int_tag_ovf and int_untag in the
x86 backend
diff --git a/pypy/jit/backend/test/test_random.py b/pypy/jit/backend/test/test_random.py
--- a/pypy/jit/backend/test/test_random.py
+++ b/pypy/jit/backend/test/test_random.py
@@ -293,6 +293,9 @@
class BinaryOvfOperation(AbstractOvfOperation, BinaryOperation):
pass
+class UnaryOvfOperation(AbstractOvfOperation, UnaryOperation):
+ pass
+
class AbstractFloatOperation(AbstractOperation):
def filter(self, builder):
if not builder.cpu.supports_floats:
@@ -421,6 +424,8 @@
for _op in [rop.INT_NEG,
rop.INT_INVERT,
+ rop.INT_TAG,
+ rop.INT_UNTAG,
]:
OPERATIONS.append(UnaryOperation(_op))
@@ -433,6 +438,7 @@
rop.INT_MUL_OVF,
]:
OPERATIONS.append(BinaryOvfOperation(_op))
+OPERATIONS.append(UnaryOvfOperation(rop.INT_TAG_OVF))
for _op in [rop.FLOAT_ADD,
rop.FLOAT_SUB,
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
@@ -1311,7 +1311,19 @@
genop_guard_float_eq = _cmpop_guard_float("E", "E", "NE","NE")
genop_guard_float_gt = _cmpop_guard_float("A", "B", "BE","AE")
genop_guard_float_ge = _cmpop_guard_float("AE","BE", "B", "A")
-
+
+
+ def genop_int_tag(self, op, arglocs, resloc):
+ loc, = arglocs
+ assert isinstance(loc, RegLoc)
+ assert isinstance(resloc, RegLoc)
+ # res = loc + (loc << 0) + 1
+ self.mc.LEA_ra(resloc.value, (loc.value, loc.value, 0, 1))
+
+ def genop_int_untag(self, op, arglocs, resloc):
+ loc, = arglocs
+ self.mc.SAR(loc, imm1)
+
def genop_math_sqrt(self, op, arglocs, resloc):
self.mc.SQRTSD(arglocs[0], resloc)
@@ -1730,6 +1742,11 @@
self.genop_int_mul(op, arglocs, result_loc)
return self._gen_guard_overflow(guard_op, guard_token)
+ def genop_guard_int_tag_ovf(self, op, guard_op, guard_token, arglocs, result_loc):
+ self.mc.STC()
+ self.mc.ADC(arglocs[0], arglocs[0])
+ return self._gen_guard_overflow(guard_op, guard_token)
+
def genop_guard_guard_false(self, ign_1, guard_op, guard_token, locs, ign_2):
loc = locs[0]
self.mc.TEST(loc, loc)
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
@@ -579,11 +579,22 @@
consider_int_sub_ovf = _consider_binop_with_guard
consider_int_add_ovf = _consider_binop_with_guard
+ def consider_int_tag_ovf(self, op, guard_op):
+ loc = self.rm.force_result_in_reg(op.result, op.getarg(0))
+ self.perform_with_guard(op, guard_op, [loc], loc)
+
+ def consider_int_tag(self, op):
+ loc = self.rm.make_sure_var_in_reg(op.getarg(0))
+ self.rm.possibly_free_vars_for_op(op)
+ res = self.rm.force_allocate_reg(op.result)
+ self.Perform(op, [loc], res)
+
def consider_int_neg(self, op):
res = self.rm.force_result_in_reg(op.result, op.getarg(0))
self.Perform(op, [res], res)
consider_int_invert = consider_int_neg
+ consider_int_untag = consider_int_neg
def consider_int_lshift(self, op):
if isinstance(op.getarg(1), Const):
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
@@ -487,6 +487,7 @@
BTS = _binaryop('BTS')
ADD = _binaryop('ADD')
+ ADC = _binaryop('ADC')
SUB = _binaryop('SUB')
IMUL = _binaryop('IMUL')
NEG = _unaryop('NEG')
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
@@ -470,6 +470,7 @@
# ------------------------------ Arithmetic ------------------------------
ADD_ri,ADD_rr,ADD_rb,_,_,ADD_rm,ADD_rj,_,_ = common_modes(0)
+ ADC_ri,ADC_rr,ADC_rb,_,_,ADC_rm,ADC_rj,_,_ = common_modes(2)
OR_ri, OR_rr, OR_rb, _,_,OR_rm, OR_rj, _,_ = common_modes(1)
AND_ri,AND_rr,AND_rb,_,_,AND_rm,AND_rj,_,_ = common_modes(4)
SUB_ri,SUB_rr,SUB_rb,_,_,SUB_rm,SUB_rj,SUB_ji8,SUB_mi8 = common_modes(5)
@@ -577,6 +578,8 @@
FSTPL_b = insn('\xDD', orbyte(3<<3), stack_bp(1)) # rffi.DOUBLE ('as' wants L??)
FSTPS_s = insn('\xD9', orbyte(3<<3), stack_sp(1)) # lltype.SingleFloat
+ STC = insn('\xF9')
+
# ------------------------------ Random mess -----------------------
RDTSC = insn('\x0F\x31')
diff --git a/pypy/jit/backend/x86/test/test_regalloc.py b/pypy/jit/backend/x86/test/test_regalloc.py
--- a/pypy/jit/backend/x86/test/test_regalloc.py
+++ b/pypy/jit/backend/x86/test/test_regalloc.py
@@ -660,3 +660,27 @@
self.run(loop)
assert self.getint(0) == 29
+ def test_int_untag(self):
+ ops = '''
+ [i0]
+ i1 = int_untag(i0)
+ finish(i1)
+ '''
+ self.interpret(ops, [1129])
+ assert self.getint(0) == 564
+ self.interpret(ops, [-1129])
+ assert self.getint(0) == -565
+
+ def test_int_tag(self):
+ ops = '''
+ [i0]
+ i1 = int_tag(i0)
+ i2 = int_tag(i0)
+ finish(i1, i2)
+ '''
+ self.interpret(ops, [1129])
+ assert self.getint(0) == 1129 * 2 + 1
+ assert self.getint(1) == 1129 * 2 + 1
+ self.interpret(ops, [-1129])
+ assert self.getint(0) == -1129 * 2 + 1
+ assert self.getint(1) == -1129 * 2 + 1
diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -452,7 +452,7 @@
return a >> 1
@arguments("i", returns="i")
def bhimpl_int_tag(a):
- return (a << 1) + 1
+ return intmask(a << 1) + 1 # mostly there for test_random
@arguments("i", returns="i")
def bhimpl_int_tag_ovf(a):
return ovfcheck(a << 1) + 1
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -3435,10 +3435,7 @@
return sa
res = self.meta_interp(f, [16])
assert res == f(16)
-
-
-
-class TestLLtype(BaseLLtypeTests, LLJitMixin):
+
def test_tagged(self):
from pypy.rlib.objectmodel import UnboxedValue
class Base(object):
@@ -3523,3 +3520,8 @@
assert x == -42
x = self.interp_operations(f, [1000, 1], taggedpointers=True)
assert x == 999
+
+
+
+class TestLLtype(BaseLLtypeTests, LLJitMixin):
+ pass # should be empty
More information about the pypy-commit
mailing list