[pypy-svn] r18463 - in pypy/dist/pypy/translator/asm: . test
mwh at codespeak.net
mwh at codespeak.net
Wed Oct 12 13:04:53 CEST 2005
Author: mwh
Date: Wed Oct 12 13:04:51 2005
New Revision: 18463
Added:
pypy/dist/pypy/translator/asm/simulator.py
pypy/dist/pypy/translator/asm/test/test_simulator.py
Log:
a simulator for our infinite register machine language
Added: pypy/dist/pypy/translator/asm/simulator.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/simulator.py Wed Oct 12 13:04:51 2005
@@ -0,0 +1,97 @@
+""" IRM Simulator """
+import autopath
+from pypy.rpython.llinterp import LLFrame
+from pypy.translator.asm.infregmachine import Instruction
+from pypy.objspace.flow.model import Constant
+
+class Machine:
+
+ def RunProgram(cls,commands,args=[],nreg=10,tracing=False):
+ #run this program
+ machine=Machine(nreg,args)
+ machine._tracing = tracing
+ ip=0
+ while not machine.stopped():
+ if ip>=len(commands):
+ return None
+ cmd=commands[ip]
+ if isinstance(cmd,str):
+ pass
+ elif cmd.name=='J':
+ ip=commands.index(cmd.arguments[0])
+ elif cmd.name=='JT':
+ c = machine.creg()
+ assert c is not None
+ if c:
+ ip=commands.index(cmd.arguments[0])
+ else:
+ machine.op(cmd.name,*cmd.arguments)
+ ip+=1
+ return machine._retval
+ RunProgram=classmethod(RunProgram)
+
+
+ def __init__(self,nreg,args):
+ self._nreg=nreg
+ self._args=args
+ self._stopped=False
+ self._creg=None
+ self._tracing = False
+ self._registers=[None for x in range(nreg+1)]
+
+ def creg(self):
+ return self._creg
+
+ def registers(self):
+ return self._registers[1:]
+
+ def register(self, reg):
+ v = self._registers[reg]
+ assert v is not None
+ return v
+
+ def stopped(self):
+ return self._stopped
+
+ def op(self,opcode,*operands):
+ if self._tracing:
+ args = []
+ for arg in operands:
+ if isinstance(arg, int):
+ args.append('r%s=%s'%(arg, self._registers[arg]))
+ else:
+ args.append(arg)
+ print opcode, ', '.join(map(str, args))
+ #will want to trap later to defer unimplemented to the LLInterpreter...
+ m = getattr(self,opcode,None)
+ if m is not None:
+ m(*operands)
+ else:
+ self.llop(opcode, *operands)
+
+ def RETPYTHON(self,reg):
+ self._stopped=True
+ self._retval=self.register(reg)
+
+ def LIA(self,destination,argindex):
+ self._registers[destination]=self._args[argindex.value]
+
+ def LOAD(self,destination,immed):
+ self._registers[destination]=immed.value
+
+ def MOV(self,destination,source):
+ self._registers[destination]=self.register(source)
+
+ def EXCH(self,destination,source):
+ self._registers[destination],self._registers[source]=self.register(source),self.register(destination)
+
+ def int_gt(self,rega,regb):
+ self._creg = self.register(rega) > self.register(regb)
+
+ def llop(self, opcode, destination, *sources):
+ sourcevalues = []
+ for r in sources:
+ sourcevalues.append(self.register(r))
+ self._registers[destination] = LLFrame.__dict__['op_'+opcode](None, *sourcevalues)
+
+
Added: pypy/dist/pypy/translator/asm/test/test_simulator.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/asm/test/test_simulator.py Wed Oct 12 13:04:51 2005
@@ -0,0 +1,69 @@
+import autopath
+from pypy.translator.asm.simulator import Machine
+from pypy.objspace.flow.model import Constant
+from pypy.translator.asm.infregmachine import Instruction
+
+def test_insn_by_insn():
+ machine=Machine(5,[0,1111,2222,3333]) # create an IRM with 5 registers to use
+
+ assert machine.registers()==[None,None,None,None,None] # check initialised.
+
+ machine.op('LOAD',1,Constant(555))
+ assert machine.registers()==[555,None,None,None,None]
+
+ machine.op('LIA',2,Constant(0)) #argument 1 to register 2
+ assert machine.registers()==[555,0,None,None,None]
+ machine.op('LIA',3,Constant(2)) #argument 3 to register 3
+ assert machine.registers()==[555,0,2222,None,None]
+
+ machine.op('MOV',2,1)
+ assert machine.registers()==[555,555,2222,None,None]
+
+ machine.op('EXCH',3,2)
+ assert machine.registers()==[555,2222,555,None,None]
+
+ machine.op('int_add',4,2,1)
+ assert machine.registers()==[555,2222,555,2222+555,None]
+
+ try:
+ machine.register(5)
+ except AssertionError:
+ pass
+ else:
+ assert False, "should not get here"
+
+ machine=Machine(3,[])
+ assert machine.creg()==None
+ machine.LOAD(1,Constant(1))
+ machine.LOAD(2,Constant(2))
+ machine.int_gt(1,2)
+ assert machine.creg()==False
+ machine.int_gt(2,1)
+ assert machine.creg()==True
+
+
+def test_programs():
+ assert Machine.RunProgram([])==None #check our program returns None if no RETPYTHON !!!
+ assert Machine.RunProgram([Instruction('LOAD',(1,Constant(23))),Instruction('RETPYTHON',(1,))])==23
+
+ prog=[Instruction('LOAD', (1, Constant(100))),
+ Instruction('J', ('label',)),
+ Instruction('LOAD', (1, Constant(200))),
+ 'label',
+ 'label2',
+ Instruction('RETPYTHON', (1,))]
+
+ assert Machine.RunProgram(prog) == 100
+
+ prog=[Instruction('LIA', (1, Constant(0))),
+ Instruction('LIA', (2, Constant(1))),
+ Instruction('LOAD', (3, Constant(77))),
+ Instruction('int_gt', (1, 2)),
+ Instruction('JT', ('label',)),
+ Instruction('LIA', (3, Constant(2))),
+ 'label',
+ Instruction('RETPYTHON', (3,))]
+
+ assert Machine.RunProgram(prog, [1,2,3]) == 3
+ assert Machine.RunProgram(prog, [2,1,3]) == 77
+
More information about the Pypy-commit
mailing list