[pypy-commit] pypy s390x-backend: adding jump instruction and working on correct assembly of guard failure
plan_rich
noreply at buildbot.pypy.org
Wed Oct 28 07:02:27 EDT 2015
Author: Richard Plangger <planrichi at 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)
More information about the pypy-commit
mailing list