Author: Maciej Fijalkowski <[email protected]>
Branch: arm64
Changeset: r96846:ca09029d532f
Date: 2019-06-22 18:43 +0000
http://bitbucket.org/pypy/pypy/changeset/ca09029d532f/

Log:    call_assembler

diff --git a/rpython/jit/backend/aarch64/assembler.py 
b/rpython/jit/backend/aarch64/assembler.py
--- a/rpython/jit/backend/aarch64/assembler.py
+++ b/rpython/jit/backend/aarch64/assembler.py
@@ -737,16 +737,16 @@
             self.mc.BL(self.stack_check_slowpath, c=c.HI)      # call if ip > 
lr
 
     def _call_header(self):
-        stack_size = (len(r.callee_saved_registers) + 2) * WORD
+        stack_size = (len(r.callee_saved_registers) + 4) * WORD
         self.mc.STP_rr_preindex(r.fp.value, r.lr.value, r.sp.value, 
-stack_size)
         for i in range(0, len(r.callee_saved_registers), 2):
             self.mc.STP_rri(r.callee_saved_registers[i].value,
                             r.callee_saved_registers[i + 1].value,
                             r.sp.value,
-                            (i + 2) * WORD)
+                            (i + 4) * WORD)
         
-        #self.saved_threadlocal_addr = 0   # at offset 0 from location 'sp'
-        # ^^^XXX save it from register x1 into some place
+        self.saved_threadlocal_addr = 3 * WORD   # at offset 3 from location 
'sp'
+        self.mc.STR_ri(r.x1.value, r.sp.value, 3 * WORD)
 
         # set fp to point to the JITFRAME, passed in argument 'x0'
         self.mc.MOV_rr(r.fp.value, r.x0.value)
@@ -798,7 +798,8 @@
                     regalloc.possibly_free_vars(guard_op.getfailargs())
                 regalloc.possibly_free_vars_for_op(guard_op)
             elif (rop.is_call_may_force(op.getopnum()) or
-                  rop.is_call_release_gil(op.getopnum())):
+                  rop.is_call_release_gil(op.getopnum()) or
+                  rop.is_call_assembler(op.getopnum())):
                 guard_op = operations[i + 1] # has to exist
                 guard_num = guard_op.getopnum()
                 assert guard_num in (rop.GUARD_NOT_FORCED, 
rop.GUARD_NOT_FORCED_2)
@@ -972,13 +973,13 @@
 
         # pop all callee saved registers
 
-        stack_size = len(r.callee_saved_registers) * WORD
+        stack_size = (len(r.callee_saved_registers) + 4) * WORD
 
         for i in range(0, len(r.callee_saved_registers), 2):
             mc.LDP_rri(r.callee_saved_registers[i].value,
                             r.callee_saved_registers[i + 1].value,
                             r.sp.value,
-                            (i + 2) * WORD)
+                            (i + 4) * WORD)
         mc.LDP_rr_postindex(r.fp.value, r.lr.value, r.sp.value, stack_size)
 
 
diff --git a/rpython/jit/backend/aarch64/opassembler.py 
b/rpython/jit/backend/aarch64/opassembler.py
--- a/rpython/jit/backend/aarch64/opassembler.py
+++ b/rpython/jit/backend/aarch64/opassembler.py
@@ -3,13 +3,14 @@
 from rpython.rlib.rarithmetic import r_uint
 from rpython.rtyper.lltypesystem import rffi, lltype
 from rpython.jit.metainterp.history import (AbstractFailDescr, ConstInt,
-                                            INT, FLOAT, REF)
+                                            INT, FLOAT, REF, VOID)
 from rpython.jit.backend.aarch64 import registers as r
 from rpython.jit.backend.aarch64.codebuilder import OverwritingBuilder
 from rpython.jit.backend.aarch64.callbuilder import Aarch64CallBuilder
 from rpython.jit.backend.arm import conditions as c, shift
+from rpython.jit.backend.aarch64.regalloc import check_imm_arg
 from rpython.jit.backend.aarch64.arch import JITFRAME_FIXED_SIZE, WORD
-from rpython.jit.backend.aarch64.locations import imm
+from rpython.jit.backend.aarch64 import locations
 from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler
 from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
 from rpython.jit.backend.llsupport.regalloc import get_scale
@@ -42,6 +43,9 @@
     return emit_op        
 
 class ResOpAssembler(BaseAssembler):
+    def imm(self, v):
+        return locations.imm(v)
+
     def int_sub_impl(self, op, arglocs, flags=0):
         l0, l1, res = arglocs
         if flags:
@@ -806,18 +810,98 @@
             else:
                 cb.emit_no_collect()
 
+    def simple_call(self, fnloc, arglocs, result_loc=r.x0):
+        if result_loc is None:
+            result_type = VOID
+            result_size = 0
+        elif result_loc.is_vfp_reg():
+            result_type = FLOAT
+            result_size = WORD
+        else:
+            result_type = INT
+            result_size = WORD
+        cb = Aarch64CallBuilder(self, fnloc, arglocs,
+                                     result_loc, result_type,
+                                     result_size)
+        cb.emit()
+
     def emit_guard_op_guard_not_forced(self, op, guard_op, fcond, arglocs):
         # arglocs is call locs + guard_locs, split them
