Author: Richard Plangger <planri...@gmail.com> Branch: s390x-backend Changeset: r80472:dd415ed2de42 Date: 2015-10-28 12:01 +0100 http://bitbucket.org/pypy/pypy/changeset/dd415ed2de42/
Log: adding jump instruction and working on correct assembly of guard failure diff --git a/rpython/jit/backend/llsupport/jump.py b/rpython/jit/backend/llsupport/jump.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/llsupport/jump.py @@ -0,0 +1,109 @@ +def remap_frame_layout(assembler, src_locations, dst_locations, tmpreg): + pending_dests = len(dst_locations) + srccount = {} # maps dst_locations to how many times the same + # location appears in src_locations + for dst in dst_locations: + key = dst.as_key() + assert key not in srccount, "duplicate value in dst_locations!" + srccount[key] = 0 + for i in range(len(dst_locations)): + src = src_locations[i] + if src.is_imm(): + continue + key = src.as_key() + if key in srccount: + if key == dst_locations[i].as_key(): + # ignore a move "x = x" + # setting any "large enough" negative value is ok, but + # be careful of overflows, don't use -sys.maxint + srccount[key] = -len(dst_locations) - 1 + pending_dests -= 1 + else: + srccount[key] += 1 + + while pending_dests > 0: + progress = False + for i in range(len(dst_locations)): + dst = dst_locations[i] + key = dst.as_key() + if srccount[key] == 0: + srccount[key] = -1 # means "it's done" + pending_dests -= 1 + src = src_locations[i] + if not src.is_imm(): + key = src.as_key() + if key in srccount: + srccount[key] -= 1 + _move(assembler, src, dst, tmpreg) + progress = True + if not progress: + # we are left with only pure disjoint cycles + sources = {} # maps dst_locations to src_locations + for i in range(len(dst_locations)): + src = src_locations[i] + dst = dst_locations[i] + sources[dst.as_key()] = src + # + for i in range(len(dst_locations)): + dst = dst_locations[i] + originalkey = dst.as_key() + if srccount[originalkey] >= 0: + assembler.regalloc_push(dst, 0) + while True: + key = dst.as_key() + assert srccount[key] == 1 + # ^^^ because we are in a simple cycle + srccount[key] = -1 + pending_dests -= 1 + src = sources[key] + if src.as_key() == originalkey: + break + _move(assembler, src, dst, tmpreg) + dst = src + assembler.regalloc_pop(dst, 0) + assert pending_dests == 0 + +def _move(assembler, src, dst, tmpreg): + if dst.is_stack() and src.is_stack(): + assembler.regalloc_mov(src, tmpreg) + src = tmpreg + assembler.regalloc_mov(src, dst) + +def remap_frame_layout_mixed(assembler, + src_locations1, dst_locations1, tmpreg1, + src_locations2, dst_locations2, tmpreg2): + # find and push the fp stack locations from src_locations2 that + # are going to be overwritten by dst_locations1 + # TODO + from rpython.jit.backend.zarch.arch import WORD + extrapushes = [] + dst_keys = {} + for loc in dst_locations1: + dst_keys[loc.as_key()] = None + src_locations2red = [] + dst_locations2red = [] + for i in range(len(src_locations2)): + loc = src_locations2[i] + dstloc = dst_locations2[i] + if loc.is_stack(): + key = loc.as_key() + if (key in dst_keys or (loc.width > WORD and + (key + 1) in dst_keys)): + assembler.regalloc_push(loc, len(extrapushes)) + extrapushes.append(dstloc) + continue + src_locations2red.append(loc) + dst_locations2red.append(dstloc) + src_locations2 = src_locations2red + dst_locations2 = dst_locations2red + # + # remap the integer and pointer registers and stack locations + remap_frame_layout(assembler, src_locations1, dst_locations1, tmpreg1) + # + # remap the fp registers and stack locations + remap_frame_layout(assembler, src_locations2, dst_locations2, tmpreg2) + # + # finally, pop the extra fp stack locations + while len(extrapushes) > 0: + loc = extrapushes.pop() + assembler.regalloc_pop(loc, len(extrapushes)) 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 @@ -16,7 +16,8 @@ from rpython.jit.metainterp.resoperation import rop from rpython.rlib.debug import (debug_print, debug_start, debug_stop, have_debug_prints) -from rpython.jit.metainterp.history import (INT, REF, FLOAT) +from rpython.jit.metainterp.history import (INT, REF, FLOAT, + TargetToken) from rpython.rlib.rarithmetic import r_uint from rpython.rlib.objectmodel import we_are_translated, specialize, compute_unique_id from rpython.rlib import rgc @@ -208,6 +209,21 @@ self.failure_recovery_code[exc + 2 * withfloats] = rawstart self.mc = None + def generate_quick_failure(self, guardtok): + startpos = self.mc.currpos() + fail_descr, target = self.store_info_on_descr(startpos, guardtok) + assert target != 0 + self.load_gcmap(self.mc, r.r2, gcmap=guardtok.gcmap) + self.mc.write('\x00\x00\x00\x00') + #load_imm(r.r0, target) + #self.mc.mtctr(r.r0.value) + #self.mc.load_imm(r.r0, fail_descr) + #self.mc.bctr() + # we need to write at least 6 insns here, for patch_jump_for_descr() + #while self.mc.currpos() < startpos + 6 * 4: + # self.mc.trap() + return startpos + def _build_wb_slowpath(self, withcards, withfloats=False, for_frame=False): pass # TODO @@ -309,9 +325,9 @@ ops_offset = self.mc.ops_offset if not we_are_translated(): # used only by looptoken.dump() -- useful in tests - looptoken._ppc_rawstart = rawstart - looptoken._ppc_fullsize = full_size - looptoken._ppc_ops_offset = ops_offset + looptoken._zarch_rawstart = rawstart + looptoken._zarch_fullsize = full_size + looptoken._zarch_ops_offset = ops_offset looptoken._ll_function_addr = rawstart if logger: logger.log_loop(inputargs, operations, 0, "rewritten", @@ -328,7 +344,7 @@ frame_depth = regalloc.get_final_frame_depth() jump_target_descr = regalloc.jump_target_descr if jump_target_descr is not None: - tgt_depth = jump_target_descr._ppc_clt.frame_info.jfi_frame_depth + tgt_depth = jump_target_descr._zarch_clt.frame_info.jfi_frame_depth target_frame_depth = tgt_depth - JITFRAME_FIXED_SIZE frame_depth = max(frame_depth, target_frame_depth) return frame_depth @@ -375,7 +391,7 @@ # move to memory elif loc.is_stack(): offset = loc.value - self.mc.store(prev_loc, r.SPP, offset) + self.mc.STG(prev_loc, l.addr(offset, r.SPP)) return assert 0, "not supported location" elif prev_loc.is_imm_float(): @@ -522,6 +538,24 @@ def emit_label(self, op, arglocs, regalloc): pass + def emit_jump(self, op, arglocs, regalloc): + # The backend's logic assumes that the target code is in a piece of + # assembler that was also called with the same number of arguments, + # so that the locations [ebp+8..] of the input arguments are valid + # stack locations both before and after the jump. + # + descr = op.getdescr() + assert isinstance(descr, TargetToken) + my_nbargs = self.current_clt._debug_nbargs + target_nbargs = descr._zarch_clt._debug_nbargs + assert my_nbargs == target_nbargs + + if descr in self.target_tokens_currently_compiling: + self.mc.b_offset(descr._ll_loop_code) + else: + self.mc.b_abs(descr._ll_loop_code) + + def emit_finish(self, op, arglocs, regalloc): base_ofs = self.cpu.get_baseofs_of_frame_field() if len(arglocs) > 1: @@ -552,7 +586,7 @@ gcmap = self._finish_gcmap else: gcmap = lltype.nullptr(jitframe.GCMAP) - # TODO self.load_gcmap(self.mc, r.r2, gcmap) + self.load_gcmap(self.mc, r.r2, gcmap) assert fail_descr_loc.getint() <= 2**12-1 self.mc.LGHI(r.r5, fail_descr_loc) @@ -566,8 +600,8 @@ def load_gcmap(self, mc, reg, gcmap): # load the current gcmap into register 'reg' ptr = rffi.cast(lltype.Signed, gcmap) - #mc.LGHI(mc.pool - #mc.load_imm(reg, ptr) + assert 0 <= ptr <= 2**15-1 + mc.LGHI(reg, loc.imm(ptr)) def notimplemented_op(asm, op, arglocs, regalloc): print "[ZARCH/asm] %s not implemented" % op.getopname() 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 @@ -95,6 +95,10 @@ def currpos(self): return self.get_relative_pos() + def b_offset(self, reladdr): + offset = reladdr - self.get_relative_pos() + self.BRC(l.imm(0xf), l.imm(offset)) + def cmp_op(self, a, b, pool=False, signed=True, fp=False): if fp == True: xxx diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py --- a/rpython/jit/backend/zarch/opassembler.py +++ b/rpython/jit/backend/zarch/opassembler.py @@ -69,7 +69,9 @@ token.pos_jump_offset = self.mc.currpos() assert token.guard_not_invalidated() == is_guard_not_invalidated if not is_guard_not_invalidated: - self.mc.trap() # has to be patched later on + pass + # TODO + #self.mc.trap() # has to be patched later on self.pending_guard_tokens.append(token) def build_guard_token(self, op, frame_depth, arglocs, fcond): diff --git a/rpython/jit/backend/zarch/regalloc.py b/rpython/jit/backend/zarch/regalloc.py --- a/rpython/jit/backend/zarch/regalloc.py +++ b/rpython/jit/backend/zarch/regalloc.py @@ -1,6 +1,7 @@ from rpython.jit.backend.llsupport.regalloc import (RegisterManager, FrameManager, TempVar, compute_vars_longevity, BaseRegalloc) +from rpython.jit.backend.llsupport.jump import remap_frame_layout_mixed from rpython.jit.backend.zarch.arch import WORD from rpython.jit.codewriter import longlong from rpython.jit.backend.zarch.locations import imm, get_fp_offset @@ -561,6 +562,39 @@ if jump_op is not None and jump_op.getdescr() is descr: self._compute_hint_frame_locations_from_descr(descr) + def prepare_jump(self, op): + descr = op.getdescr() + assert isinstance(descr, TargetToken) + self.jump_target_descr = descr + arglocs = self.assembler.target_arglocs(descr) + + # get temporary locs + tmploc = r.SCRATCH + fptmploc = r.f0 + + # Part about non-floats + src_locations1 = [] + dst_locations1 = [] + src_locations2 = [] + dst_locations2 = [] + + # Build the four lists + for i in range(op.numargs()): + box = op.getarg(i) + src_loc = self.loc(box) + dst_loc = arglocs[i] + if box.type != FLOAT: + src_locations1.append(src_loc) + dst_locations1.append(dst_loc) + else: + src_locations2.append(src_loc) + dst_locations2.append(dst_loc) + + remap_frame_layout_mixed(self.assembler, + src_locations1, dst_locations1, tmploc, + src_locations2, dst_locations2, fptmploc) + return [] + def prepare_finish(self, op): descr = op.getdescr() fail_descr = cast_instance_to_gcref(descr) diff --git a/rpython/jit/backend/zarch/registers.py b/rpython/jit/backend/zarch/registers.py --- a/rpython/jit/backend/zarch/registers.py +++ b/rpython/jit/backend/zarch/registers.py @@ -13,6 +13,7 @@ RETURN = r14 POOL = r13 SPP = r11 +SCRATCH = r0 [f0,f1,f2,f3,f4,f5,f6,f7,f8, f9,f10,f11,f12,f13,f14,f15] = fpregisters diff --git a/rpython/jit/backend/zarch/runner.py b/rpython/jit/backend/zarch/runner.py --- a/rpython/jit/backend/zarch/runner.py +++ b/rpython/jit/backend/zarch/runner.py @@ -1,7 +1,8 @@ from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU +from rpython.jit.backend.zarch import registers as r from rpython.jit.backend.zarch.assembler import AssemblerZARCH +from rpython.rlib import rgc from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rlib import rgc class AbstractZARCHCPU(AbstractLLCPU): def __init__(self, rtyper, stats, opts=None, translate_support_code=False, @@ -18,6 +19,15 @@ class CPU_S390_64(AbstractZARCHCPU): supports_floats = True + IS_64_BIT = True + + frame_reg = r.SP + all_reg_indexes = [-1] * 32 + for _i, _r in enumerate(r.MANAGED_REGS): + all_reg_indexes[_r.value] = _i + gen_regs = r.MANAGED_REGS + float_regs = r.MANAGED_FP_REGS + def setup(self): self.assembler = AssemblerZARCH(self) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit