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