Author: Armin Rigo <ar...@tunes.org> Branch: errno-again Changeset: r75406:ff91d89bf257 Date: 2015-01-16 23:04 +0100 http://bitbucket.org/pypy/pypy/changeset/ff91d89bf257/
Log: Untested: ARM support diff --git a/rpython/jit/backend/arm/callbuilder.py b/rpython/jit/backend/arm/callbuilder.py --- a/rpython/jit/backend/arm/callbuilder.py +++ b/rpython/jit/backend/arm/callbuilder.py @@ -11,6 +11,8 @@ from rpython.jit.backend.arm.helper.assembler import saved_registers from rpython.jit.backend.arm.helper.regalloc import check_imm_arg from rpython.jit.backend.arm.codebuilder import OverwritingBuilder +from rpython.jit.backend.llsupport import llerrno +from rpython.rtyper.lltypesystem import rffi class ARMCallbuilder(AbstractCallBuilder): @@ -172,6 +174,41 @@ self.mc.LSL_ri(resloc.value, resloc.value, 16) self.mc.ASR_ri(resloc.value, resloc.value, 16) + def write_real_errno(self, save_err): + if save_err & rffi.RFFI_READSAVED_ERRNO: + # Just before a call, read 'rpy_errno' and write it into the + # real 'errno'. The r0-r3 registers contain arguments to the + # future call; the r5-r7 registers contain various stuff. + # We still have r8-r12. + rpy_errno = llerrno.get_rpy_errno_offset(self.asm.cpu) + p_errno = llerrno.get_p_errno_offset(self.asm.cpu) + self.mc.LDR_ri(r.r9.value, r.sp.value, + self.asm.saved_threadlocal_addr + self.current_sp) + self.mc.LDR_ri(r.ip.value, r.r9.value, p_errno) + self.mc.LDR_ri(r.r9.value, r.r9.value, rpy_errno) + self.mc.STR_ri(r.r9.value, r.ip.value) + elif save_err & rffi.RFFI_ZERO_ERRNO_BEFORE: + # Same, but write zero. + p_errno = llerrno.get_p_errno_offset(self.asm.cpu) + self.mc.LDR_ri(r.r9.value, r.sp.value, + self.asm.saved_threadlocal_addr + self.current_sp) + self.mc.LDR_ri(r.ip.value, r.r9.value, p_errno) + self.mc.MOV_ri(r.r9.value, 0) + self.mc.STR_ri(r.r9.value, r.ip.value) + + def read_real_errno(self, save_err): + if save_err & rffi.RFFI_SAVE_ERRNO: + # Just after a call, read the real 'errno' and save a copy of + # it inside our thread-local 'rpy_errno'. Registers r8-r12 + # are unused here, and registers r2-r3 never contain anything + # after the call. + rpy_errno = llerrno.get_rpy_errno_offset(self.asm.cpu) + p_errno = llerrno.get_p_errno_offset(self.asm.cpu) + self.mc.LDR_ri(r.r3.value, r.sp.value, + self.asm.saved_threadlocal_addr) + self.mc.LDR_ri(r.ip.value, r.r3.value, p_errno) + self.mc.LDR_ri(r.ip.value, r.ip.value, 0) + self.mc.STR_ri(r.ip.value, r.r3.value, rpy_errno) class SoftFloatCallBuilder(ARMCallbuilder): 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 @@ -403,7 +403,9 @@ # args = [resloc, size, sign, args...] from rpython.jit.backend.llsupport.descr import CallDescr - cb = callbuilder.get_callbuilder(self.cpu, self, arglocs[3], arglocs[4:], arglocs[0]) + func_index = 3 + is_call_release_gil + cb = callbuilder.get_callbuilder(self.cpu, self, arglocs[func_index], + arglocs[func_index+1:], arglocs[0]) descr = op.getdescr() assert isinstance(descr, CallDescr) @@ -418,7 +420,9 @@ cb.ressign = signloc.value if is_call_release_gil: - cb.emit_call_release_gil() + saveerrloc = arglocs[3] + assert saveerrloc.is_imm() + cb.emit_call_release_gil(saveerrloc.value) else: cb.emit() return fcond @@ -1073,7 +1077,7 @@ def emit_guard_call_release_gil(self, op, guard_op, arglocs, regalloc, fcond): numargs = op.numargs() - callargs = arglocs[:numargs + 3] # extract the arguments to the call + callargs = arglocs[:numargs + 4] # extract the arguments to the call guardargs = arglocs[len(callargs):] # extrat the arguments for the guard self._store_force_index(guard_op) self._emit_call(op, callargs, is_call_release_gil=True) @@ -1286,9 +1290,13 @@ return fcond def emit_opx_threadlocalref_get(self, op, arglocs, regalloc, fcond): - ofs0, res = arglocs - assert ofs0.is_imm() + ofs_loc, size_loc, sign_loc, res_loc = arglocs + assert ofs_loc.is_imm() + assert size_loc.is_imm() + assert sign_loc.is_imm() ofs = self.saved_threadlocal_addr - self.load_reg(self.mc, res, r.sp, ofs) - self.load_reg(self.mc, res, res, ofs0.value) + self.load_reg(self.mc, res_loc, r.sp, ofs) + scale = get_scale(size_loc.value) + signed = (sign_loc.value != 0) + self._load_from_mem(res_loc, res_loc, ofs_loc, scale, signed, fcond) return fcond 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 @@ -573,11 +573,12 @@ # ... return self._prepare_call(op) - def _prepare_call(self, op, force_store=[], save_all_regs=False): + def _prepare_call(self, op, force_store=[], save_all_regs=False, + first_arg_index=1): args = [None] * (op.numargs() + 3) calldescr = op.getdescr() assert isinstance(calldescr, CallDescr) - assert len(calldescr.arg_classes) == op.numargs() - 1 + assert len(calldescr.arg_classes) == op.numargs() - first_arg_index for i in range(op.numargs()): args[i + 3] = self.loc(op.getarg(i)) @@ -626,10 +627,12 @@ return [loc0, res] def _prepare_threadlocalref_get(self, op, fcond): - ofs0 = imm(op.getarg(1).getint()) - xxxxxxxxxxxxxxxx check the size and signedness of op.getdescr() - res = self.force_allocate_reg(op.result) - return [ofs0, res] + ofs_loc = imm(op.getarg(1).getint()) + calldescr = op.getdescr() + size_loc = imm(calldescr.get_result_size()) + sign_loc = imm(calldescr.is_result_signed()) + res_loc = self.force_allocate_reg(op.result) + return [ofs_loc, size_loc, sign_loc, res_loc] def _prepare_guard(self, op, args=None): if args is None: @@ -1236,7 +1239,10 @@ def prepare_guard_call_may_force(self, op, guard_op, fcond): args = self._prepare_call(op, save_all_regs=True) return self._prepare_guard(guard_op, args) - prepare_guard_call_release_gil = prepare_guard_call_may_force + + def prepare_guard_call_release_gil(self, op, guard_op, fcond): + args = self._prepare_call(op, save_all_regs=True, first_arg_index=2) + return self._prepare_guard(guard_op, args) def prepare_guard_call_assembler(self, op, guard_op, fcond): locs = self.locs_for_call_assembler(op, guard_op) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit