[pypy-svn] r79684 - pypy/branch/arm-backend/pypy/jit/backend/arm
david at codespeak.net
david at codespeak.net
Tue Nov 30 15:47:13 CET 2010
Author: david
Date: Tue Nov 30 15:47:11 2010
New Revision: 79684
Modified:
pypy/branch/arm-backend/pypy/jit/backend/arm/assembler.py
pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
pypy/branch/arm-backend/pypy/jit/backend/arm/runner.py
Log:
Exception and string copy operations
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 Tue Nov 30 15:47:11 2010
@@ -5,7 +5,7 @@
from pypy.jit.backend.arm.codebuilder import ARMv7Builder, ARMv7InMemoryBuilder
from pypy.jit.backend.arm.regalloc import ARMRegisterManager, ARMFrameManager
from pypy.jit.backend.llsupport.regalloc import compute_vars_longevity, TempBox
-from pypy.jit.metainterp.history import (ConstInt, BoxInt, BasicFailDescr,
+from pypy.jit.metainterp.history import (Const, ConstInt, BoxInt, BasicFailDescr,
INT, REF, FLOAT)
from pypy.jit.metainterp.resoperation import rop
from pypy.rlib import rgc
@@ -16,6 +16,9 @@
# XXX Move to llsupport
from pypy.jit.backend.x86.support import values_array
+memcpy_fn = rffi.llexternal('memcpy', [llmemory.Address, llmemory.Address,
+ rffi.SIZE_T], lltype.Void,
+ sandboxsafe=True, _nowrapper=True)
class AssemblerARM(ResOpAssembler):
@@ -29,6 +32,7 @@
self.malloc_array_func_addr = 0
self.malloc_str_func_addr = 0
self.malloc_unicode_func_addr = 0
+ self.memcpy_addr = 0
def setup(self):
if self.mc is None:
@@ -55,6 +59,7 @@
ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode()
self.malloc_unicode_func_addr = rffi.cast(lltype.Signed,
ll_new_unicode)
+ self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn)
def setup_failure_recovery(self):
@@ -439,6 +444,20 @@
return arg.getint() <= size and lower_bound
return False
+ def _ensure_value_is_boxed(self, thing, regalloc):
+ box = None
+ loc = None
+ if isinstance(thing, Const):
+ box = TempBox()
+ loc = regalloc.force_allocate_reg(box)
+ imm = regalloc.convert_to_imm(thing)
+ self.mc.gen_load_int(loc.value, imm.getint())
+ else:
+ loc = regalloc.make_sure_var_in_reg(thing, imm_fine=False)
+ box = thing
+ return loc, box
+
+
def _ensure_result_bit_extension(self, resloc, size, signed, regalloc):
if size == 4:
Modified: pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py
==============================================================================
--- pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py (original)
+++ pypy/branch/arm-backend/pypy/jit/backend/arm/opassembler.py Tue Nov 30 15:47:11 2010
@@ -180,15 +180,22 @@
_mixin_ = True
- guard_size = ARMv7Builder.size_of_gen_load_int + 2*WORD
- def _emit_guard(self, op, regalloc, fcond):
+ guard_size = ARMv7Builder.size_of_gen_load_int + 6*WORD
+ def _emit_guard(self, op, regalloc, fcond, save_exc=False):
descr = op.getdescr()
assert isinstance(descr, BasicFailDescr)
#if hasattr(op, 'getfailargs'):
# print 'Failargs: ', op.getfailargs()
+
self.mc.ensure_can_fit(self.guard_size)
self.mc.ADD_ri(r.pc.value, r.pc.value, self.guard_size, cond=fcond)
descr._arm_guard_code = self.mc.curraddr()
+
+ self.mc.PUSH([reg.value for reg in r.caller_resp])
+ addr = self.cpu.get_on_leave_jitted_int(save_exception=save_exc)
+ self.mc.BL(addr)
+ self.mc.POP([reg.value for reg in r.caller_resp])
+
memaddr = self._gen_path_to_exit_path(op, op.getfailargs(), regalloc)
descr._failure_recovery_code = memaddr
regalloc.possibly_free_vars_for_op(op)
@@ -358,6 +365,47 @@
regalloc.possibly_free_var(op.result)
return fcond
+ def emit_op_cond_call_gc_wb(self, op, regalloc, fcond):
+ #XXX implement once gc support is in place
+ return fcond
+
+ def emit_op_guard_no_exception(self, op, regalloc, fcond):
+ t = TempBox()
+ loc = regalloc.force_allocate_reg(t)
+ self.mc.gen_load_int(loc.value, self.cpu.pos_exception(), fcond)
+ self.mc.LDR_ri(loc.value, loc.value)
+ self.mc.CMP_ri(loc.value, 0)
+ self._emit_guard(op, regalloc, c.EQ, save_exc=True)
+ regalloc.possibly_free_var(t)
+
+ def emit_op_guard_exception(self, op, regalloc, fcond):
+ args = op.getarglist()
+ t = TempBox()
+ t1 = TempBox()
+ loc = regalloc.force_allocate_reg(t, args)
+ loc1 = regalloc.force_allocate_reg(t1, args + [t])
+ self.mc.gen_load_int(loc.value,
+ self.cpu.cast_adr_to_int(
+ op.getarg(0).getint()), fcond)
+
+ self.mc.gen_load_int(loc1.value, self.cpu.pos_exception(), fcond)
+ self.mc.LDR_ri(loc1.value, loc1.value)
+
+ self.mc.CMP_rr(loc1.value, loc.value)
+ self._emit_guard(op, regalloc, c.EQ, save_exc=True)
+ self.mc.gen_load_int(loc1.value, self.cpu.pos_exc_value(), fcond)
+ if op.result in regalloc.longevity:
+ resloc = regalloc.force_allocate_reg(op.result, args + [t, t1])
+ self.mc.LDR_ri(resloc.value, loc1.value)
+ regalloc.possibly_free_var(resloc)
+ self.mc.gen_load_int(loc.value, self.cpu.pos_exception(), fcond)
+ self.mc.MOV_ri(r.ip.value, 0)
+ self.mc.STR_ri(r.ip.value, loc.value)
+ self.mc.STR_ri(r.ip.value, loc1.value)
+ regalloc.possibly_free_var(t)
+ regalloc.possibly_free_var(t1)
+ return fcond
+
class FieldOpAssembler(object):
_mixin_ = True
@@ -573,6 +621,106 @@
self.mc.STRB_ri(value_loc.value, temp.value, basesize, cond=fcond)
return fcond
+ #from ../x86/regalloc.py:928 ff.
+ def emit_op_copystrcontent(self, op, regalloc, fcond):
+ self._emit_copystrcontent(op, regalloc, fcond, is_unicode=False)
+
+ def emit_op_copyunicodecontent(self, op, regalloc, fcond):
+ self._emit_copystrcontent(op, regalloc, fcond, is_unicode=True)
+
+ def _emit_copystrcontent(self, op, regalloc, fcond, is_unicode):
+ # compute the source address
+ args = op.getarglist()
+ boxes = []
+ base_loc, box = self._ensure_value_is_boxed(args[0], regalloc)
+ boxes.append(box)
+ ofs_loc, box = self._ensure_value_is_boxed(args[2], regalloc)
+ boxes.append(box)
+ assert args[0] is not args[1] # forbidden case of aliasing
+
+ srcaddr_box = TempBox()
+ forbidden_vars = [args[1], args[3], args[4], srcaddr_box]
+ srcaddr_loc = regalloc.force_allocate_reg(srcaddr_box, forbidden_vars)
+ self._gen_address_inside_string(base_loc, ofs_loc, srcaddr_loc,
+ is_unicode=is_unicode)
+ regalloc.possibly_free_var(boxes[0])
+ if args[3] is not args[2] is not args[4]: # MESS MESS MESS: don't free
+ regalloc.possibly_free_var(boxes[1]) # it if ==args[3] or args[4]
+
+ # compute the destination address
+ base_loc, box = self._ensure_value_is_boxed(args[1], regalloc)
+ boxes.append(box)
+ ofs_loc, box = self._ensure_value_is_boxed(args[3], regalloc)
+ boxes.append(box)
+ assert base_loc.is_reg()
+ assert ofs_loc.is_reg()
+ forbidden_vars = [args[4], srcaddr_box]
+ dstaddr_box = TempBox()
+ dstaddr_loc = regalloc.force_allocate_reg(dstaddr_box,
+ forbidden_vars)
+ self._gen_address_inside_string(base_loc, ofs_loc, dstaddr_loc,
+ is_unicode=is_unicode)
+ regalloc.possibly_free_var(boxes[2])
+ if args[3] is not args[4]: # more of the MESS described above
+ regalloc.possibly_free_var(boxes[3])
+
+ # compute the length in bytes
+ length_loc, length_box = self._ensure_value_is_boxed(args[4], regalloc)
+ boxes.append(length_box)
+ if is_unicode:
+ forbidden_vars = [srcaddr_box, dstaddr_box]
+ bytes_box = TempBox()
+ bytes_loc = regalloc.force_allocate_reg(bytes_box, forbidden_vars)
+ scale = self._get_unicode_item_scale()
+ self.mc.MOV_rr(bytes_loc.value, length_loc.value)
+ self._load_address(length_loc, 0, scale, bytes_loc)
+ length_box = bytes_box
+ length_loc = bytes_loc
+ # call memcpy()
+ self._emit_call(self.memcpy_addr, [dstaddr_box, srcaddr_box, length_box], regalloc)
+
+ regalloc.possibly_free_var(length_box)
+ regalloc.possibly_free_var(dstaddr_box)
+ regalloc.possibly_free_var(srcaddr_box)
+ regalloc.possibly_free_vars_for_op(op)
+ regalloc.possibly_free_vars(boxes)
+
+ def _load_address(self, sizereg, baseofs, scale, result, baseloc=None):
+ if baseloc is not None:
+ assert baseloc.is_reg()
+ self.mc.MOV_rr(result.value, baseloc.value)
+ else:
+ self.mc.MOV_ri(result.value, 0)
+ assert sizereg.is_reg()
+ if scale > 0:
+ self.mc.LSL_ri(r.ip.value, sizereg.value, scale)
+ else:
+ self.mc.MOV_rr(r.ip.value, sizereg.value)
+ self.mc.ADD_rr(result.value, result.value, r.ip.value)
+ self.mc.ADD_ri(result.value, result.value, baseofs)
+
+ def _gen_address_inside_string(self, baseloc, ofsloc, resloc, is_unicode):
+ cpu = self.cpu
+ if is_unicode:
+ ofs_items, _, _ = symbolic.get_array_token(rstr.UNICODE,
+ self.cpu.translate_support_code)
+ scale = self._get_unicode_item_scale()
+ else:
+ ofs_items, itemsize, _ = symbolic.get_array_token(rstr.STR,
+ self.cpu.translate_support_code)
+ assert itemsize == 1
+ scale = 0
+ self._load_address(ofsloc, ofs_items, scale, resloc, baseloc)
+
+ def _get_unicode_item_scale(self):
+ _, itemsize, _ = symbolic.get_array_token(rstr.UNICODE,
+ self.cpu.translate_support_code)
+ if itemsize == 4:
+ return 2
+ elif itemsize == 2:
+ return 1
+ else:
+ raise AssertionError("bad unicode item size")
class UnicodeOpAssembler(object):
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 Tue Nov 30 15:47:11 2010
@@ -52,17 +52,16 @@
return self.get_fail_descr_from_number(fail_index)
def _execute_call(self, func):
- #prev_interpreter = LLInterpreter.current_interpreter
- #LLInterpreter.current_interpreter = self.debug_ll_interpreter
+ prev_interpreter = LLInterpreter.current_interpreter
+ LLInterpreter.current_interpreter = self.debug_ll_interpreter
res = 0
- #try:
- res = func()
- #finally:
- # LLInterpreter.current_interpreter = prev_interpreter
+ try:
+ res = func()
+ finally:
+ LLInterpreter.current_interpreter = prev_interpreter
return res
- @staticmethod
- def cast_ptr_to_int(x):
+ def cast_ptr_to_int(self, x):
adr = llmemory.cast_ptr_to_adr(x)
return self.cast_adr_to_int(adr)
More information about the Pypy-commit
mailing list