[pypy-svn] r36794 - in pypy/dist/pypy/jit/codegen: ppc test
mwh at codespeak.net
mwh at codespeak.net
Tue Jan 16 12:31:21 CET 2007
Author: mwh
Date: Tue Jan 16 12:31:17 2007
New Revision: 36794
Modified:
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
pypy/dist/pypy/jit/codegen/test/operation_tests.py
Log:
beef up operation_tests considerably.
update ppc/rgenop.py to match (strangely, division is more painful than
shifting, not what i expected).
will run tests on intel on wyvern imminently.
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Tue Jan 16 12:31:17 2007
@@ -48,7 +48,7 @@
def __init__(self, value):
self.value = value
-
+
@specialize.arg(1)
def revealconst(self, T):
if isinstance(T, lltype.Ptr):
@@ -344,11 +344,7 @@
return r
def jump_if_false(self, gv_condition, args_gv):
- #print 'jump_if_false', [id(v) for v in args_gv]
- #print id(self)
- t = self._jump(gv_condition, False, args_gv)
- #print '->', id(t)
- return t
+ return self._jump(gv_condition, False, args_gv)
def jump_if_true(self, gv_condition, args_gv):
return self._jump(gv_condition, True, args_gv)
@@ -569,16 +565,6 @@
self.asm.stw(rFP, rSP, 0)
# branch to "here"
-## def patch_stack_adjustment(self, newsize):
-## if self.stack_adj_addr == 0:
-## return
-## #print "patch_stack_adjustment at:", self.stack_adj_addr, newsize
-## # we build an addi instruction by hand here
-## mc = self.asm.mc
-## self.asm.mc = self.rgenop.ExistingCodeBlock(self.stack_adj_addr, self.stack_adj_addr+4)
-## self.asm.addi(rSCRATCH, rFP, -newsize)
-## self.asm.mc = mc
-
def _arg_op(self, gv_arg, opcode):
gv_result = Var()
self.insns.append(
@@ -702,7 +688,28 @@
commutative=True)
def op_int_floordiv(self, gv_x, gv_y):
- return self._arg_arg_op(gv_x, gv_y, _PPC.divw)
+ # grumble, the powerpc handles division when the signs of x
+ # and y differ the other way to how cpython wants it. this
+ # crawling horror is a branch-free way of computing the right
+ # remainder in all cases. it's probably not optimal.
+
+ # we need to adjust the result iff the remainder is non-zero
+ # and the signs of x and y differ. in the standard-ish PPC
+ # way, we compute boolean values as either all-bits-0 or
+ # all-bits-1 and "and" them together, resulting in either
+ # adding 0 or -1 as needed in the final step.
+
+ gv_dividend = self._arg_arg_op(gv_x, gv_y, _PPC.divw)
+ gv_remainder = self.op_int_sub(gv_x, self.op_int_mul(gv_dividend, gv_y))
+
+ gv_t = self._arg_arg_op(gv_y, gv_x, _PPC.xor)
+ gv_signs_differ = self._arg_imm_op(gv_t, self.rgenop.genconst(31), _PPC.srawi)
+
+ gv_foo = self._arg_imm_op(gv_remainder, self.rgenop.genconst(0), _PPC.subfic)
+ gv_remainder_non_zero = self._arg_arg_op(gv_foo, gv_foo, _PPC.subfe)
+
+ gv_b = self._arg_arg_op(gv_remainder_non_zero, gv_signs_differ, _PPC.and_)
+ return self._arg_arg_op(gv_dividend, gv_b, _PPC.add)
## def op_int_floordiv_zer(self, gv_x, gv_y):
@@ -749,11 +756,30 @@
commutative=True)
def op_int_lshift(self, gv_x, gv_y):
- # could be messy if shift is not in 0 <= ... < 32
- return self._arg_arg_op_with_imm(gv_x, gv_y, _PPC.slw, _PPC.slwi)
+ if gv_y.fits_in_immediate():
+ if abs(gv_y.value) > 32:
+ return self.rgenop.genconst(0)
+ else:
+ return self._arg_imm_op(gv_x, gv_y, _PPC.slwi)
+ gv_abs_y = self.op_int_abs(gv_y)
+ # computing x << y when you don't know y is <=32
+ # (we can assume y >=0 though, i think)
+ # here's the plan:
+ #
+ # z = ngeu(x, 32) (as per cwg)
+ # w = x << y
+ # r = w&z
+ gv_a = self._arg_imm_op(gv_y, self.rgenop.genconst(32), _PPC.subfic)
+ gv_b = self._arg_op(gv_y, _PPC.addze)
+ gv_z = self._arg_arg_op(gv_b, gv_y, _PPC.subf)
+ gv_w = self._arg_arg_op(gv_x, gv_y, _PPC.slw)
+ return self._arg_arg_op(gv_z, gv_w, _PPC.and_)
+
## def op_int_lshift_val(self, gv_x, gv_y):
+
def op_int_rshift(self, gv_x, gv_y):
return self._arg_arg_op_with_imm(gv_x, gv_y, _PPC.sraw, _PPC.srawi)
+
## def op_int_rshift_val(self, gv_x, gv_y):
def op_int_xor(self, gv_x, gv_y):
@@ -866,7 +892,7 @@
def __init__(self):
self.mcs = [] # machine code blocks where no-one is currently writing
- self.keepalive_gc_refs = []
+ self.keepalive_gc_refs = []
# ----------------------------------------------------------------
# the public RGenOp interface
Modified: pypy/dist/pypy/jit/codegen/test/operation_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/operation_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/operation_tests.py Tue Jan 16 12:31:17 2007
@@ -29,88 +29,95 @@
return fp
def test_arithmetic(self):
- for fn in [lambda x, y: x + y,
- lambda x, y: x - y,
- lambda x, y: x * y,
- lambda x, y: x // y,
- lambda x, y: x % y,
- lambda x, y: x << y,
- lambda x, y: x >> y,
- lambda x, y: x ^ y,
- lambda x, y: x & y,
- lambda x, y: x | y,
- lambda x, y: -y,
- lambda x, y: ~y,
- lambda x, y: abs(y),
- lambda x, y: abs(-x),
- ]:
+ for op, fn in [('x + y', lambda x, y: x + y),
+ ('x - y', lambda x, y: x - y),
+ ('x * y', lambda x, y: x * y),
+ ('x // y', lambda x, y: x // y),
+ ('x % y', lambda x, y: x % y),
+ ('x << y', lambda x, y: x << y),
+ ('x >> y', lambda x, y: x >> y),
+ ('x ^ y', lambda x, y: x ^ y),
+ ('x & y', lambda x, y: x & y),
+ ('x | y', lambda x, y: x | y),
+ ('-y', lambda x, y: -y),
+ ('~y', lambda x, y: ~y),
+ ('abs(y)', lambda x, y: abs(y)),
+ ('abs(-x)', lambda x, y: abs(-x)),
+ ]:
fp = self.rgen(fn, [int, int])
+ print op
assert fp(40, 2) == intmask(fn(40, 2))
assert fp(25, 3) == intmask(fn(25, 3))
assert fp(149, 32) == intmask(fn(149, 32))
assert fp(149, 33) == intmask(fn(149, 33))
+ assert fp(149, 150) == intmask(fn(149, 150))
+ assert fp(-40, 2) == intmask(fn(-40, 2))
+ assert fp(-25, 3) == intmask(fn(-25, 3))
+ assert fp(-149, 32) == intmask(fn(-149, 32))
+ assert fp(-149, 33) == intmask(fn(-149, 33))
+ assert fp(-149, 150) == intmask(fn(-149, 150))
def test_comparison(self):
- for fn in [lambda x, y: int(x < y),
- lambda x, y: int(x <= y),
- lambda x, y: int(x == y),
- lambda x, y: int(x != y),
- lambda x, y: int(x > y),
- lambda x, y: int(x >= y),
- ]:
+ for op, fn in [('int(x < y)', lambda x, y: int(x < y)),
+ ('int(x <= y)', lambda x, y: int(x <= y)),
+ ('int(x == y)', lambda x, y: int(x == y)),
+ ('int(x != y)', lambda x, y: int(x != y)),
+ ('int(x > y)', lambda x, y: int(x > y)),
+ ('int(x >= y)', lambda x, y: int(x >= y)),
+ ]:
fp = self.rgen(fn, [int, int])
- assert fp(12, 11) == fn(12, 11)
- assert fp(12, 12) == fn(12, 12)
- assert fp(12, 13) == fn(12, 13)
- assert fp(-12, 11) == fn(-12, 11)
- assert fp(-12, 12) == fn(-12, 12)
- assert fp(-12, 13) == fn(-12, 13)
- assert fp(12, -11) == fn(12, -11)
- assert fp(12, -12) == fn(12, -12)
- assert fp(12, -13) == fn(12, -13)
- assert fp(-12, -11) == fn(-12, -11)
- assert fp(-12, -12) == fn(-12, -12)
- assert fp(-12, -13) == fn(-12, -13)
+ assert fp(12, 11) == fn(12, 11), op
+ assert fp(12, 12) == fn(12, 12), op
+ assert fp(12, 13) == fn(12, 13), op
+ assert fp(-12, 11) == fn(-12, 11), op
+ assert fp(-12, 12) == fn(-12, 12), op
+ assert fp(-12, 13) == fn(-12, 13), op
+ assert fp(12, -11) == fn(12, -11), op
+ assert fp(12, -12) == fn(12, -12), op
+ assert fp(12, -13) == fn(12, -13), op
+ assert fp(-12, -11) == fn(-12, -11), op
+ assert fp(-12, -12) == fn(-12, -12), op
+ assert fp(-12, -13) == fn(-12, -13), op
def test_char_comparison(self):
- for fn in [lambda x, y: int(chr(x) < chr(y)),
- lambda x, y: int(chr(x) <= chr(y)),
- lambda x, y: int(chr(x) == chr(y)),
- lambda x, y: int(chr(x) != chr(y)),
- lambda x, y: int(chr(x) > chr(y)),
- lambda x, y: int(chr(x) >= chr(y)),
- ]:
+ for op, fn in [('int(chr(x) < chr(y))', lambda x, y: int(chr(x) < chr(y))),
+ ('int(chr(x) <= chr(y))', lambda x, y: int(chr(x) <= chr(y))),
+ ('int(chr(x) == chr(y))', lambda x, y: int(chr(x) == chr(y))),
+ ('int(chr(x) != chr(y))', lambda x, y: int(chr(x) != chr(y))),
+ ('int(chr(x) > chr(y))', lambda x, y: int(chr(x) > chr(y))),
+ ('int(chr(x) >= chr(y))', lambda x, y: int(chr(x) >= chr(y))),
+ ]:
fp = self.rgen(fn, [int, int])
- assert fp(12, 11) == fn(12, 11)
- assert fp(12, 12) == fn(12, 12)
- assert fp(12, 13) == fn(12, 13)
- assert fp(182, 11) == fn(182, 11)
- assert fp(182, 12) == fn(182, 12)
- assert fp(182, 13) == fn(182, 13)
- assert fp(12, 181) == fn(12, 181)
- assert fp(12, 182) == fn(12, 182)
- assert fp(12, 183) == fn(12, 183)
- assert fp(182, 181) == fn(182, 181)
- assert fp(182, 182) == fn(182, 182)
- assert fp(182, 183) == fn(182, 183)
+ assert fp(12, 11) == fn(12, 11), op
+ assert fp(12, 12) == fn(12, 12), op
+ assert fp(12, 13) == fn(12, 13), op
+ assert fp(182, 11) == fn(182, 11), op
+ assert fp(182, 12) == fn(182, 12), op
+ assert fp(182, 13) == fn(182, 13), op
+ assert fp(12, 181) == fn(12, 181), op
+ assert fp(12, 182) == fn(12, 182), op
+ assert fp(12, 183) == fn(12, 183), op
+ assert fp(182, 181) == fn(182, 181), op
+ assert fp(182, 182) == fn(182, 182), op
+ assert fp(182, 183) == fn(182, 183), op
def test_unichar_comparison(self):
- for fn in [lambda x, y: int(unichr(x) == unichr(y)),
- lambda x, y: int(unichr(x) != unichr(y)),
- ]:
+ for op, fn in [('int(unichr(x) == unichr(y))', lambda x, y: int(unichr(x) == unichr(y))),
+ ('int(unichr(x) != unichr(y))', lambda x, y: int(unichr(x) != unichr(y))),
+ ]:
fp = self.rgen(fn, [int, int])
- assert fp(12, 11) == fn(12, 11)
- assert fp(12, 12) == fn(12, 12)
- assert fp(12, 13) == fn(12, 13)
- assert fp(53182, 11) == fn(53182, 11)
- assert fp(53182, 12) == fn(53182, 12)
- assert fp(53182, 13) == fn(53182, 13)
- assert fp(12, 53181) == fn(12, 53181)
- assert fp(12, 53182) == fn(12, 53182)
- assert fp(12, 53183) == fn(12, 53183)
- assert fp(53182, 53181) == fn(53182, 53181)
- assert fp(53182, 53182) == fn(53182, 53182)
- assert fp(53182, 53183) == fn(53182, 53183)
+ assert fp(12, 11) == fn(12, 11), op
+ assert fp(12, 12) == fn(12, 12), op
+ assert fp(12, 13) == fn(12, 13), op
+ assert fp(53182, 11) == fn(53182, 11), op
+ assert fp(53182, 12) == fn(53182, 12), op
+ assert fp(53182, 13) == fn(53182, 13), op
+ assert fp(12, 53181) == fn(12, 53181), op
+ assert fp(12, 53182) == fn(12, 53182), op
+ assert fp(12, 53183) == fn(12, 53183), op
+ assert fp(53182, 53181) == fn(53182, 53181), op
+ assert fp(53182, 53182) == fn(53182, 53182), op
+ assert fp(53182, 53183) == fn(53182, 53183), op
def test_char_array(self):
A = lltype.GcArray(lltype.Char)
@@ -176,51 +183,51 @@
assert res == 5
def test_unsigned(self):
- for fn in [lambda x, y: x + y,
- lambda x, y: x - y,
- lambda x, y: x * y,
- lambda x, y: x // y,
- lambda x, y: x % y,
- lambda x, y: x << y,
- lambda x, y: x >> y,
- lambda x, y: x ^ y,
- lambda x, y: x & y,
- lambda x, y: x | y,
- lambda x, y: -y,
- lambda x, y: ~y,
- ]:
+ for op, fn in [('x + y', lambda x, y: x + y),
+ ('x - y', lambda x, y: x - y),
+ ('x * y', lambda x, y: x * y),
+ ('x // y', lambda x, y: x // y),
+ ('x % y', lambda x, y: x % y),
+ ('x << y', lambda x, y: x << y),
+ ('x >> y', lambda x, y: x >> y),
+ ('x ^ y', lambda x, y: x ^ y),
+ ('x & y', lambda x, y: x & y),
+ ('x | y', lambda x, y: x | y),
+ ('-y', lambda x, y: -y),
+ ('~y', lambda x, y: ~y),
+ ]:
fp = self.rgen(fn, [r_uint, r_uint])
- assert fp(40, 2) == fn(40, 2)
- assert fp(25, 3) == fn(25, 3)
+ assert fp(40, 2) == fn(40, 2), op
+ assert fp(25, 3) == fn(25, 3), op
def test_float_arithmetic(self):
- for fn in [lambda x, y: x + y,
- lambda x, y: x - y,
- lambda x, y: x * y,
- lambda x, y: x / y,
- #lambda x, y: x % y, #not used?
- lambda x, y: -y,
- #lambda x, y: ~y, #TypeError: bad operand type for unary ~
- lambda x, y: abs(y),
- lambda x, y: abs(-x),
- ]:
+ for op, fn in [('x + y', lambda x, y: x + y),
+ ('x - y', lambda x, y: x - y),
+ ('x * y', lambda x, y: x * y),
+ ('x / y', lambda x, y: x / y),
+ #('x % y', lambda x, y: x % y), #not used?
+ ('-y', lambda x, y: -y),
+ #('~y', lambda x, y: ~y), #TypeError: bad operand type for unary ~
+ ('abs(y)', lambda x, y: abs(y)),
+ ('abs(-x)', lambda x, y: abs(-x)),
+ ]:
fp = self.rgen(fn, [float, float], float)
- assert fp(40.0, 2.0) == fn(40.0, 2.0)
- assert fp(25.125, 1.5) == fn(25.125, 1.5)
+ assert fp(40.0, 2.0) == fn(40.0, 2.0), op
+ assert fp(25.125, 1.5) == fn(25.125, 1.5), op
def test_float_pow(self): #harder test for llvm
- for fn in [lambda x, y: x ** y, #not supported in llvm backend
- ]:
+ for op, fn in [('x ** y', lambda x, y: x ** y), #not supported in llvm backend
+ ]:
fp = self.rgen(fn, [float, float], float)
- assert fp(40.0, 2.0) == fn(40.0, 2.0)
- assert fp(25.125, 1.5) == fn(25.125, 1.5)
+ assert fp(40.0, 2.0) == fn(40.0, 2.0), op
+ assert fp(25.125, 1.5) == fn(25.125, 1.5), op
def test_float_cast(self): #because of different rettype
- for fn in [lambda x: bool(x),
- lambda x: bool(x - 2.0),
- ]:
+ for op, fn in [('bool(x)', lambda x: bool(x)),
+ ('bool(2.0 - x)', lambda x: bool(x - 2.0)),
+ ]:
fp = self.rgen(fn, [float], bool)
- assert fp(6.0) == fn(6.0)
- assert fp(2.0) == fn(2.0)
- assert fp(0.0) == fn(0.0)
- assert fp(-2.0) == fn(-2.0)
+ assert fp(6.0) == fn(6.0), op
+ assert fp(2.0) == fn(2.0), op
+ assert fp(0.0) == fn(0.0), op
+ assert fp(-2.0) == fn(-2.0), op
More information about the Pypy-commit
mailing list