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

Reply via email to