[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-commit mailing list