[pypy-svn] r25107 - pypy/dist/pypy/translator/cli
antocuni at codespeak.net
antocuni at codespeak.net
Wed Mar 29 15:53:50 CEST 2006
Author: antocuni
Date: Wed Mar 29 15:53:43 2006
New Revision: 25107
Added:
pypy/dist/pypy/translator/cli/metavm.py (contents, props changed)
Modified:
pypy/dist/pypy/translator/cli/function.py
pypy/dist/pypy/translator/cli/opcodes.py
Log:
More opcodes refactoring
Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py (original)
+++ pypy/dist/pypy/translator/cli/function.py Wed Mar 29 15:53:43 2006
@@ -2,7 +2,8 @@
from pypy.rpython.lltypesystem.lltype import Void
from pypy.translator.cli.option import getoption
from pypy.translator.cli import cts
-from pypy.translator.cli.opcodes import opcodes, MicroInstruction, PushAllArgs, Literal
+from pypy.translator.cli.opcodes import opcodes
+from pypy.translator.cli.metavm import InstructionList, Generator
from pypy.tool.ansi_print import ansi_log
import py
@@ -18,7 +19,7 @@
pass
-class Function(Node):
+class Function(Node, Generator):
def __init__(self, graph, is_entrypoint = False):
self.graph = graph
self.is_entrypoint = is_entrypoint
@@ -179,13 +180,10 @@
return 'block%s' % self.blocknum[block]
def _render_op(self, op):
- opname = op.opname
-
- cli_opcode = opcodes.get(opname, None)
- if cli_opcode is not None:
- self._render_cli_opcode(cli_opcode, op)
- elif opname == 'direct_call':
- self._call(op)
+ instr_list = opcodes.get(op.opname, None)
+ if instr_list is not None:
+ assert isinstance(instr_list, InstructionList)
+ instr_list.render(self, op)
else:
if getoption('nostop'):
log.WARNING('Unknown opcode: %s ' % op)
@@ -193,35 +191,17 @@
else:
assert False, 'Unknown opcode: %s ' % op
- def _render_cli_opcode(self, cli_opcode, op):
- if type(cli_opcode) is str:
- instructions = [PushAllArgs(), cli_opcode]
- else:
- instructions = cli_opcode
-
- for instr in instructions:
- if type(instr) is str:
- instr = Literal(instr)
-
- assert isinstance(instr, MicroInstruction)
- instr.render(self, op)
-
- self.store(op.result)
-
+ # following methods belongs to the Generator interface
- def _call(self, op):
- func_name = cts.graph_to_signature(op.args[0].value.graph)
-
- # push parameters
- for func_arg in op.args[1:]:
- self.load(func_arg)
-
- self.ilasm.call(func_name)
- self.store(op.result)
+ def function_name(self, graph):
+ return cts.graph_to_signature(graph)
def emit(self, instr, *args):
self.ilasm.opcode(instr, *args)
+ def call(self, func_name):
+ self.ilasm.call(func_name)
+
def load(self, v):
if isinstance(v, flowmodel.Variable):
if v.name in self.argset:
Added: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/metavm.py Wed Mar 29 15:53:43 2006
@@ -0,0 +1,63 @@
+class Generator(object):
+ def function_name(self, graph):
+ pass
+
+ def emit(self, instr, *args):
+ pass
+
+ def call(self, func_name):
+ pass
+
+ def load(self, v):
+ pass
+
+ def store(self, v):
+ pass
+
+
+class InstructionList(list):
+ def render(self, generator, op):
+ for instr in self:
+ if isinstance(instr, MicroInstruction):
+ instr.render(generator, op)
+ else:
+ generator.emit(instr)
+
+
+class MicroInstruction(object):
+ def render(self, generator, op):
+ pass
+
+
+class PushArg(MicroInstruction):
+ def __init__(self, n):
+ self.n = n
+
+ def render(self, generator, op):
+ generator.load(op.args[self.n])
+
+
+class _PushAllArgs(MicroInstruction):
+ def render(self, generator, op):
+ for arg in op.args:
+ generator.load(arg)
+
+
+class _StoreResult(MicroInstruction):
+ def render(self, generator, op):
+ generator.store(op.result)
+
+
+class _Call(MicroInstruction):
+ def render(self, generator, op):
+ func_name = generator.function_name(op.args[0].value.graph)
+
+ # push parameters
+ for func_arg in op.args[1:]:
+ generator.load(func_arg)
+
+ generator.call(func_name)
+
+PushAllArgs = _PushAllArgs()
+StoreResult = _StoreResult()
+Call = _Call()
Modified: pypy/dist/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/cli/opcodes.py (original)
+++ pypy/dist/pypy/translator/cli/opcodes.py Wed Mar 29 15:53:43 2006
@@ -1,42 +1,17 @@
-class MicroInstruction(object):
- def render(self, generator, op):
- pass
-
-
-class Literal(MicroInstruction):
- def __init__(self, instr):
- self.instr = instr
-
- def render(self, generator, op):
- generator.emit(self.instr)
-
-
-class PushArg(MicroInstruction):
- def __init__(self, n):
- self.n = n
-
- def render(self, generator, op):
- generator.load(op.args[self.n])
-
-
-class PushAllArgs(MicroInstruction):
- def render(self, generator, op):
- for arg in op.args:
- generator.load(arg)
-
+from pypy.translator.cli.metavm import PushArg, PushAllArgs, StoreResult, Call, InstructionList
# some useful instruction patterns
Not = ['ldc.i4.0', 'ceq']
-DoNothing = [PushAllArgs()]
+DoNothing = [PushAllArgs]
def _not(op):
- return [PushAllArgs(), op]+Not
+ return [PushAllArgs, op]+Not
opcodes = {
'same_as': DoNothing, # TODO: does same_as really do nothing else than renaming?
- 'direct_call': None, # for now it's a special case
- 'indirect_call': None, # when it's generated?
+ 'direct_call': [Call],
+ 'indirect_call': None, # when is it generated?
# __________ numeric operations __________
@@ -54,7 +29,7 @@
'int_is_true': DoNothing,
'int_neg': 'neg',
- 'int_neg_ovf': ['ldc.i4.0', PushAllArgs(), 'sub.ovf'],
+ 'int_neg_ovf': ['ldc.i4.0', PushAllArgs, 'sub.ovf'],
'int_abs': None, # TODO
'int_abs_ovf': None, # TODO
'int_invert': 'not',
@@ -124,7 +99,7 @@
'uint_rshift': 'shr.un',
'uint_xor': 'xor',
- 'float_is_true': [PushAllArgs(), 'ldc.r8 0', 'ceq']+Not,
+ 'float_is_true': [PushAllArgs, 'ldc.r8 0', 'ceq']+Not,
'float_neg': 'neg',
'float_abs': None, # TODO
@@ -144,7 +119,7 @@
'float_floor': None, # TODO
'float_fmod': None, # TODO
- 'llong_is_true': [PushAllArgs(), 'ldc.i8 0', 'ceq']+Not,
+ 'llong_is_true': [PushAllArgs, 'ldc.i8 0', 'ceq']+Not,
'llong_neg': 'neg',
'llong_abs': None, # TODO
'llong_invert': 'not',
@@ -163,7 +138,7 @@
'llong_gt': 'cgt',
'llong_ge': _not('clt'),
- 'ullong_is_true': [PushAllArgs(), 'ldc.i8 0', 'ceq']+Not,
+ 'ullong_is_true': [PushAllArgs, 'ldc.i8 0', 'ceq']+Not,
'ullong_neg': None,
'ullong_abs': None, # TODO
'ullong_invert': 'not',
@@ -186,9 +161,9 @@
# 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_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': None,
'cast_unichar_to_int': None,
'cast_int_to_char': None,
@@ -201,3 +176,12 @@
'cast_float_to_uint': 'conv.i4',
'truncate_longlong_to_int': 'conv.i4',
}
+
+for key, value in opcodes.iteritems():
+ if type(value) is str:
+ value = InstructionList([PushAllArgs, value, StoreResult])
+ elif value is not None:
+ value = InstructionList(value + [StoreResult])
+
+ opcodes[key] = value
+
More information about the Pypy-commit
mailing list