[pypy-svn] r51334 - in pypy/dist/pypy: jit/codegen/cli translator/cli
antocuni at codespeak.net
antocuni at codespeak.net
Fri Feb 8 15:07:02 CET 2008
Author: antocuni
Date: Fri Feb 8 15:07:00 2008
New Revision: 51334
Modified:
pypy/dist/pypy/jit/codegen/cli/operation.py
pypy/dist/pypy/jit/codegen/cli/rgenop.py
pypy/dist/pypy/translator/cli/opcodes.py
Log:
the cli jit and non jit backends now share the descriptions of the
various opcodes. Not all of those are yet supported by the jit
backend though.
Modified: pypy/dist/pypy/jit/codegen/cli/operation.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/cli/operation.py (original)
+++ pypy/dist/pypy/jit/codegen/cli/operation.py Fri Feb 8 15:07:00 2008
@@ -1,5 +1,8 @@
+import py
+from pypy.rlib.objectmodel import specialize
from pypy.rpython.ootypesystem import ootype
from pypy.translator.cli.dotnet import CLR, typeof
+from pypy.translator.cli import opcodes as cli_opcodes
System = CLR.System
OpCodes = System.Reflection.Emit.OpCodes
@@ -21,15 +24,11 @@
def emit(self):
raise NotImplementedError
+ def pushAllArgs(self):
+ raise NotImplementedError
-class Branch(Operation):
-
- def __init__(self, il, label):
- self.il = il
- self.label = label
-
- def emit(self):
- self.il.emit(OpCodes.Br, self.label)
+ def storeResult(self):
+ self.gv_res().store(self.il)
class UnaryOp(Operation):
@@ -37,41 +36,8 @@
self.il = il
self.gv_x = gv_x
-
-class AbstractBranchIf(UnaryOp):
-
- def __init__(self, il, gv_x, label):
- self.il = il
- self.gv_x = gv_x
- self.label = label
-
- def restype(self):
- return None
-
- def emit(self):
- self.il.emit(self.getOpCode(), self.label)
-
- def getOpCode(self):
- return OpCodes.Brtrue
-
-
-class BrFalse(AbstractBranchIf):
-
- def getOpCode(self):
- return OpCodes.Brfalse
-
-class BrTrue(AbstractBranchIf):
-
- def getOpCode(self):
- return OpCodes.Brtrue
-
-
-class SameAs(UnaryOp):
- def emit(self):
- gv_res = self.gv_res()
+ def pushAllArgs(self):
self.gv_x.load(self.il)
- self.gv_res().store(self.il)
-
class BinaryOp(Operation):
def __init__(self, il, gv_x, gv_y):
@@ -79,28 +45,77 @@
self.gv_x = gv_x
self.gv_y = gv_y
- def emit(self):
+ def pushAllArgs(self):
self.gv_x.load(self.il)
self.gv_y.load(self.il)
+
+ def emit(self):
+ self.pushAllArgs()
self.il.Emit(self.getOpCode())
- self.gv_res().store(self.il)
+ self.storeResult()
def getOpCode(self):
raise NotImplementedError
-class Add(BinaryOp):
- def getOpCode(self):
- return OpCodes.Add
+class SameAs(UnaryOp):
+ def emit(self):
+ gv_res = self.gv_res()
+ self.gv_x.load(self.il)
+ self.gv_res().store(self.il)
-class Sub(BinaryOp):
- def getOpCode(self):
- return OpCodes.Sub
+def opcode2attrname(opcode):
+ parts = map(str.capitalize, opcode.split('.'))
+ return '_'.join(parts)
+
+def is_comparison(opname):
+ suffixes = '_lt _le _eq _ne _gt _ge'.split()
+ for suffix in suffixes:
+ if opname.endswith(suffix):
+ return True
+ return False
-class Gt(BinaryOp):
+def fillops(ops, baseclass):
+ # monkey-patch boolean operations
def restype(self):
return typeof(System.Boolean)
- def getOpCode(self):
- return OpCodes.Cgt
+ out = {}
+ for opname, value in ops.iteritems():
+ if isinstance(value, str):
+ attrname = opcode2attrname(value)
+ source = py.code.Source("""
+ class %(opname)s (%(baseclass)s):
+ def getOpCode(self):
+ return OpCodes.%(attrname)s
+ """ % locals())
+ code = source.compile()
+ exec code in globals(), out
+ if is_comparison(opname):
+ out[opname].restype = restype
+ elif value is cli_opcodes.DoNothing:
+ out[opname] = SameAs
+ else:
+ pass # XXX: handle remaining ops
+ return out
+
+UNARYOPS = fillops(cli_opcodes.unary_ops, "UnaryOp")
+BINARYOPS = fillops(cli_opcodes.binary_ops, "BinaryOp")
+
+ at specialize.memo()
+def getopclass1(opname):
+ try:
+ return UNARYOPS[opname]
+ except KeyError:
+ raise MissingBackendOperation(opname)
+
+ at specialize.memo()
+def getopclass2(opname):
+ try:
+ return BINARYOPS[opname]
+ except KeyError:
+ raise MissingBackendOperation(opname)
+
+class MissingBackendOperation(Exception):
+ pass
Modified: pypy/dist/pypy/jit/codegen/cli/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/cli/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/cli/rgenop.py Fri Feb 8 15:07:00 2008
@@ -178,14 +178,8 @@
@specialize.arg(1)
def genop2(self, opname, gv_arg1, gv_arg2):
- if opname == 'int_add':
- op = ops.Add(self.il, gv_arg1, gv_arg2)
- elif opname == 'int_sub':
- op = ops.Sub(self.il, gv_arg1, gv_arg2)
- elif opname == 'int_gt':
- op = ops.Gt(self.il, gv_arg1, gv_arg2)
- else:
- assert False
+ opcls = ops.getopclass2(opname)
+ op = opcls(self.il, gv_arg1, gv_arg2)
self.emit(op)
return op.gv_res()
Modified: pypy/dist/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/cli/opcodes.py (original)
+++ pypy/dist/pypy/translator/cli/opcodes.py Fri Feb 8 15:07:00 2008
@@ -26,9 +26,8 @@
mapping = [('[mscorlib]System.DivideByZeroException', 'exceptions.ZeroDivisionError')]
return [MapException(op, mapping)]
-
-opcodes = {
- # __________ object oriented operations __________
+# __________ object oriented & misc operations __________
+misc_ops = {
'new': [New],
'runtimenew': [RuntimeNew],
'oosetfield': [SetField],
@@ -57,7 +56,6 @@
'ooparse_float': [PushAllArgs, 'call float64 [pypylib]pypy.runtime.Utils::OOParseFloat(string)'],
'oonewcustomdict': [NewCustomDict],
- 'same_as': DoNothing,
'hint': [PushArg(0), StoreResult],
'direct_call': [Call],
'indirect_call': [IndirectCall],
@@ -68,11 +66,65 @@
'resume_point': Ignore,
'debug_assert': Ignore,
'keepalive': Ignore,
+ 'is_early_constant': [PushPrimitive(ootype.Bool, False)],
+ }
- # __________ numeric operations __________
+# __________ numeric operations __________
+unary_ops = {
+ 'same_as': DoNothing,
+
'bool_not': [PushAllArgs]+Not,
+ 'int_is_true': [PushAllArgs, 'ldc.i4.0', 'cgt.un'],
+ 'int_neg': 'neg',
+ 'int_neg_ovf': _check_ovf(['ldc.i4.0', PushAllArgs, 'sub.ovf', StoreResult]),
+ 'int_abs': _abs('int32'),
+ 'int_abs_ovf': _check_ovf(_abs('int32')),
+ 'int_invert': 'not',
+
+ 'uint_is_true': [PushAllArgs, 'ldc.i4.0', 'cgt.un'],
+ 'uint_invert': 'not',
+
+ 'float_is_true': [PushAllArgs, 'ldc.r8 0', 'ceq']+Not,
+ 'float_neg': 'neg',
+ 'float_abs': _abs('float64'),
+
+ 'llong_is_true': [PushAllArgs, 'ldc.i8 0', 'cgt.un'],
+ 'llong_neg': 'neg',
+ 'llong_neg_ovf': _check_ovf(['ldc.i8 0', PushAllArgs, 'sub.ovf', StoreResult]),
+ 'llong_abs': _abs('int64'),
+ 'llong_abs_ovf': _check_ovf(_abs('int64')),
+ 'llong_invert': 'not',
+
+ 'ullong_is_true': [PushAllArgs, 'ldc.i8 0', 'cgt.un'],
+ 'ullong_invert': 'not',
+
+ # when casting from bool we want that every truth value is casted
+ # to 1: we can't simply DoNothing, because the CLI stack could
+ # contains a truth value not equal to 1, so we should use the !=0
+ # trick.
+ 'cast_bool_to_int': [PushAllArgs, 'ldc.i4.0', 'ceq']+Not,
+ 'cast_bool_to_uint': [PushAllArgs, 'ldc.i4.0', 'ceq']+Not,
+ 'cast_bool_to_float': [PushAllArgs, 'ldc.i4 0', 'ceq']+Not+['conv.r8'],
+ 'cast_char_to_int': DoNothing,
+ 'cast_unichar_to_int': DoNothing,
+ 'cast_int_to_char': DoNothing,
+ 'cast_int_to_unichar': DoNothing,
+ 'cast_int_to_uint': DoNothing,
+ 'cast_int_to_float': 'conv.r8',
+ 'cast_int_to_longlong': 'conv.i8',
+ 'cast_uint_to_int': DoNothing,
+ 'cast_uint_to_float': [PushAllArgs, 'conv.u8', 'conv.r8'],
+ 'cast_float_to_int': 'conv.i4',
+ 'cast_float_to_uint': 'conv.u4',
+ 'cast_longlong_to_float': 'conv.r8',
+ 'cast_float_to_longlong': 'conv.i8',
+ 'cast_primitive': [PushAllArgs, CastPrimitive],
+ 'truncate_longlong_to_int': 'conv.i4',
+ }
+
+binary_ops = {
'char_lt': 'clt',
'char_le': _not('cgt'),
'char_eq': 'ceq',
@@ -83,13 +135,6 @@
'unichar_eq': 'ceq',
'unichar_ne': _not('ceq'),
- 'int_is_true': [PushAllArgs, 'ldc.i4.0', 'cgt.un'],
- 'int_neg': 'neg',
- 'int_neg_ovf': _check_ovf(['ldc.i4.0', PushAllArgs, 'sub.ovf', StoreResult]),
- 'int_abs': _abs('int32'),
- 'int_abs_ovf': _check_ovf(_abs('int32')),
- 'int_invert': 'not',
-
'int_add': 'add',
'int_sub': 'sub',
'int_mul': 'mul',
@@ -133,9 +178,6 @@
'int_mod_ovf_zer': _check_zer('rem'),
'int_mod_zer': _check_zer('rem'),
- 'uint_is_true': [PushAllArgs, 'ldc.i4.0', 'cgt.un'],
- 'uint_invert': 'not',
-
'uint_add': 'add',
'uint_sub': 'sub',
'uint_mul': 'mul',
@@ -155,10 +197,6 @@
'uint_rshift': 'shr.un',
'uint_xor': 'xor',
- 'float_is_true': [PushAllArgs, 'ldc.r8 0', 'ceq']+Not,
- 'float_neg': 'neg',
- 'float_abs': _abs('float64'),
-
'float_add': 'add',
'float_sub': 'sub',
'float_mul': 'mul',
@@ -169,13 +207,6 @@
'float_ne': _not('ceq'),
'float_gt': 'cgt',
'float_ge': _not('clt'),
-
- 'llong_is_true': [PushAllArgs, 'ldc.i8 0', 'cgt.un'],
- 'llong_neg': 'neg',
- 'llong_neg_ovf': _check_ovf(['ldc.i8 0', PushAllArgs, 'sub.ovf', StoreResult]),
- 'llong_abs': _abs('int64'),
- 'llong_abs_ovf': _check_ovf(_abs('int64')),
- 'llong_invert': 'not',
'llong_add': 'add',
'llong_sub': 'sub',
@@ -198,9 +229,6 @@
'llong_rshift': [PushAllArgs, 'conv.i4', 'shr'],
'llong_xor': 'xor',
- 'ullong_is_true': [PushAllArgs, 'ldc.i8 0', 'cgt.un'],
- 'ullong_invert': 'not',
-
'ullong_add': 'add',
'ullong_sub': 'sub',
'ullong_mul': 'mul',
@@ -216,32 +244,12 @@
'ullong_ge': _not('clt.un'),
'ullong_lshift': [PushAllArgs, 'conv.u4', 'shl'],
'ullong_rshift': [PushAllArgs, 'conv.i4', 'shr'],
-
- # when casting from bool we want that every truth value is casted
- # to 1: we can't simply DoNothing, because the CLI stack could
- # contains a truth value not equal to 1, so we should use the !=0
- # trick.
- 'cast_bool_to_int': [PushAllArgs, 'ldc.i4.0', 'ceq']+Not,
- 'cast_bool_to_uint': [PushAllArgs, 'ldc.i4.0', 'ceq']+Not,
- 'cast_bool_to_float': [PushAllArgs, 'ldc.i4 0', 'ceq']+Not+['conv.r8'],
- 'cast_char_to_int': DoNothing,
- 'cast_unichar_to_int': DoNothing,
- 'cast_int_to_char': DoNothing,
- 'cast_int_to_unichar': DoNothing,
- 'cast_int_to_uint': DoNothing,
- 'cast_int_to_float': 'conv.r8',
- 'cast_int_to_longlong': 'conv.i8',
- 'cast_uint_to_int': DoNothing,
- 'cast_uint_to_float': [PushAllArgs, 'conv.u8', 'conv.r8'],
- 'cast_float_to_int': 'conv.i4',
- 'cast_float_to_uint': 'conv.u4',
- 'cast_longlong_to_float': 'conv.r8',
- 'cast_float_to_longlong': 'conv.i8',
- 'cast_primitive': [PushAllArgs, CastPrimitive],
- 'truncate_longlong_to_int': 'conv.i4',
- 'is_early_constant': [PushPrimitive(ootype.Bool, False)]
}
+opcodes = misc_ops.copy()
+opcodes.update(unary_ops)
+opcodes.update(binary_ops)
+
for key, value in opcodes.iteritems():
if type(value) is str:
value = InstructionList([PushAllArgs, value, StoreResult])
@@ -252,4 +260,3 @@
opcodes[key] = value
-
More information about the pypy-svn
mailing list