[pypy-dev] [pypy-commit] pypy jitframe-on-heap: start fixing call_assembler for ARM
Maciej Fijalkowski
fijall at gmail.com
Thu Feb 14 17:04:46 CET 2013
Hi David.
I started working on this, but also this is again a direct copy of x86
code. I understand where it comes from but please refrain from doing
it in the future. I will work out the call_assembler and friends, but
I'll backout your commit.
On Thu, Feb 14, 2013 at 5:44 PM, bivab <noreply at buildbot.pypy.org> wrote:
> Author: David Schneider <david.schneider at picle.org>
> Branch: jitframe-on-heap
> Changeset: r61238:1dd0aa6c631a
> Date: 2013-02-14 16:43 +0100
> http://bitbucket.org/pypy/pypy/changeset/1dd0aa6c631a/
>
> Log: start fixing call_assembler for ARM
>
> floats do not work correctly yet
>
> diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py
> --- a/rpython/jit/backend/arm/opassembler.py
> +++ b/rpython/jit/backend/arm/opassembler.py
> @@ -1104,59 +1104,52 @@
> # XXX Split into some helper methods
> def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc,
> fcond):
> - tmploc = arglocs[1]
> - resloc = arglocs[2]
> - callargs = arglocs[3:]
> -
> self._store_force_index(guard_op)
> descr = op.getdescr()
> assert isinstance(descr, JitCellToken)
> - # check value
> - assert tmploc is r.r0
> - self._emit_call(imm(descr._ll_function_addr),
> - callargs, fcond, resloc=tmploc)
> + if len(arglocs) == 4:
> + [frame_loc, vloc, result_loc, argloc] = arglocs
> + else:
> + [frame_loc, result_loc, argloc] = arglocs
> + vloc = imm(0)
> +
> + #
> + # Write a call to the target assembler
> + # we need to allocate the frame, keep in sync with runner's
> + # execute_token
> + jd = descr.outermost_jitdriver_sd
> + base_ofs = self.cpu.get_baseofs_of_frame_field()
> + self._emit_call(imm(descr._ll_function_addr), [argloc], fcond)
> if op.result is None:
> - value = self.cpu.done_with_this_frame_void_v
> + assert result_loc is None
> + value = self.cpu.done_with_this_frame_descr_void
> else:
> kind = op.result.type
> if kind == INT:
> - value = self.cpu.done_with_this_frame_int_v
> + assert result_loc is r.r0
> + value = self.cpu.done_with_this_frame_descr_int
> elif kind == REF:
> - value = self.cpu.done_with_this_frame_ref_v
> + assert result_loc is r.r0
> + value = self.cpu.done_with_this_frame_descr_ref
> elif kind == FLOAT:
> - value = self.cpu.done_with_this_frame_float_v
> + value = self.cpu.done_with_this_frame_descr_float
> else:
> raise AssertionError(kind)
> - from rpython.jit.backend.llsupport.descr import unpack_fielddescr
> - from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr
> - descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
> - _offset, _size, _ = unpack_fielddescr(descrs.jf_descr)
> - fail_descr = self.cpu.get_fail_descr_from_number(value)
> - value = fail_descr.hide(self.cpu)
> - rgc._make_sure_does_not_move(value)
> - value = rffi.cast(lltype.Signed, value)
>
> - if check_imm_arg(_offset):
> - self.mc.LDR_ri(r.ip.value, tmploc.value, imm=_offset)
> - else:
> - self.mc.gen_load_int(r.ip.value, _offset)
> - self.mc.LDR_rr(r.ip.value, tmploc.value, r.ip.value)
> +
> + gcref = cast_instance_to_gcref(value)
> + rgc._make_sure_does_not_move(gcref)
> + value = rffi.cast(lltype.Signed, gcref)
> + ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
> + assert check_imm_arg(ofs)
> + self.mc.LDR_ri(r.ip.value, r.r0.value, imm=ofs)
> +
> if check_imm_arg(value):
> self.mc.CMP_ri(r.ip.value, imm=value)
> else:
> self.mc.gen_load_int(r.lr.value, value)
> self.mc.CMP_rr(r.lr.value, r.ip.value)
> -
> -
> - #if values are equal we take the fast path
> - # Slow path, calling helper
> - # jump to merge point
> -
> - jd = descr.outermost_jitdriver_sd
> - assert jd is not None
> -
> - # Path A: load return value and reset token
> - # Fast Path using result boxes
> + # Path 1: Fast Path
>
> fast_path_cond = c.EQ
> # Reset the vable token --- XXX really too much special logic here:-(
> @@ -1164,45 +1157,40 @@
> from rpython.jit.backend.llsupport.descr import FieldDescr
> fielddescr = jd.vable_token_descr
> assert isinstance(fielddescr, FieldDescr)
> - ofs = fielddescr.offset
> - tmploc = regalloc.get_scratch_reg(INT)
> - self.mov_loc_loc(arglocs[0], r.ip, cond=fast_path_cond)
> - self.mc.MOV_ri(tmploc.value, 0, cond=fast_path_cond)
> - self.mc.STR_ri(tmploc.value, r.ip.value, ofs, cond=fast_path_cond)
> + assert isinstance(fielddescr, FieldDescr)
> + vtoken_ofs = fielddescr.offset
> + assert check_imm_arg(vtoken_ofs)
> + self.mov_loc_loc(vloc, r.ip, cond=fast_path_cond)
> + self.mc.MOV_ri(r.lr.value, 0, cond=fast_path_cond)
> + self.mc.STR_ri(tmploc.value, r.ip.value, vtoken_ofs, cond=fast_path_cond)
> + # in the line above, TOKEN_NONE = 0
>
> if op.result is not None:
> - # load the return value from fail_boxes_xxx[0]
> + # load the return value from the dead frame's value index 0
> kind = op.result.type
> if kind == FLOAT:
> - t = unpack_interiorfielddescr(descrs.as_float)[0]
> - if not check_imm_arg(t):
> - self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond)
> + descr = self.cpu.getarraydescr_for_frame(kind)
> + ofs = self.cpu.unpack_arraydescr(descr)
> + if not check_imm_arg(ofs):
> + self.mc.gen_load_int(r.ip.value, ofs, cond=fast_path_cond)
> self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value,
> cond=fast_path_cond)
> - t = 0
> + ofs = 0
> base = r.ip
> else:
> base = r.r0
> - self.mc.VLDR(resloc.value, base.value, imm=t,
> - cond=fast_path_cond)
> + self.mc.VLDR(result_loc.value, base.value, imm=ofs,
> + cond=fast_path_cond)
> else:
> - assert resloc is r.r0
> - if kind == INT:
> - t = unpack_interiorfielddescr(descrs.as_int)[0]
> - else:
> - t = unpack_interiorfielddescr(descrs.as_ref)[0]
> - if not check_imm_arg(t):
> - self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond)
> - self.mc.LDR_rr(resloc.value, resloc.value, r.ip.value,
> - cond=fast_path_cond)
> - else:
> - self.mc.LDR_ri(resloc.value, resloc.value, imm=t,
> - cond=fast_path_cond)
> + assert result_loc is r.r0
> + descr = self.cpu.getarraydescr_for_frame(kind)
> + ofs = self.cpu.unpack_arraydescr(descr)
> + self.load_reg(self.mc, r.r0, r.r0, ofs, cond=fast_path_cond)
> # jump to merge point
> jmp_pos = self.mc.currpos()
> self.mc.BKPT()
>
> - # Path B: use assembler helper
> + # Path 2: use assembler helper
> asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr)
> if self.cpu.supports_floats:
> floats = r.caller_vfp_resp
> @@ -1213,28 +1201,24 @@
> # the result
> core = r.caller_resp
> if op.result:
> - if resloc.is_vfp_reg():
> + if result_loc.is_vfp_reg():
> floats = r.caller_vfp_resp[1:]
> else:
> core = r.caller_resp[1:] + [r.ip] # keep alignment
> with saved_registers(self.mc, core, floats):
> # result of previous call is in r0
> - self.mov_loc_loc(arglocs[0], r.r1)
> + self.mov_loc_loc(vloc, r.r1)
> self.mc.BL(asm_helper_adr)
> - if not self.cpu.use_hf_abi and op.result and resloc.is_vfp_reg():
> + if not self.cpu.use_hf_abi and op.result and result_loc.is_vfp_reg():
> # move result to the allocated register
> - self.mov_to_vfp_loc(r.r0, r.r1, resloc)
> + self.mov_to_vfp_loc(r.r0, r.r1, result_loc)
>
> # merge point
> currpos = self.mc.currpos()
> pmc = OverwritingBuilder(self.mc, jmp_pos, WORD)
> pmc.B_offs(currpos, fast_path_cond)
>
> - self.mc.LDR_ri(r.ip.value, r.fp.value)
> - self.mc.CMP_ri(r.ip.value, 0)
> -
> - self._emit_guard(guard_op, regalloc._prepare_guard(guard_op),
> - c.GE, save_exc=True)
> + self._emit_guard_may_force(guard_op, arglocs, op.numargs())
> return fcond
>
> # ../x86/assembler.py:668
> diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py
> --- a/rpython/jit/backend/arm/regalloc.py
> +++ b/rpython/jit/backend/arm/regalloc.py
> @@ -1101,20 +1101,18 @@
> prepare_guard_call_release_gil = prepare_guard_call_may_force
>
> def prepare_guard_call_assembler(self, op, guard_op, fcond):
> +
> descr = op.getdescr()
> assert isinstance(descr, JitCellToken)
> - jd = descr.outermost_jitdriver_sd
> - assert jd is not None
> - vable_index = jd.index_of_virtualizable
> - if vable_index >= 0:
> - self._sync_var(op.getarg(vable_index))
> - vable = self.frame_manager.loc(op.getarg(vable_index))
> + arglist = op.getarglist()
> + self.rm._sync_var(arglist[0])
> + frame_loc = self.fm.loc(op.getarg(0))
> + if len(arglist) == 2:
> + self.rm._sync_var(arglist[1])
> + locs = [frame_loc, self.fm.loc(arglist[1])]
> else:
> - vable = imm(0)
> - # make sure the call result location is free
> - tmploc = self.get_scratch_reg(INT, selected_reg=r.r0)
> - self.possibly_free_vars(guard_op.getfailargs())
> - return [vable, tmploc] + self._prepare_call(op, save_all_regs=True)
> + locs = [frame_loc]
> + return locs + self._prepare_call(op, save_all_regs=True)
>
> def _prepare_args_for_new_op(self, new_args):
> gc_ll_descr = self.cpu.gc_ll_descr
> _______________________________________________
> pypy-commit mailing list
> pypy-commit at python.org
> http://mail.python.org/mailman/listinfo/pypy-commit
More information about the pypy-dev
mailing list