-        assert fcond == op.numargs() + 3
-        call_args = arglocs[:fcond]
-        guard_locs = arglocs[fcond:]
-        self._store_force_index(guard_op)
-        self._emit_call(op, call_args)
+        if rop.is_call_assembler(op.getopnum()):
+            if fcond == 4:
+                [argloc, vloc, result_loc, tmploc] = arglocs[:4]
+            else:
+                [argloc, result_loc, tmploc] = arglocs[:3]
+                vloc = locations.imm(0)
+            guard_locs = arglocs[fcond:]
+            self._store_force_index(guard_op)
+            self.call_assembler(op, argloc, vloc, result_loc, tmploc)
+        else:
+            assert fcond == op.numargs() + 3
+            call_args = arglocs[:fcond]
+            guard_locs = arglocs[fcond:]
+            self._store_force_index(guard_op)
+            self._emit_call(op, call_args)
+        # process the guard_not_forced
         ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
         self.mc.LDR_ri(r.ip0.value, r.fp.value, ofs)
         self.mc.CMP_ri(r.ip0.value, 0)
         self._emit_guard(guard_op, c.EQ, guard_locs)
 
+    def _call_assembler_emit_call(self, addr, argloc, resloc):
+        ofs = self.saved_threadlocal_addr
+        # we are moving the threadlocal directly to x1, to avoid strange
+        # dances
+        self.mc.LDR_ri(r.x1.value, r.sp.value, ofs)
+        self.simple_call(addr, [argloc], result_loc=resloc)
+
+    def _call_assembler_emit_helper_call(self, addr, arglocs, resloc):
+        self.simple_call(addr, arglocs, result_loc=resloc)
+
+    def _call_assembler_check_descr(self, value, tmploc):
+        ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
+        self.mc.LDR_ri(r.ip0.value, tmploc.value, ofs)
+        if check_imm_arg(value):
+            self.mc.CMP_ri(r.ip0.value, value)
+        else:
+            self.mc.gen_load_int(r.ip1.value, value)
+            self.mc.CMP_rr(r.ip0.value, r.ip1.value)
+        pos = self.mc.currpos()
+        self.mc.BRK()
+        return pos
+
+    def _call_assembler_patch_je(self, result_loc, jmp_location):
+        pos = self.mc.currpos()
+        self.mc.BRK()
+        #
+        pmc = OverwritingBuilder(self.mc, jmp_location, WORD)
+        pmc.B_ofs_cond(self.mc.currpos() - jmp_location, c.EQ)
+        return pos
+
+    def _call_assembler_load_result(self, op, result_loc):
+        if op.type != 'v':
+            # load the return value from (tmploc, 0)
+            kind = op.type
+            descr = self.cpu.getarraydescr_for_frame(kind)
+            if kind == FLOAT:
+                ofs = self.cpu.unpack_arraydescr(descr)
+                assert check_imm_arg(ofs)
+                assert result_loc.is_vfp_reg()
+                # we always have a register here, since we have to sync them
+                # before call_assembler
+                self.mc.LDR_di(result_loc.value, r.x0.value, ofs)
+            else:
+                assert result_loc is r.x0
+                ofs = self.cpu.unpack_arraydescr(descr)
+                assert check_imm_arg(ofs)
+                self.mc.LDR_ri(result_loc.value, r.x0.value, ofs)
+
+    def _call_assembler_patch_jmp(self, jmp_location):
+        # merge point
+        currpos = self.mc.currpos()
+        pmc = OverwritingBuilder(self.mc, jmp_location, WORD)
+        pmc.B_ofs(currpos - jmp_location)
+
     def _store_force_index(self, guard_op):
         faildescr = guard_op.getdescr()
         faildescrindex = self.get_gcref_from_faildescr(faildescr)
diff --git a/rpython/jit/backend/aarch64/regalloc.py 
b/rpython/jit/backend/aarch64/regalloc.py
--- a/rpython/jit/backend/aarch64/regalloc.py
+++ b/rpython/jit/backend/aarch64/regalloc.py
@@ -640,7 +640,13 @@
         if rop.is_call_release_gil(prev_op.getopnum()):
             arglocs = self._prepare_call(prev_op, save_all_regs=True,
                                          first_arg_index=2)
+        elif rop.is_call_assembler(prev_op.getopnum()):
+            locs = self.locs_for_call_assembler(prev_op)
+            tmploc = self.get_scratch_reg(INT, selected_reg=r.x0)
+            resloc = self._call(prev_op, locs + [tmploc], gc_level=2)
+            arglocs = locs + [resloc, tmploc]
         else:
+            assert rop.is_call_may_force(prev_op.getopnum())
             arglocs = self._prepare_call(prev_op, save_all_regs=True)
         guard_locs = self._guard_impl(op)
         return arglocs + guard_locs, len(arglocs)
diff --git a/rpython/jit/backend/test/runner_test.py 
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -3722,7 +3722,8 @@
     def test_assembler_call(self):
         called = []
         def assembler_helper(deadframe, virtualizable):
-            assert self.cpu.get_int_value(deadframe, 0) == 97
+            print "CALLED ASSEMBLER HELPER"
+            called.append(self.cpu.get_int_value(deadframe, 0))
             called.append(self.cpu.get_latest_descr(deadframe))
             return 4 + 9
 
@@ -3776,7 +3777,7 @@
         args = [i+1 for i in range(10)]
         deadframe = self.cpu.execute_token(othertoken, *args)
         assert self.cpu.get_int_value(deadframe, 0) == 13
-        assert called == [finish_descr]
+        assert called == [97, finish_descr]
 
         # test the fast path, which should not call assembler_helper()
         del called[:]
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to