[pypy-commit] pypy virtual-arguments: implement int_force_ge_zero
fijal
noreply at buildbot.pypy.org
Fri Jul 20 11:33:41 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: virtual-arguments
Changeset: r56287:cfa030de1f93
Date: 2012-07-20 11:33 +0200
http://bitbucket.org/pypy/pypy/changeset/cfa030de1f93/
Log: implement int_force_ge_zero
diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -1522,6 +1522,7 @@
def do_new_array(arraynum, count):
TYPE = symbolic.Size2Type[arraynum]
+ assert count >= 0 # explode if it's not
x = lltype.malloc(TYPE, count, zero=True)
return cast_to_ptr(x)
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
@@ -1375,6 +1375,11 @@
genop_cast_ptr_to_int = genop_same_as
genop_cast_int_to_ptr = genop_same_as
+ def genop_int_force_ge_zero(self, op, arglocs, resloc):
+ self.mc.TEST(arglocs[0], arglocs[0])
+ self.mov(imm0, resloc)
+ self.mc.CMOVNS(arglocs[0], resloc)
+
def genop_int_mod(self, op, arglocs, resloc):
if IS_X86_32:
self.mc.CDQ()
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
@@ -1188,6 +1188,12 @@
consider_cast_ptr_to_int = consider_same_as
consider_cast_int_to_ptr = consider_same_as
+ def consider_int_force_ge_zero(self, op):
+ argloc = self.loc(op.getarg(0))
+ resloc = self.force_allocate_reg(op.result, [op.getarg(0)])
+ self.possibly_free_var(op.getarg(0))
+ self.Perform(op, [argloc], resloc)
+
def consider_strlen(self, op):
args = op.getarglist()
base_loc = self.rm.make_sure_var_in_reg(op.getarg(0), args)
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
@@ -548,6 +548,7 @@
# Avoid XCHG because it always implies atomic semantics, which is
# slower and does not pair well for dispatch.
#XCHG = _binaryop('XCHG')
+ CMOVNS = _binaryop('CMOVNS')
PUSH = _unaryop('PUSH')
POP = _unaryop('POP')
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
@@ -530,6 +530,8 @@
NOT_r = insn(rex_w, '\xF7', register(1), '\xD0')
NOT_b = insn(rex_w, '\xF7', orbyte(2<<3), stack_bp(1))
+ CMOVNS_rr = insn(rex_w, '\x0F\x49', register(2, 8), register(1), '\xC0')
+
# ------------------------------ Misc stuff ------------------------------
NOP = insn('\x90')
diff --git a/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py b/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py
--- a/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py
+++ b/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py
@@ -317,7 +317,9 @@
# CALL_j is actually relative, so tricky to test
(instrname == 'CALL' and argmodes == 'j') or
# SET_ir must be tested manually
- (instrname == 'SET' and argmodes == 'ir')
+ (instrname == 'SET' and argmodes == 'ir') or
+ # asm gets CMOVNS args the wrong way
+ (instrname.startswith('CMOV'))
)
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
@@ -477,6 +477,11 @@
@arguments("i", "i", "i", returns="i")
def bhimpl_int_between(a, b, c):
return a <= b < c
+ @arguments("i", returns="i")
+ def bhimpl_int_force_ge_zero(i):
+ if i < 0:
+ return 0
+ return i
@arguments("i", "i", returns="i")
def bhimpl_uint_lt(a, b):
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -222,7 +222,7 @@
'float_neg', 'float_abs',
'cast_ptr_to_int', 'cast_int_to_ptr',
'convert_float_bytes_to_longlong',
- 'convert_longlong_bytes_to_float',
+ 'convert_longlong_bytes_to_float', 'int_force_ge_zero',
]:
exec py.code.Source('''
@arguments("box")
diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -443,6 +443,7 @@
'INT_IS_TRUE/1b',
'INT_NEG/1',
'INT_INVERT/1',
+ 'INT_FORCE_GE_ZERO/1',
#
'SAME_AS/1', # gets a Const or a Box, turns it into another Box
'CAST_PTR_TO_INT/1',
diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py
--- a/pypy/jit/metainterp/test/test_list.py
+++ b/pypy/jit/metainterp/test/test_list.py
@@ -251,6 +251,16 @@
self.meta_interp(f, [10], listops=True)
self.check_resops(new_array=0, call=0)
+ def test_list_mul(self):
+ def f(i):
+ l = [0] * i
+ return len(l)
+
+ r = self.interp_operations(f, [3])
+ assert r == 3
+ r = self.interp_operations(f, [-1])
+ assert r == 0
+
class TestOOtype(ListTests, OOJitMixin):
pass
More information about the pypy-commit
mailing list