Author: Richard Plangger <planri...@gmail.com> Branch: s390x-backend Changeset: r82140:6cf6a1b5353a Date: 2016-02-10 12:43 +0100 http://bitbucket.org/pypy/pypy/changeset/6cf6a1b5353a/
Log: saving f8 through f15 before entering the jit and restoring it before exiting it. (ABI demands this) diff --git a/rpython/jit/backend/zarch/arch.py b/rpython/jit/backend/zarch/arch.py --- a/rpython/jit/backend/zarch/arch.py +++ b/rpython/jit/backend/zarch/arch.py @@ -83,3 +83,9 @@ JUMPABS_TARGET_ADDR__POOL_OFFSET = 0 JUMPABS_POOL_ADDR_POOL_OFFSET = 8 + +# r8 through r15 are saved registers (= non volatile) +# thus when entering the jit, we do not know if those +# are overwritten in the jit. save them using some extra +# stack space! +JIT_ENTER_EXTRA_STACK_SPACE = 8*8 diff --git a/rpython/jit/backend/zarch/assembler.py b/rpython/jit/backend/zarch/assembler.py --- a/rpython/jit/backend/zarch/assembler.py +++ b/rpython/jit/backend/zarch/assembler.py @@ -17,7 +17,7 @@ STD_FRAME_SIZE_IN_BYTES, THREADLOCAL_ADDR_OFFSET, RECOVERY_GCMAP_POOL_OFFSET, RECOVERY_TARGET_POOL_OFFSET, JUMPABS_TARGET_ADDR__POOL_OFFSET, JUMPABS_POOL_ADDR_POOL_OFFSET, - THREADLOCAL_ON_ENTER_JIT) + THREADLOCAL_ON_ENTER_JIT, JIT_ENTER_EXTRA_STACK_SPACE) from rpython.jit.backend.zarch.opassembler import OpAssembler from rpython.jit.backend.zarch.regalloc import Regalloc from rpython.jit.codewriter.effectinfo import EffectInfo @@ -50,6 +50,7 @@ self.gcrootmap_retaddr_forced = 0 self.failure_recovery_code = [0, 0, 0, 0] self.wb_slowpath = [0,0,0,0,0] + self.pool = None def setup(self, looptoken): BaseAssembler.setup(self, looptoken) @@ -57,7 +58,8 @@ if we_are_translated(): self.debug = False self.current_clt = looptoken.compiled_loop_token - self.mc = InstrBuilder() + self.pool = LiteralPool() + self.mc = InstrBuilder(self.pool) self.pending_guard_tokens = [] self.pending_guard_tokens_recovered = 0 #assert self.datablockwrapper is None --- but obscure case @@ -68,7 +70,6 @@ self.mc.datablockwrapper = self.datablockwrapper self.target_tokens_currently_compiling = {} self.frame_depth_to_patch = [] - self.pool = LiteralPool() def teardown(self): self.pending_guard_tokens = None @@ -91,7 +92,7 @@ self.mc.BCR_rr(0xf, register.value) def _build_failure_recovery(self, exc, withfloats=False): - mc = InstrBuilder() + mc = InstrBuilder(self.pool) self.mc = mc # fill in the jf_descr and jf_gcmap fields of the frame according # to which failure we are resuming from. These are set before @@ -202,6 +203,7 @@ mc.LAY(r.SP, l.addr(-extra_stack_size, r.SP)) mc.STMG(r.r10, r.r12, l.addr(off, r.SP)) mc.STG(r.r2, l.addr(off+3*WORD, r.SP)) + # OK to use STD, because offset is not negative mc.STD(r.f0, l.addr(off+4*WORD, r.SP)) saved_regs = None saved_fp_regs = None @@ -1008,14 +1010,22 @@ def _call_header(self): # Build a new stackframe of size STD_FRAME_SIZE_IN_BYTES - self.mc.STMG(r.r6, r.r15, l.addr(6*WORD, r.SP)) + fpoff = JIT_ENTER_EXTRA_STACK_SPACE + self.mc.STMG(r.r6, r.r15, l.addr(-fpoff+6*WORD, r.SP)) self.mc.LARL(r.POOL, l.halfword(self.pool.pool_start - self.mc.get_relative_pos())) + # f8 through f15 are saved registers (= non volatile) + # TODO it would be good to detect if any float is used in the loop + # and to skip this push/pop whenever no float operation occurs + for i,reg in enumerate(range(8,16)): + off = -fpoff + STD_FRAME_SIZE_IN_BYTES + assert off > 0 + self.mc.STD_rx(reg, l.addr(off + i*8, r.SP)) # save r3, the second argument, to the thread local position self.mc.STG(r.r3, l.addr(THREADLOCAL_ON_ENTER_JIT, r.SP)) - # push a standard frame for any call - self.mc.push_std_frame() + # push a standard frame for any within the jit trace + self.mc.push_std_frame(fpoff) # move the first argument to SPP: the jitframe object self.mc.LGR(r.SPP, r.r2) @@ -1060,8 +1070,13 @@ if gcrootmap and gcrootmap.is_shadow_stack: self._call_footer_shadowstack(gcrootmap) + size = STD_FRAME_SIZE_IN_BYTES + # f8 through f15 are saved registers (= non volatile) + # TODO it would be good to detect if any float is used in the loop + # and to skip this push/pop whenever no float operation occurs + for i,reg in enumerate(range(8,16)): + self.mc.LD_rx(reg, l.addr(size + size + i*8, r.SP)) # restore registers r6-r15 - size = STD_FRAME_SIZE_IN_BYTES self.mc.LMG(r.r6, r.r15, l.addr(size+6*WORD, r.SP)) self.jmpto(r.r14) diff --git a/rpython/jit/backend/zarch/codebuilder.py b/rpython/jit/backend/zarch/codebuilder.py --- a/rpython/jit/backend/zarch/codebuilder.py +++ b/rpython/jit/backend/zarch/codebuilder.py @@ -69,9 +69,10 @@ RAW_CALL_REG = r.r14 - def __init__(self): + def __init__(self, pool=None): AbstractZARCHBuilder.__init__(self) self.init_block_builder() + self.pool = pool # # ResOperation --> offset in the assembly. # ops_offset[None] represents the beginning of the code after the last op @@ -173,6 +174,9 @@ elif -2**31 <= word <= 2**31-1: self.LGFI(dest_reg, l.imm(word)) else: + if self.pool and self.pool.contains_constant(word): + self.LG(dest_reg, l.pool(self.pool.get_direct_offset(word))) + return # this is not put into the constant pool, because it # is an immediate value that cannot easily be forseen self.IILF(dest_reg, l.imm(word & 0xFFFFffff)) diff --git a/rpython/jit/backend/zarch/pool.py b/rpython/jit/backend/zarch/pool.py --- a/rpython/jit/backend/zarch/pool.py +++ b/rpython/jit/backend/zarch/pool.py @@ -95,6 +95,9 @@ if arg.is_constant(): self.reserve_literal(8, arg) + def contains_constant(self, unique_val): + return unique_val in self.offset_map + def get_descr_offset(self, descr): return self.offset_descr[descr] @@ -105,6 +108,11 @@ assert self.offset_map[uvalue] >= 0 return self.offset_map[uvalue] + def get_direct_offset(self, unique_val): + """ Get the offset directly using a unique value, + use get_offset if you have a Const box """ + return self.offset_map[unique_val] + def unique_value(self, val): if val.type == FLOAT: if val.getfloat() == 0.0: @@ -170,6 +178,8 @@ self.pool_start = asm.mc.get_relative_pos() for op in operations: self.ensure_can_hold_constants(asm, op) + self.ensure_value(asm.cpu.pos_exc_value()) + # TODO add more values that are loaded with load_imm if self.size == 0: # no pool needed! return diff --git a/rpython/jit/backend/zarch/test/test_calling_convention.py b/rpython/jit/backend/zarch/test/test_calling_convention.py --- a/rpython/jit/backend/zarch/test/test_calling_convention.py +++ b/rpython/jit/backend/zarch/test/test_calling_convention.py @@ -5,7 +5,7 @@ import rpython.jit.backend.zarch.conditions as c -class TestPPCCallingConvention(CallingConvTests): +class TestZARCHCallingConvention(CallingConvTests): # ../../test/calling_convention_test.py def make_function_returning_stack_pointer(self): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit