[pypy-svn] r77796 - in pypy/branch/arm-backend/pypy/jit/backend/arm: . test
david at codespeak.net
david at codespeak.net
Mon Oct 11 17:40:36 CEST 2010
Author: david
Date: Mon Oct 11 17:40:34 2010
New Revision: 77796
Modified:
pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
pypy/branch/arm-backend/pypy/jit/backend/arm/registers.py
pypy/branch/arm-backend/pypy/jit/backend/arm/runner.py
pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py
Log:
(antocuni, david) some refactoring of the resoperation encoding, start using the register allocator,
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py Mon Oct 11 17:40:34 2010
@@ -1,8 +1,10 @@
from pypy.jit.backend.arm.codebuilder import ARMv7Builder
from pypy.jit.backend.arm import registers as r
from pypy.jit.backend.arm import conditions as c
-#from pypy.jit.backend.arm.regalloc import RegAlloc, ARMRegisterManager
+from pypy.jit.backend.llsupport.regalloc import compute_vars_longevity
+from pypy.jit.backend.arm.regalloc import ARMRegisterManager
from pypy.jit.metainterp.resoperation import rop
+from pypy.jit.metainterp.history import ConstInt, Box
from pypy.rpython.lltypesystem import lltype
# XXX Move to llsupport
from pypy.jit.backend.x86.support import values_array
@@ -13,42 +15,81 @@
def __init__(self, cpu, failargs_limit=1000):
self.mc = ARMv7Builder()
self.cpu = cpu
+ self.input_arg_boxes_int = values_array(lltype.Signed, failargs_limit) # merge with fail_boxes_int later
self.fail_boxes_int = values_array(lltype.Signed, failargs_limit)
def assemble_loop(self, inputargs, operations, looptoken):
assert len(inputargs) == 1
- reg = 0
+ longevity = compute_vars_longevity(inputargs, operations)
+ regalloc = ARMRegisterManager(longevity, assembler=self.mc)
self.gen_func_prolog()
- addr = self.fail_boxes_int.get_addr_for_num(0)
- self.gen_load_int(r.r3, addr)
- self.mc.LDR_ri(r.r1, r.r3)
+ self.gen_bootstrap_code(inputargs, regalloc)
loop_head=self.mc.curraddr()
+ looptoken._arm_bootstrap_code = self.mc.baseaddr()
+ looptoken._arm_loop_code = loop_head
+ looptoken._temp_inputargs = inputargs#XXX remove
fcond=c.AL
for op in operations:
opnum = op.getopnum()
- if opnum == rop.INT_ADD:
- self.mc.ADD_ri(r.r1, r.r1, op.getarg(1).getint())
- elif opnum == rop.INT_LE:
- self.mc.CMP(r.r1, op.getarg(1).getint())
- fcond = c.GT
- elif opnum == rop.GUARD_TRUE:
- n = self.cpu.get_fail_descr_number(op.getdescr())
- self.mc.MOV_ri(r.r0, n, cond=fcond)
- self.mc.STR_ri(r.r1, r.r3, cond=fcond)
- self.gen_func_epilog(cond=fcond)
- fcond = c.AL
- elif opnum == rop.JUMP:
- self.gen_load_int(r.r7, loop_head)
- self.mc.MOV_rr(r.pc, r.r7)
- elif opnum == rop.FINISH:
- n = self.cpu.get_fail_descr_number(op.getdescr())
- self.mc.MOV_ri(r.r0, n)
- self.mc.STR_ri(r.r1, r.r3)
- else:
- raise ValueError("Unknown op %r" % op)
+ fcond = self.operations[opnum](self, op, regalloc, fcond)
self.gen_func_epilog()
- looptoken._arm_bootstrap_code = self.mc.baseaddr()
- looptoken._arm_loop_code = loop_head
+ f = open('loop.asm', 'wb')
+ for i in range(self.mc._pos):
+ f.write(self.mc._data[i])
+ f.close()
+ print 'Done assembling'
+
+ def emit_op_jump(self, op, regalloc, fcond):
+ tmp = Box()
+ tmpreg = regalloc.try_allocate_reg(tmp)
+ inputargs = op.getdescr()._temp_inputargs
+ for i in range(op.numargs()):
+ reg = regalloc.try_allocate_reg(op.getarg(i))
+ inpreg = regalloc.try_allocate_reg(inputargs[i])
+ # XXX only if every value is in a register
+ self.mc.MOV_rr(inpreg, reg)
+ loop_code = op.getdescr()._arm_loop_code
+ self.gen_load_int(tmpreg, loop_code)
+ self.mc.MOV_rr(r.pc, tmpreg)
+ regalloc.possibly_free_var(tmpreg)
+ return fcond
+
+ def emit_op_finish(self, op, regalloc, fcond):
+ self.gen_write_back(op, op.getarglist(), regalloc, fcond)
+ return fcond
+
+ def emit_op_int_le(self, op, regalloc, fcond):
+ reg = regalloc.try_allocate_reg(op.getarg(0))
+ assert isinstance(op.getarg(1), ConstInt)
+ self.mc.CMP(reg, op.getarg(1).getint())
+ return c.GT
+
+ def emit_op_int_add(self, op, regalloc, fcond):
+ reg = regalloc.try_allocate_reg(op.getarg(0))
+ res = regalloc.try_allocate_reg(op.result)
+ assert isinstance(op.getarg(1), ConstInt)
+ self.mc.ADD_ri(res, reg, op.getarg(1).getint())
+ regalloc.possibly_free_vars_for_op(op)
+ return fcond
+
+ def emit_op_guard_true(self, op, regalloc, fcond):
+ assert fcond == c.GT
+ self.gen_write_back(op, op.getfailargs(), regalloc, fcond)
+ self.gen_func_epilog(cond=fcond)
+ return c.AL
+
+ def gen_write_back(self, op, args, regalloc, fcond):
+ temp = Box()
+ temp_reg = regalloc.try_allocate_reg(temp)
+ for i in range(len(args)):
+ reg = regalloc.try_allocate_reg(args[i])
+ addr = self.fail_boxes_int.get_addr_for_num(i)
+ self.gen_load_int(temp_reg, addr, cond=fcond)
+ self.mc.STR_ri(reg, temp_reg, cond=fcond)
+
+ regalloc.possibly_free_var(temp_reg)
+ n = self.cpu.get_fail_descr_number(op.getdescr())
+ self.mc.MOV_ri(r.r0, n, cond=fcond)
def gen_func_epilog(self,cond=c.AL):
self.mc.LDM(r.sp, r.callee_restored_registers, cond=cond)
@@ -56,6 +97,13 @@
def gen_func_prolog(self):
self.mc.PUSH(r.callee_saved_registers)
+ def gen_bootstrap_code(self, inputargs, regalloc):
+ for i in range(len(inputargs)):
+ reg = regalloc.try_allocate_reg(inputargs[i])
+ addr = self.input_arg_boxes_int.get_addr_for_num(i)
+ self.gen_load_int(reg, addr)
+ self.mc.LDR_ri(reg, reg)
+
def gen_load_int(self, reg, value, cond=c.AL):
assert reg != r.ip, 'ip is used to load int'
self.mc.MOV_ri(reg, (value & 0xFF), cond=cond)
@@ -63,3 +111,24 @@
for offset in range(8, 25, 8):
self.mc.MOV_ri(r.ip, (value >> offset) & 0xFF, cond=cond)
self.mc.ORR_rr(reg, reg, r.ip, offset, cond=cond)
+
+
+
+def make_operation_list():
+ def notimplemented(self, op, regalloc, fcond):
+ raise NotImplementedError
+
+ operations = [None] * (rop._LAST+1)
+ for key, value in rop.__dict__.items():
+ key = key.lower()
+ if key.startswith('_'):
+ continue
+ methname = 'emit_op_%s' % key
+ if hasattr(AssemblerARM, methname):
+ func = getattr(AssemblerARM, methname).im_func
+ else:
+ func = notimplemented
+ operations[value] = func
+ return operations
+
+AssemblerARM.operations = make_operation_list()
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/registers.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/registers.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/registers.py Mon Oct 11 17:40:34 2010
@@ -6,6 +6,7 @@
lr = 14
pc = 15
+all_regs = range(12)
callee_resp = [r4, r5, r6, r7, r8, r9, r10, r11]
callee_saved_registers = callee_resp+[lr]
callee_restored_registers = callee_resp+[pc]
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/runner.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/runner.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/runner.py Mon Oct 11 17:40:34 2010
@@ -19,7 +19,7 @@
self.assembler.assemble_loop(inputargs, operations, looptoken)
def set_future_value_int(self, index, intvalue):
- self.assembler.fail_boxes_int.setitem(index, intvalue)
+ self.assembler.input_arg_boxes_int.setitem(index, intvalue)
def get_latest_value_int(self, index):
return self.assembler.fail_boxes_int.getitem(index)
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/test/test_assembler.py Mon Oct 11 17:40:34 2010
@@ -2,6 +2,7 @@
from pypy.jit.backend.arm import conditions as c
from pypy.jit.backend.arm.assembler import AssemblerARM
from pypy.jit.backend.arm.test.support import skip_unless_arm, run_asm
+from pypy.jit.metainterp.resoperation import rop
skip_unless_arm()
@@ -9,6 +10,10 @@
def setup_method(self, method):
self.a = AssemblerARM(None)
+ def test_make_operation_list(self):
+ i = rop.INT_ADD
+ assert self.a.operations[i] is AssemblerARM.emit_op_int_add.im_func
+
def test_load_small_int_to_reg(self):
self.a.gen_func_prolog()
self.a.gen_load_int(r.r0, 123)
@@ -43,7 +48,7 @@
self.a.gen_func_epilog()
assert run_asm(self.a) == 123333
- def test_int_le(self):
+ def test_cmp(self):
self.a.gen_func_prolog()
self.a.gen_load_int(r.r1, 22)
self.a.mc.CMP(r.r1, 123)
@@ -86,3 +91,4 @@
self.a.gen_func_epilog()
assert run_asm(self.a) == 9
+
More information about the Pypy-commit
mailing list