Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit