[pypy-commit] pypy s390x-backend: removed pool and loading constant using immediate values, test_runner passes already
plan_rich
pypy.commits at gmail.com
Wed Mar 2 10:03:31 EST 2016
Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r82656:62b48d6dd7ca
Date: 2016-03-02 14:41 +0100
http://bitbucket.org/pypy/pypy/changeset/62b48d6dd7ca/
Log: removed pool and loading constant using immediate values,
test_runner passes already
diff --git a/rpython/jit/backend/llsupport/tl/test/code_strategies.py b/rpython/jit/backend/llsupport/tl/test/code_strategies.py
--- a/rpython/jit/backend/llsupport/tl/test/code_strategies.py
+++ b/rpython/jit/backend/llsupport/tl/test/code_strategies.py
@@ -73,4 +73,3 @@
inst = clazz.create_from(draw, get_strategy_for)
bytecode, consts = code.Context().transform([inst])
return bytecode, consts
-
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
@@ -50,7 +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
+ # self.pool = None
def setup(self, looptoken):
BaseAssembler.setup(self, looptoken)
@@ -58,8 +58,8 @@
if we_are_translated():
self.debug = False
self.current_clt = looptoken.compiled_loop_token
- self.pool = LiteralPool()
- self.mc = InstrBuilder(self.pool)
+ # POOL self.pool = LiteralPool()
+ self.mc = InstrBuilder(None)
self.pending_guard_tokens = []
self.pending_guard_tokens_recovered = 0
#assert self.datablockwrapper is None --- but obscure case
@@ -76,7 +76,8 @@
self.current_clt = None
self._regalloc = None
self.mc = None
- self.pool = None
+ # self.pool = None
+
def target_arglocs(self, looptoken):
return looptoken._zarch_arglocs
@@ -92,7 +93,7 @@
self.mc.BCR_rr(0xf, register.value)
def _build_failure_recovery(self, exc, withfloats=False):
- mc = InstrBuilder(self.pool)
+ mc = InstrBuilder(None)
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
@@ -132,20 +133,23 @@
startpos = self.mc.currpos()
fail_descr, target = self.store_info_on_descr(startpos, guardtok)
assert target != 0
- pool_offset = guardtok._pool_offset
- assert pool_offset != -1
+ # POOL
+ #pool_offset = guardtok._pool_offset
+ #assert pool_offset != -1
# overwrite the gcmap in the jitframe
- offset = pool_offset + RECOVERY_GCMAP_POOL_OFFSET
- self.mc.LG(r.SCRATCH2, l.pool(offset))
+ #offset = pool_offset + RECOVERY_GCMAP_POOL_OFFSET
+ #self.mc.LG(r.SCRATCH2, l.pool(offset))
+ ## overwrite the target in pool
+ #offset = pool_offset + RECOVERY_TARGET_POOL_OFFSET
+ ## overwrite!!
+ #self.pool.overwrite_64(self.mc, offset, target)
+ #self.mc.LG(r.r14, l.pool(offset))
- # overwrite the target in pool
- offset = pool_offset + RECOVERY_TARGET_POOL_OFFSET
- self.pool.overwrite_64(self.mc, offset, target)
- self.mc.LG(r.r14, l.pool(offset))
-
+ self.load_gcmap(self.mc, r.SCRATCH2, gcmap=guardtok.gcmap)
+ self.mc.load_imm(r.r14, target)
self.mc.load_imm(r.SCRATCH, fail_descr)
- self.mc.BCR(l.imm(0xf), r.r14)
+ self.mc.BCR(c.ANY, r.r14)
return startpos
@@ -632,7 +636,7 @@
#
operations = regalloc.prepare_loop(inputargs, operations,
looptoken, clt.allgcrefs)
- self.pool.pre_assemble(self, operations)
+ # POOL self.pool.pre_assemble(self, operations)
entrypos = self.mc.get_relative_pos()
self._call_header_with_stack_check()
looppos = self.mc.get_relative_pos()
@@ -641,7 +645,7 @@
self.update_frame_depth(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
#
size_excluding_failure_stuff = self.mc.get_relative_pos()
- self.pool.post_assemble(self)
+ # POOL self.pool.post_assemble(self)
self.write_pending_failure_recoveries()
full_size = self.mc.get_relative_pos()
#
@@ -700,13 +704,13 @@
operations,
self.current_clt.allgcrefs,
self.current_clt.frame_info)
- self.pool.pre_assemble(self, operations, bridge=True)
+ # POOL self.pool.pre_assemble(self, operations, bridge=True)
startpos = self.mc.get_relative_pos()
- self.mc.LARL(r.POOL, l.halfword(self.pool.pool_start - startpos))
+ # POOL self.mc.LARL(r.POOL, l.halfword(self.pool.pool_start - startpos))
self._check_frame_depth(self.mc, regalloc.get_gcmap())
frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations)
codeendpos = self.mc.get_relative_pos()
- self.pool.post_assemble(self)
+ # POOL self.pool.post_assemble(self)
self.write_pending_failure_recoveries()
fullsize = self.mc.get_relative_pos()
#
@@ -733,7 +737,7 @@
# to 'adr_new_target'.
# Updates the pool address
mc = InstrBuilder()
- mc.write_i64(adr_new_target)
+ mc.b_abs(adr_new_target)
mc.copy_to_raw_memory(faildescr.adr_jump_offset)
assert faildescr.adr_jump_offset != 0
faildescr.adr_jump_offset = 0 # means "patched"
@@ -878,14 +882,16 @@
self.mc.STG(r.SCRATCH, l.addr(offset, r.SPP))
return
assert 0, "not supported location"
- elif prev_loc.is_in_pool():
- if loc.is_reg():
- self.mc.LG(loc, prev_loc)
+ elif prev_loc.is_imm_float():
+ self.mc.load_imm(r.SCRATCH, prev_loc.value)
+ if loc.is_fp_reg():
+ self.mc.LDY(loc, l.addr(0, r.SCRATCH))
return
- elif loc.is_fp_reg():
- self.mc.LDY(loc, prev_loc)
+ elif loc.is_stack():
+ src_adr = l.addr(0, r.SCRATCH)
+ tgt_adr = l.AddressLocation(r.SPP, None, loc.value, l.imm(7))
+ self.mc.MVC(tgt_adr, src_adr)
return
- assert 0, "not supported location (previous is pool loc)"
elif prev_loc.is_stack():
offset = prev_loc.value
# move from memory to register
@@ -989,9 +995,11 @@
for tok in self.pending_guard_tokens:
addr = rawstart + tok.pos_jump_offset
#
- tok.faildescr.adr_jump_offset = rawstart + \
- self.pool.pool_start + tok._pool_offset + \
- RECOVERY_TARGET_POOL_OFFSET
+ # POOL
+ #tok.faildescr.adr_jump_offset = rawstart + \
+ # self.pool.pool_start + tok._pool_offset + \
+ # RECOVERY_TARGET_POOL_OFFSET
+ tok.faildescr.adr_jump_offset = rawstart + tok.pos_recovery_stub
relative_target = tok.pos_recovery_stub - tok.pos_jump_offset
#
if not tok.guard_not_invalidated():
@@ -1011,7 +1019,7 @@
# Build a new stackframe of size STD_FRAME_SIZE_IN_BYTES
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()))
+ # POOL 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
@@ -1172,9 +1180,11 @@
# ASSEMBLER EMISSION
def emit_label(self, op, arglocs, regalloc):
- offset = self.pool.pool_start - self.mc.get_relative_pos()
+ pass
+ # POOL
+ #offset = self.pool.pool_start - self.mc.get_relative_pos()
# load the pool address at each label
- self.mc.LARL(r.POOL, l.halfword(offset))
+ #self.mc.LARL(r.POOL, l.halfword(offset))
def emit_jump(self, op, arglocs, regalloc):
# The backend's logic assumes that the target code is in a piece of
@@ -1191,14 +1201,16 @@
if descr in self.target_tokens_currently_compiling:
# a label has a LARL instruction that does not need
# to be executed, thus remove the first opcode
- self.mc.b_offset(descr._ll_loop_code + self.mc.LARL_byte_count)
+ self.mc.b_offset(descr._ll_loop_code) # POOL + self.mc.LARL_byte_count)
else:
- offset = self.pool.get_descr_offset(descr) + \
- JUMPABS_TARGET_ADDR__POOL_OFFSET
- self.mc.LG(r.SCRATCH, l.pool(offset))
+ # POOL
+ #offset = self.pool.get_descr_offset(descr) + \
+ # JUMPABS_TARGET_ADDR__POOL_OFFSET
+ #self.mc.LG(r.SCRATCH, l.pool(offset))
+ #self.pool.overwrite_64(self.mc, offset, descr._ll_loop_code)
+ self.mc.load_imm(r.SCRATCH, descr._ll_loop_code)
self.mc.BCR(c.ANY, r.SCRATCH)
- self.pool.overwrite_64(self.mc, offset, descr._ll_loop_code)
def emit_finish(self, op, arglocs, regalloc):
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
@@ -35,7 +35,7 @@
GuardToken.__init__(self, cpu, gcmap, descr, failargs, faillocs,
guard_opnum, frame_depth)
self.fcond = fcond
- self._pool_offset = -1
+ # POOL self._pool_offset = -1
class AbstractZARCHBuilder(object):
@@ -122,6 +122,10 @@
def currpos(self):
return self.get_relative_pos()
+ def b_abs(self, addr):
+ self.load_imm(r.r14, addr)
+ self.BCR(c.ANY, r.r14)
+
def b_cond_offset(self, offset, condition):
assert condition != c.cond_none
self.BRCL(condition, l.imm(offset))
@@ -171,7 +175,6 @@
# 64 bit unsigned
self.CLGR(a, b)
-
def load_imm(self, dest_reg, word):
if -2**15 <= word <= 2**15-1:
self.LGHI(dest_reg, l.imm(word))
@@ -181,8 +184,6 @@
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))
self.IIHF(dest_reg, l.imm((word >> 32) & 0xFFFFffff))
diff --git a/rpython/jit/backend/zarch/helper/assembler.py b/rpython/jit/backend/zarch/helper/assembler.py
--- a/rpython/jit/backend/zarch/helper/assembler.py
+++ b/rpython/jit/backend/zarch/helper/assembler.py
@@ -2,6 +2,7 @@
import rpython.jit.backend.zarch.registers as r
from rpython.rlib.rarithmetic import intmask
from rpython.jit.backend.zarch.arch import WORD
+from rpython.jit.backend.zarch.helper.regalloc import check_imm_value
from rpython.jit.metainterp.history import FLOAT
from rpython.jit.metainterp.resoperation import rop
from rpython.rtyper.lltypesystem import rffi, lltype
@@ -11,7 +12,8 @@
l1 = arglocs[1]
assert not l0.is_imm()
# do the comparison
- self.mc.cmp_op(l0, l1, pool=l1.is_in_pool(), imm=l1.is_imm(), signed=signed, fp=fp)
+ # POOL self.mc.cmp_op(l0, l1, pool=l1.is_in_pool(), imm=l1.is_imm(), signed=signed, fp=fp)
+ self.mc.cmp_op(l0, l1, imm=l1.is_imm(), signed=signed, fp=fp)
self.flush_cc(condition, arglocs[2])
@@ -28,43 +30,60 @@
f.name = 'emit_shift_' + func
return f
-def gen_emit_rr_or_rpool(rr_func, rp_func):
- """ the parameters can either be both in registers or
- the first is in the register, second in literal pool.
- """
+def gen_emit_rr(rr_func):
def f(self, op, arglocs, regalloc):
l0, l1 = arglocs
- if l1.is_imm() and not l1.is_in_pool():
- assert 0, "logical imm must reside in pool!"
- if l1.is_in_pool():
- getattr(self.mc, rp_func)(l0, l1)
- else:
- getattr(self.mc, rr_func)(l0, l1)
+ getattr(self.mc, rr_func)(l0, l1)
return f
-def gen_emit_imm_pool_rr(imm_func, pool_func, rr_func):
+# POOL
+#def gen_emit_rr_or_rpool(rr_func, rp_func):
+# """ the parameters can either be both in registers or
+# the first is in the register, second in literal pool.
+# """
+# def f(self, op, arglocs, regalloc):
+# l0, l1 = arglocs
+# if l1.is_imm() and not l1.is_in_pool():
+# assert 0, "logical imm must reside in pool!"
+# if l1.is_in_pool():
+# getattr(self.mc, rp_func)(l0, l1)
+# else:
+# getattr(self.mc, rr_func)(l0, l1)
+# return f
+
+def gen_emit_rr_rh_ri(rr_func, rh_func, ri_func):
def emit(self, op, arglocs, regalloc):
l0, l1 = arglocs
- if l1.is_in_pool():
- getattr(self.mc, pool_func)(l0, l1)
- elif l1.is_imm():
- getattr(self.mc, imm_func)(l0, l1)
+ if l1.is_imm():
+ if check_imm_value(l1.value):
+ getattr(self.mc, rh_func)(l0, l1)
+ else:
+ getattr(self.mc, ri_func)(l0, l1)
else:
getattr(self.mc, rr_func)(l0, l1)
return emit
-def gen_emit_pool_or_rr_evenodd(pool_func, rr_func):
+# POOL
+#def gen_emit_imm_pool_rr(imm_func, pool_func, rr_func):
+# def emit(self, op, arglocs, regalloc):
+# l0, l1 = arglocs
+# if l1.is_in_pool():
+# getattr(self.mc, pool_func)(l0, l1)
+# elif l1.is_imm():
+# getattr(self.mc, imm_func)(l0, l1)
+# else:
+# getattr(self.mc, rr_func)(l0, l1)
+# return emit
+
+def gen_emit_div_mod(rr_func):
def emit(self, op, arglocs, regalloc):
lr, lq, l1 = arglocs # lr == remainer, lq == quotient
# when entering the function lr contains the dividend
# after this operation either lr or lq is used further
- assert l1.is_in_pool() or not l1.is_imm() , "imm divider not supported"
+ assert not l1.is_imm(), "imm divider not supported"
# remainer is always a even register r0, r2, ... , r14
assert lr.is_even()
assert lq.is_odd()
self.mc.XGR(lr, lr)
- if l1.is_in_pool():
- getattr(self.mc,pool_func)(lr, l1)
- else:
- getattr(self.mc,rr_func)(lr, l1)
+ getattr(self.mc,rr_func)(lr, l1)
return emit
diff --git a/rpython/jit/backend/zarch/helper/regalloc.py b/rpython/jit/backend/zarch/helper/regalloc.py
--- a/rpython/jit/backend/zarch/helper/regalloc.py
+++ b/rpython/jit/backend/zarch/helper/regalloc.py
@@ -26,7 +26,8 @@
if check_imm32(a1):
l1 = imm(a1.getint())
else:
- l1 = self.ensure_reg_or_pool(a1)
+ # POOL l1 = self.ensure_reg_or_pool(a1)
+ l1 = self.ensure_reg(a1)
l0 = self.force_result_in_reg(op, a0)
return [l0, l1]
@@ -38,7 +39,7 @@
if check_imm32(a1):
l1 = imm(a1.getint())
else:
- l1 = self.ensure_reg_or_pool(a1)
+ l1 = self.ensure_reg(a1)
l0 = self.force_result_in_reg(op, a0)
return [l0, l1]
@@ -50,7 +51,7 @@
if check_imm32(a1):
l1 = imm(a1.getint())
else:
- l1 = self.ensure_reg_or_pool(a1)
+ l1 = self.ensure_reg(a1)
lr,lq = self.rm.ensure_even_odd_pair(a0, op, bind_first=False)
return [lr, lq, l1]
@@ -60,11 +61,11 @@
a1 = op.getarg(1)
l1 = self.ensure_reg(a1)
if isinstance(a0, Const):
- poolloc = self.ensure_reg_or_pool(a0)
+ loc = self.ensure_reg(a0)
lr,lq = self.rm.ensure_even_odd_pair(a0, op,
bind_first=modulus, must_exist=False,
move_regs=False)
- self.assembler.regalloc_mov(poolloc, lq)
+ self.assembler.regalloc_mov(loc, lq)
else:
lr,lq = self.rm.ensure_even_odd_pair(a0, op, bind_first=modulus)
return [lr, lq, l1]
@@ -77,16 +78,18 @@
a0 = op.getarg(0)
a1 = op.getarg(1)
# sub is not commotative, thus cannot swap operands
- l1 = self.ensure_reg_or_pool(a1)
- l0 = self.force_result_in_reg(op, a0)
- return [l0, l1]
+ # POOL l1 = self.ensure_reg_or_pool(a1)
+ l0 = self.ensure_reg(a0)
+ l1 = self.ensure_reg(a1)
+ res = self.force_allocate_reg(op)
+ return [res, l0, l1]
def prepare_int_logic(self, op):
a0 = op.getarg(0)
a1 = op.getarg(1)
if a0.is_constant():
a0, a1 = a1, a0
- l1 = self.ensure_reg_or_pool(a1)
+ l1 = self.ensure_reg(a1)
l0 = self.force_result_in_reg(op, a0)
return [l0, l1]
@@ -120,7 +123,7 @@
def prepare_float_cmp_op(self, op):
l0 = self.ensure_reg(op.getarg(0))
- l1 = self.ensure_reg_or_pool(op.getarg(1))
+ l1 = self.ensure_reg(op.getarg(1))
res = self.force_allocate_reg_or_cc(op)
return [l0, l1, res]
@@ -139,7 +142,7 @@
if allow_swap:
if isinstance(a0, Const):
a0,a1 = a1,a0
- l1 = self.ensure_reg_or_pool(a1)
+ l1 = self.ensure_reg(a1)
l0 = self.force_result_in_reg(op, a0)
return [l0, l1]
return prepare_float_binary_op
diff --git a/rpython/jit/backend/zarch/instructions.py b/rpython/jit/backend/zarch/instructions.py
--- a/rpython/jit/backend/zarch/instructions.py
+++ b/rpython/jit/backend/zarch/instructions.py
@@ -26,6 +26,7 @@
# mul
'MSGR': ('rre', ['\xB9','\x0C']),
'MSG': ('rxy', ['\xE3','\x0C']),
+ 'MGHI': ('ri', ['\xA7','\x0D']),
'MSGFI': ('ril', ['\xC2','\x00']),
'MLGR': ('rre', ['\xB9','\x86'], 'eo,r'),
# div/mod
@@ -131,6 +132,7 @@
# move
'MVCLE': ('rs', ['\xA8'], 'eo,eo,bd'),
+ 'MVC': ('ssa', ['\xD2']),
# load memory
diff --git a/rpython/jit/backend/zarch/locations.py b/rpython/jit/backend/zarch/locations.py
--- a/rpython/jit/backend/zarch/locations.py
+++ b/rpython/jit/backend/zarch/locations.py
@@ -1,6 +1,8 @@
from rpython.jit.metainterp.history import INT, FLOAT
from rpython.jit.backend.zarch.arch import WORD, DOUBLE_WORD
+FWORD = 8
+
class AssemblerLocation(object):
_immutable_ = True
type = INT
@@ -60,6 +62,30 @@
def as_key(self): # 0 <= as_key <= 15
return self.value
+class ConstFloatLoc(AssemblerLocation):
+ """This class represents an imm float value which is stored in memory at
+ the address stored in the field value"""
+ _immutable_ = True
+ width = FWORD
+ type = FLOAT
+
+ def __init__(self, value):
+ self.value = value
+
+ def getint(self):
+ return self.value
+
+ def __repr__(self):
+ return "imm_float(stored at %d)" % (self.value)
+
+ def is_imm_float(self):
+ return True
+
+ def is_float(self):
+ return True
+
+ def as_key(self):
+ return self.value
class FloatRegisterLocation(RegisterLocation):
_immutable_ = True
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
@@ -3,8 +3,7 @@
STD_FRAME_SIZE_IN_BYTES)
from rpython.jit.backend.zarch.arch import THREADLOCAL_ADDR_OFFSET
from rpython.jit.backend.zarch.helper.assembler import (gen_emit_cmp_op,
- gen_emit_rr_or_rpool, gen_emit_shift, gen_emit_pool_or_rr_evenodd,
- gen_emit_imm_pool_rr)
+ gen_emit_rr, gen_emit_shift, gen_emit_rr_rh_ri, gen_emit_div_mod)
from rpython.jit.backend.zarch.helper.regalloc import (check_imm,
check_imm_value)
from rpython.jit.metainterp.history import (ConstInt)
@@ -29,29 +28,33 @@
class IntOpAssembler(object):
_mixin_ = True
- emit_int_add = gen_emit_imm_pool_rr('AGFI','AG','AGR')
+ emit_int_add = gen_emit_rr_rh_ri('AGR', 'AGHI', 'AGFI')
emit_int_add_ovf = emit_int_add
emit_nursery_ptr_increment = emit_int_add
def emit_int_sub(self, op, arglocs, regalloc):
- l0, l1 = arglocs
- if l1.is_imm() and not l1.is_in_pool():
- assert 0, "logical imm must reside in pool!"
- if l1.is_in_pool():
- self.mc.SG(l0, l1)
- else:
- self.mc.SGR(l0, l1)
+ res, l0, l1 = arglocs
+ self.mc.SGRK(res, l0, l1)
+ # POOL
+ #if l1.is_imm() and not l1.is_in_pool():
+ # assert 0, "logical imm must reside in pool!"
+ #if l1.is_in_pool():
+ # self.mc.SG(l0, l1)
+ #else:
+ # self.mc.SGR(l0, l1)
emit_int_sub_ovf = emit_int_sub
- emit_int_mul = gen_emit_imm_pool_rr('MSGFI', 'MSG', 'MSGR')
+ emit_int_mul = gen_emit_rr_rh_ri('MSGR', 'MGHI', 'MSGFI')
def emit_int_mul_ovf(self, op, arglocs, regalloc):
lr, lq, l1 = arglocs
- if l1.is_in_pool():
- self.mc.LG(r.SCRATCH, l1)
- l1 = r.SCRATCH
- elif l1.is_imm():
+ # POOL
+ # if l1.is_in_pool():
+ # self.mc.LG(r.SCRATCH, l1)
+ # l1 = r.SCRATCH
+ # elif
+ if l1.is_imm():
self.mc.LGFI(r.SCRATCH, l1)
l1 = r.SCRATCH
else:
@@ -77,7 +80,8 @@
mc.LPGR(lq, lq)
mc.LPGR(l1, l1)
mc.MLGR(lr, l1)
- mc.LG(r.SCRATCH, l.pool(self.pool.constant_64_sign_bit))
+ mc.LGHI(r.SCRATCH, l.imm(-1))
+ mc.RISBG(r.SCRATCH, r.SCRATCH, l.imm(0), l.imm(0x80 | 0), l.imm(0))
# is the value greater than 2**63 ? then an overflow occured
jmp_xor_lq_overflow = mc.get_relative_pos()
mc.reserve_cond_jump() # CLGRJ lq > 0x8000 ... 00 -> (label_overflow)
@@ -94,7 +98,9 @@
mc.LPGR(lq, lq)
mc.LPGR(l1, l1)
mc.MLGR(lr, l1)
- mc.LG(r.SCRATCH, l.pool(self.pool.constant_max_64_positive))
+ mc.LGHI(r.SCRATCH, l.imm(-1))
+ # 0xff -> shift 0 -> 0xff set MSB on pos 0 to zero -> 7f
+ mc.RISBG(r.SCRATCH, r.SCRATCH, l.imm(1), l.imm(0x80 | 63), l.imm(0))
jmp_lq_overflow = mc.get_relative_pos()
mc.reserve_cond_jump() # CLGRJ lq > 0x7fff ... ff -> (label_overflow)
jmp_lr_overflow = mc.get_relative_pos()
@@ -163,16 +169,17 @@
omc.BRC(c.ANY, l.imm(label_end - jmp_neither_lqlr_overflow))
omc.overwrite()
- emit_int_floordiv = gen_emit_pool_or_rr_evenodd('DSG','DSGR')
- emit_uint_floordiv = gen_emit_pool_or_rr_evenodd('DLG','DLGR')
+ emit_int_floordiv = gen_emit_div_mod('DSGR')
+ emit_uint_floordiv = gen_emit_div_mod('DLGR')
# NOTE division sets one register with the modulo value, thus
# the regalloc ensures the right register survives.
- emit_int_mod = gen_emit_pool_or_rr_evenodd('DSG','DSGR')
+ emit_int_mod = gen_emit_div_mod('DSGR')
def emit_int_invert(self, op, arglocs, regalloc):
l0, = arglocs
assert not l0.is_imm()
- self.mc.XG(l0, l.pool(self.pool.constant_64_ones))
+ self.mc.LGHI(r.SCRATCH, l.imm(-1))
+ self.mc.XGR(l0, r.SCRATCH)
def emit_int_neg(self, op, arglocs, regalloc):
l0, = arglocs
@@ -206,9 +213,9 @@
self.mc.CGHI(l0, l.imm(0))
self.flush_cc(c.NE, res)
- emit_int_and = gen_emit_rr_or_rpool("NGR", "NG")
- emit_int_or = gen_emit_rr_or_rpool("OGR", "OG")
- emit_int_xor = gen_emit_rr_or_rpool("XGR", "XG")
+ emit_int_and = gen_emit_rr("NGR")
+ emit_int_or = gen_emit_rr("OGR")
+ emit_int_xor = gen_emit_rr("XGR")
emit_int_rshift = gen_emit_shift("SRAG")
emit_int_lshift = gen_emit_shift("SLLG")
@@ -235,10 +242,10 @@
class FloatOpAssembler(object):
_mixin_ = True
- emit_float_add = gen_emit_rr_or_rpool('ADBR','ADB')
- emit_float_sub = gen_emit_rr_or_rpool('SDBR','SDB')
- emit_float_mul = gen_emit_rr_or_rpool('MDBR','MDB')
- emit_float_truediv = gen_emit_rr_or_rpool('DDBR','DDB')
+ emit_float_add = gen_emit_rr('ADBR')
+ emit_float_sub = gen_emit_rr('SDBR')
+ emit_float_mul = gen_emit_rr('MDBR')
+ emit_float_truediv = gen_emit_rr('DDBR')
# Support for NaNs: S390X sets condition code to 0x3 (unordered)
# whenever any operand is nan.
@@ -568,7 +575,8 @@
# scratch = (index >> card_page_shift) & 7
# 0x80 sets zero flag. will store 0 into all not selected bits
mc.RISBG(r.SCRATCH, loc_index, l.imm(61), l.imm(0x80 | 63), l.imm(64-n))
- mc.XG(tmp_loc, l.pool(self.pool.constant_64_ones))
+ mc.LGHI(r.SCRATCH2, l.imm(-1))
+ mc.XGR(tmp_loc, r.SCRATCH2)
# set SCRATCH2 to 1 << r1
mc.LGHI(r.SCRATCH2, l.imm(1))
@@ -636,7 +644,7 @@
token = ZARCHGuardToken(self.cpu, gcmap, descr, op.getfailargs(),
arglocs, op.getopnum(), frame_depth,
fcond)
- token._pool_offset = self.pool.get_descr_offset(descr)
+ #token._pool_offset = self.pool.get_descr_offset(descr)
return token
def emit_guard_true(self, op, arglocs, regalloc):
@@ -901,9 +909,9 @@
def _emit_gc_load(self, op, arglocs, regalloc):
result_loc, base_loc, ofs_loc, size_loc, sign_loc = arglocs
- assert not result_loc.is_in_pool()
- assert not base_loc.is_in_pool()
- assert not ofs_loc.is_in_pool()
+ # POOL assert not result_loc.is_in_pool()
+ # POOL assert not base_loc.is_in_pool()
+ # POOL assert not ofs_loc.is_in_pool()
if ofs_loc.is_imm():
assert self._mem_offset_supported(ofs_loc.value)
src_addr = l.addr(ofs_loc.value, base_loc)
@@ -917,15 +925,14 @@
def _emit_gc_load_indexed(self, op, arglocs, regalloc):
result_loc, base_loc, index_loc, offset_loc, size_loc, sign_loc=arglocs
- assert not result_loc.is_in_pool()
- assert not base_loc.is_in_pool()
- assert not index_loc.is_in_pool()
- assert not offset_loc.is_in_pool()
+ # POOL assert not result_loc.is_in_pool()
+ # POOL assert not base_loc.is_in_pool()
+ # POOL assert not index_loc.is_in_pool()
+ # POOL assert not offset_loc.is_in_pool()
if offset_loc.is_imm() and self._mem_offset_supported(offset_loc.value):
addr_loc = l.addr(offset_loc.value, base_loc, index_loc)
else:
- self.mc.LGR(r.SCRATCH, index_loc)
- self.mc.AGR(r.SCRATCH, offset_loc)
+ self.mc.AGRK(r.SCRATCH, index_loc, offset_loc)
addr_loc = l.addr(0, base_loc, r.SCRATCH)
self._memory_read(result_loc, addr_loc, size_loc.value, sign_loc.value)
@@ -935,9 +942,9 @@
def emit_gc_store(self, op, arglocs, regalloc):
(base_loc, index_loc, value_loc, size_loc) = arglocs
- assert not base_loc.is_in_pool()
- assert not index_loc.is_in_pool()
- assert not value_loc.is_in_pool()
+ # POOL assert not base_loc.is_in_pool()
+ # POOL assert not index_loc.is_in_pool()
+ # POOL assert not value_loc.is_in_pool()
if index_loc.is_imm() and self._mem_offset_supported(index_loc.value):
addr_loc = l.addr(index_loc.value, base_loc)
else:
@@ -947,9 +954,9 @@
def emit_gc_store_indexed(self, op, arglocs, regalloc):
(base_loc, index_loc, value_loc, offset_loc, size_loc) = arglocs
- assert not base_loc.is_in_pool()
- assert not index_loc.is_in_pool()
- assert not value_loc.is_in_pool()
+ # POOL assert not base_loc.is_in_pool()
+ # POOL assert not index_loc.is_in_pool()
+ # POOL assert not value_loc.is_in_pool()
addr_loc = self._load_address(base_loc, index_loc, offset_loc, r.SCRATCH)
self._memory_store(value_loc, addr_loc, size_loc)
@@ -962,8 +969,7 @@
assert index_loc.is_core_reg()
addr_loc = l.addr(offset_loc.value, base_loc, index_loc)
else:
- self.mc.LGR(helper_reg, index_loc)
- self.mc.AGR(helper_reg, offset_loc)
+ self.mc.AGRK(helper_reg, index_loc, offset_loc)
addr_loc = l.addr(0, base_loc, helper_reg)
return addr_loc
@@ -1088,7 +1094,7 @@
self._store_force_index(self._find_nearby_operation(regalloc, +1))
# 'result_loc' is either r2, f0 or None
self.call_assembler(op, argloc, vloc, result_loc, r.r2)
- self.mc.LARL(r.POOL, l.halfword(self.pool.pool_start - self.mc.get_relative_pos()))
+ # POOL self.mc.LARL(r.POOL, l.halfword(self.pool.pool_start - self.mc.get_relative_pos()))
emit_call_assembler_i = _genop_call_assembler
emit_call_assembler_r = _genop_call_assembler
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
@@ -70,8 +70,13 @@
return adr
def convert_to_imm(self, c):
- off = self.pool.get_offset(c)
- return l.pool(off, float=True)
+ adr = self.convert_to_adr(c)
+ return l.ConstFloatLoc(adr)
+
+ # POOL
+ #def convert_to_imm(self, c):
+ # off = self.pool.get_offset(c)
+ # return l.pool(off, float=True)
def __init__(self, longevity, frame_manager=None, assembler=None):
RegisterManager.__init__(self, longevity, frame_manager, assembler)
@@ -79,31 +84,46 @@
def call_result_location(self, v):
return r.FPR_RETURN
- def place_in_pool(self, var):
- offset = self.assembler.pool.get_offset(var)
- return l.pool(offset, float=True)
+ # POOL
+ # def place_in_pool(self, var):
+ # offset = self.assembler.pool.get_offset(var)
+ # return l.pool(offset, float=True)
- def ensure_reg_or_pool(self, box):
- if isinstance(box, Const):
- return self.place_in_pool(box)
- else:
- assert box in self.temp_boxes
- loc = self.make_sure_var_in_reg(box,
- forbidden_vars=self.temp_boxes)
- return loc
+ # POOL
+ #def ensure_reg_or_pool(self, box):
+ # if isinstance(box, Const):
+ # loc = self.get_scratch_reg()
+ # immvalue = self.convert_to_int(box)
+ # self.assembler.mc.load_imm(loc, immvalue)
+ # else:
+ # assert box in self.temp_boxes
+ # loc = self.make_sure_var_in_reg(box,
+ # forbidden_vars=self.temp_boxes)
+ # return loc
+
+ def get_scratch_reg(self):
+ box = TempVar()
+ reg = self.force_allocate_reg(box, forbidden_vars=self.temp_boxes)
+ self.temp_boxes.append(box)
+ return reg
def ensure_reg(self, box):
if isinstance(box, Const):
- poolloc = self.place_in_pool(box)
- tmp = TempVar()
- reg = self.force_allocate_reg(tmp, self.temp_boxes)
- self.temp_boxes.append(tmp)
- assert poolloc.displace >= 0
- if poolloc.displace <= 2**16-1:
- self.assembler.mc.LD(reg, poolloc)
- else:
- self.assembler.mc.LDY(reg, poolloc)
- return reg
+ # POOL
+ #poolloc = self.place_in_pool(box)
+ #tmp = TempVar()
+ #reg = self.force_allocate_reg(tmp, self.temp_boxes)
+ #self.temp_boxes.append(tmp)
+ #assert poolloc.displace >= 0
+ #if poolloc.displace <= 2**12-1:
+ # self.assembler.mc.LD(reg, poolloc)
+ #else:
+ # self.assembler.mc.LDY(reg, poolloc)
+ loc = self.get_scratch_reg()
+ immadrvalue = self.convert_to_adr(box)
+ mc = self.assembler.mc
+ mc.load_imm(r.SCRATCH, immadrvalue)
+ mc.LD(loc, l.addr(0, r.SCRATCH))
else:
assert box in self.temp_boxes
loc = self.make_sure_var_in_reg(box,
@@ -140,28 +160,36 @@
return rffi.cast(lltype.Signed, c.value)
def convert_to_imm(self, c):
- off = self.pool.get_offset(c)
- return l.pool(off)
+ val = self.convert_to_int(c)
+ return l.imm(val)
- def ensure_reg_or_pool(self, box):
- if isinstance(box, Const):
- offset = self.assembler.pool.get_offset(box)
- return l.pool(offset)
- else:
- assert box in self.temp_boxes
- loc = self.make_sure_var_in_reg(box,
- forbidden_vars=self.temp_boxes)
- return loc
+ # POOL
+ #def convert_to_imm(self, c):
+ # off = self.pool.get_offset(c)
+ # return l.pool(off)
+ #def ensure_reg_or_pool(self, box):
+ # if isinstance(box, Const):
+ # offset = self.assembler.pool.get_offset(box)
+ # return l.pool(offset)
+ # else:
+ # assert box in self.temp_boxes
+ # loc = self.make_sure_var_in_reg(box,
+ # forbidden_vars=self.temp_boxes)
+ # return loc
+
+ # POOL
+ #offset = self.assembler.pool.get_offset(box)
+ #poolloc = l.pool(offset)
+ #tmp = TempInt()
+ #reg = self.force_allocate_reg(tmp, forbidden_vars=self.temp_boxes)
+ #self.temp_boxes.append(tmp)
+ #self.assembler.mc.LG(reg, poolloc)
def ensure_reg(self, box):
if isinstance(box, Const):
- offset = self.assembler.pool.get_offset(box)
- poolloc = l.pool(offset)
- tmp = TempInt()
- reg = self.force_allocate_reg(tmp, forbidden_vars=self.temp_boxes)
- self.temp_boxes.append(tmp)
- self.assembler.mc.LG(reg, poolloc)
- return reg
+ loc = self.get_scratch_reg()
+ immvalue = self.convert_to_int(box)
+ self.assembler.mc.load_imm(loc, immvalue)
else:
assert box in self.temp_boxes
loc = self.make_sure_var_in_reg(box,
@@ -357,10 +385,10 @@
self.rm = ZARCHRegisterManager(self.longevity,
frame_manager = self.fm,
assembler = self.assembler)
- self.rm.pool = self.assembler.pool
+ #self.rm.pool = self.assembler.pool
self.fprm = FPRegisterManager(self.longevity, frame_manager = self.fm,
assembler = self.assembler)
- self.fprm.pool = self.assembler.pool
+ #self.fprm.pool = self.assembler.pool
return operations
def prepare_loop(self, inputargs, operations, looptoken, allgcrefs):
@@ -576,11 +604,12 @@
else:
return self.rm.call_result_location(v)
- def ensure_reg_or_pool(self, box):
- if box.type == FLOAT:
- return self.fprm.ensure_reg_or_pool(box)
- else:
- return self.rm.ensure_reg_or_pool(box)
+ # POOL
+ #def ensure_reg_or_pool(self, box):
+ # if box.type == FLOAT:
+ # return self.fprm.ensure_reg_or_pool(box)
+ # else:
+ # return self.rm.ensure_reg_or_pool(box)
def ensure_reg(self, box):
if box.type == FLOAT:
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
@@ -7,7 +7,7 @@
[r0,r1,r2,r3,r4,r5,r6,r7,r8,
r9,r10,r11,r12,r13,r14,r15] = registers
-MANAGED_REGS = [r2,r3,r4,r5,r6,r7,r8,r9,r10,r11] # keep this list sorted (asc)!
+MANAGED_REGS = [r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r13] # keep this list sorted (asc)!
MANAGED_REG_PAIRS = [(r2,r3), (r4,r5), (r6,r7), (r8,r9), (r10,r11)]
VOLATILES = [r2,r3,r4,r5,r6]
SP = r15
@@ -39,7 +39,6 @@
for _r in MANAGED_FP_REGS:
ALL_REG_INDEXES[_r] = len(ALL_REG_INDEXES)
# NOT used, but keeps JITFRAME_FIXED_SIZE even
-ALL_REG_INDEXES[f15] = len(ALL_REG_INDEXES)
JITFRAME_FIXED_SIZE = len(ALL_REG_INDEXES)
def odd_reg(r):
diff --git a/rpython/jit/backend/zarch/test/test_assembler.py b/rpython/jit/backend/zarch/test/test_assembler.py
--- a/rpython/jit/backend/zarch/test/test_assembler.py
+++ b/rpython/jit/backend/zarch/test/test_assembler.py
@@ -325,11 +325,23 @@
self.a.mc.LGFI(r.r5, loc.imm(63))
self.a.mc.NGR(r.r4, r.r5)
self.a.mc.LGFI(r.r3, loc.imm(18))
- self.a.mc.LGFI(r.r2, loc.imm(0xffffffff))
+ self.a.mc.LGFI(r.r2, loc.imm(-1))
self.a.mc.SRLG(r.r2, r.r3, loc.addr(18))
self.a.jmpto(r.r14)
assert run_asm(self.a) == 0
+ def test_generate_max_integral_64bit(self):
+ self.a.mc.LGHI(r.r2, loc.imm(-1))
+ self.a.mc.RISBG(r.r2, r.r2, loc.imm(1), loc.imm(0x80 | 63), loc.imm(0))
+ self.a.jmpto(r.r14)
+ assert run_asm(self.a) == 2**63-1
+
+ def test_generate_sign_bit(self):
+ self.a.mc.LGHI(r.r2, loc.imm(-1))
+ self.a.mc.RISBG(r.r2, r.r2, loc.imm(0), loc.imm(0x80 | 0), loc.imm(0))
+ self.a.jmpto(r.r14)
+ assert run_asm(self.a) == -2**63
+
def test_ag_overflow(self):
self.a.mc.BRC(con.ANY, loc.imm(4+8+8))
self.a.mc.write('\x7f' + '\xff' * 7)
@@ -593,7 +605,7 @@
# ensure there is just on instruction for the 'best case'
self.pushpop_jitframe(r.MANAGED_REGS)
- assert stored == [(r.r2, r.r11)]
+ assert stored == [(r.r2, r.r11), (r.r13,)]
assert stored == loaded
stored = []
loaded = []
diff --git a/rpython/jit/backend/zarch/test/test_runner.py b/rpython/jit/backend/zarch/test/test_runner.py
--- a/rpython/jit/backend/zarch/test/test_runner.py
+++ b/rpython/jit/backend/zarch/test/test_runner.py
@@ -24,7 +24,6 @@
cpu.setup_once()
return cpu
- add_loop_instructions = "lg; lgr; larl; agr; cgfi; jge; j;$"
- # realloc frame takes the most space (from just after larl, to lay)
- bridge_loop_instructions = "larl; lg; cgfi; jnl; lghi; " \
- "iilf;( iihf;)? iilf;( iihf;)? basr; lg; br;$"
+ add_loop_instructions = "lg; lgr; agr; cgfi; jge; j;$"
+ bridge_loop_instructions = "lg; cgfi; jnl; lghi; " \
+ "iilf;( iihf;)? iilf;( iihf;)? basr; iilf;( iihf;)? br;$"
More information about the pypy-commit
mailing list