Author: Armin Rigo <[email protected]>
Branch: ppc-updated-backend
Changeset: r79926:7d9d9d7d1398
Date: 2015-10-02 10:35 +0200
http://bitbucket.org/pypy/pypy/changeset/7d9d9d7d1398/
Log: PPC Backend #6 step 1
diff too long, truncating to 2000 out of 4756 lines
diff --git a/rpython/jit/backend/arm/assembler.py
b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -225,6 +225,10 @@
if not for_frame:
self._push_all_regs_to_jitframe(mc, [], withfloats,
callee_only=True)
else:
+ # NOTE: don't save registers on the jitframe here! It might
+ # override already-saved values that will be restored
+ # later...
+ #
# we're possibly called from the slowpath of malloc
# save the caller saved registers
# assuming we do not collect here
diff --git a/rpython/jit/backend/arm/regalloc.py
b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -1259,18 +1259,6 @@
self.possibly_free_vars(guard_op.getfailargs())
return locs + [resloc, tmploc]
- def _prepare_args_for_new_op(self, new_args):
- gc_ll_descr = self.cpu.gc_ll_descr
- args = gc_ll_descr.args_for_new(new_args)
- arglocs = []
- for i in range(len(args)):
- arg = args[i]
- t = TempInt()
- l = self.force_allocate_reg(t, selected_reg=r.all_regs[i])
- self.assembler.load(l, imm(arg))
- arglocs.append(t)
- return arglocs
-
prepare_op_float_add = prepare_float_op(name='prepare_op_float_add')
prepare_op_float_sub = prepare_float_op(name='prepare_op_float_sub')
prepare_op_float_mul = prepare_float_op(name='prepare_op_float_mul')
diff --git a/rpython/jit/backend/llsupport/test/ztranslation_test.py
b/rpython/jit/backend/llsupport/test/ztranslation_test.py
--- a/rpython/jit/backend/llsupport/test/ztranslation_test.py
+++ b/rpython/jit/backend/llsupport/test/ztranslation_test.py
@@ -303,7 +303,7 @@
for line in open(str(logfile)):
if 'guard_class' in line:
guard_class += 1
- # if we get many more guard_classes, it means that we generate
+ # if we get many more guard_classes (~93), it means that we generate
# guards that always fail (the following assert's original purpose
# is to catch the following case: each GUARD_CLASS is misgenerated
# and always fails with "gcremovetypeptr")
diff --git a/rpython/jit/backend/ppc/callbuilder.py
b/rpython/jit/backend/ppc/callbuilder.py
--- a/rpython/jit/backend/ppc/callbuilder.py
+++ b/rpython/jit/backend/ppc/callbuilder.py
@@ -126,8 +126,8 @@
if gcrootmap.is_shadow_stack and self.is_call_release_gil:
# in this mode, 'ebx' happens to contain the shadowstack
# top at this point, so reuse it instead of loading it again
- ssreg = ebx
- self.asm._reload_frame_if_necessary(self.mc)
+ ssreg = self.RSHADOWPTR
+ self.asm._reload_frame_if_necessary(self.mc, shadowstack_reg=ssreg)
def emit_raw_call(self):
self.mc.raw_call()
@@ -151,9 +151,10 @@
# Save this thread's shadowstack pointer into r29, for later comparison
gcrootmap = self.asm.cpu.gc_ll_descr.gcrootmap
if gcrootmap:
- rst = gcrootmap.get_root_stack_top_addr()
- self.mc.load_imm(RSHADOWPTR, rst)
- self.mc.load(RSHADOWOLD.value, RSHADOWPTR.value, 0)
+ if gcrootmap.is_shadow_stack:
+ rst = gcrootmap.get_root_stack_top_addr()
+ self.mc.load_imm(RSHADOWPTR, rst)
+ self.mc.load(RSHADOWOLD.value, RSHADOWPTR.value, 0)
#
# change 'rpy_fastgil' to 0 (it should be non-zero right now)
self.mc.load_imm(RFASTGILPTR, fastgil)
@@ -184,7 +185,8 @@
self.mc.cmpdi(0, r.r10.value, 0)
b1_location = self.mc.currpos()
- self.mc.trap() # patched with a BEQ: jump if r10 is zero
+ self.mc.trap() # boehm: patched with a BEQ: jump if r10 is zero
+ # shadowstack: patched with BNE instead
if self.asm.cpu.gc_ll_descr.gcrootmap:
# When doing a call_release_gil with shadowstack, there
@@ -192,20 +194,23 @@
# current shadowstack can be the one of a different
# thread. So here we check if the shadowstack pointer
# is still the same as before we released the GIL (saved
- # in 'r7'), and if not, we fall back to 'reacqgil_addr'.
- XXXXXXXXXXXXXXXXXXX
- self.mc.LDR_ri(r.ip.value, r.r5.value, cond=c.EQ)
- self.mc.CMP_rr(r.ip.value, r.r7.value, cond=c.EQ)
+ # in RSHADOWOLD), and if not, we fall back to 'reacqgil_addr'.
+ self.mc.load(r.r9.value, RSHADOWPTR.value, 0)
+ self.mc.cmpdi(0, r.r9.value, RSHADOWOLD.value)
+ bne_location = b1_location
b1_location = self.mc.currpos()
- self.mc.BKPT() # BEQ below
- # there are two cases here: either EQ was false from
- # the beginning, or EQ was true at first but the CMP
- # made it false. In the second case we need to
- # release the fastgil here. We know which case it is
- # by checking again r3.
- self.mc.CMP_ri(r.r3.value, 0)
- self.mc.STR_ri(r.r3.value, r.r6.value, cond=c.EQ)
+ self.mc.trap()
+
+ # revert the rpy_fastgil acquired above, so that the
+ # general 'reacqgil_addr' below can acquire it again...
+ # (here, r10 is conveniently zero)
+ self.mc.std(r.r10.value, RFASTGILPTR.value, 0)
+
+ pmc = OverwritingBuilder(self.mc, bne_location, 1)
+ pmc.bne(self.mc.currpos() - bne_location)
+ pmc.overwrite()
#
+ # Yes, we need to call the reacqgil() function.
# save the result we just got
RSAVEDRES = RFASTGILPTR # can reuse this reg here
reg = self.resloc
@@ -225,9 +230,8 @@
PARAM_SAVE_AREA_OFFSET + 7 * WORD)
# replace b1_location with BEQ(here)
- jmp_target = self.mc.currpos()
pmc = OverwritingBuilder(self.mc, b1_location, 1)
- pmc.beq(jmp_target - b1_location)
+ pmc.beq(self.mc.currpos() - b1_location)
pmc.overwrite()
if not we_are_translated(): # for testing: now we can access
diff --git a/rpython/jit/backend/ppc/codebuilder.py
b/rpython/jit/backend/ppc/codebuilder.py
--- a/rpython/jit/backend/ppc/codebuilder.py
+++ b/rpython/jit/backend/ppc/codebuilder.py
@@ -17,11 +17,15 @@
from rpython.jit.backend.ppc.rassemblermaker import make_rassembler
-# these are the *forbidden* encodings that don't accept register r0:
-# addi rX, r0, immed
-# subi rX, r0, immed
-# addis rX, r0, immed
-# subis rX, r0, immed
+# the following instructions can't accept "r0" as the second argument
+# (i.e. the base address): it is recognized as "0" instead, or is
+# even invalid (load-with-update, store-with-update).
+#
+# any load or store instruction
+# addi rD, r0, immed
+# subi rD, r0, immed
+# addis rD, r0, immed
+# subis rD, r0, immed
A = Form("frD", "frA", "frB", "XO3", "Rc")
@@ -1000,12 +1004,23 @@
if word & 0xFFFF != 0:
self.ori(rD, rD, lo(word))
+ def load_imm_plus(self, dest_reg, word):
+ """Like load_imm(), but with one instruction less, and
+ leaves the loaded value off by some signed 16-bit difference.
+ Returns that difference."""
+ diff = rffi.cast(lltype.Signed, rffi.cast(rffi.SHORT, word))
+ word -= diff
+ assert word & 0xFFFF == 0
+ self.load_imm(dest_reg, word)
+ return diff
+
def load_from_addr(self, rD, addr):
- self.load_imm(rD, addr)
+ assert rD is not r.r0
+ diff = self.load_imm_plus(rD, addr)
if IS_PPC_32:
- self.lwzx(rD.value, 0, rD.value)
+ self.lwz(rD.value, rD.value, diff)
else:
- self.ldx(rD.value, 0, rD.value)
+ self.ld(rD.value, rD.value, diff)
def b_offset(self, target):
curpos = self.currpos()
@@ -1073,60 +1088,6 @@
# Call the function
self.bctrl()
- ## def call(self, address):
- ## """ do a call to an absolute address
- ## """
- ## with scratch_reg(self):
- ## if IS_PPC_32:
- ## self.load_imm(r.SCRATCH, address)
- ## else:
- ## self.store(r.TOC.value, r.SP.value, 5 * WORD)
- ## self.load_imm(r.r11, address)
- ## self.load(r.SCRATCH.value, r.r11.value, 0)
- ## self.load(r.TOC.value, r.r11.value, WORD)
- ## self.load(r.r11.value, r.r11.value, 2 * WORD)
- ## self.mtctr(r.SCRATCH.value)
- ## self.bctrl()
-
- ## if IS_PPC_64:
- ## self.load(r.TOC.value, r.SP.value, 5 * WORD)
-
- ## def call_register(self, call_reg):
- ## """ do a call to an address given in a register
- ## """
- ## assert isinstance(call_reg, RegisterLocation)
- ## with scratch_reg(self):
- ## if IS_PPC_32:
- ## self.mr(r.SCRATCH.value, call_reg.value)
- ## else:
- ## self.store(r.TOC.value, r.SP.value, 5 * WORD)
- ## self.mr(r.r11.value, call_reg.value)
- ## self.load(r.SCRATCH.value, r.r11.value, 0)
- ## self.load(r.TOC.value, r.r11.value, WORD)
- ## self.load(r.r11.value, r.r11.value, 2 * WORD)
- ## self.mtctr(r.SCRATCH.value)
- ## self.bctrl()
-
- ## if IS_PPC_64:
- ## self.load(r.TOC.value, r.SP.value, 5 * WORD)
-
- ## def make_function_prologue(self, frame_size):
- ## """ Build a new stackframe of size frame_size
- ## and store the LR in the previous frame.
- ## """
- ## with scratch_reg(self):
- ## self.store_update(r.SP.value, r.SP.value, -frame_size)
- ## self.mflr(r.SCRATCH.value)
- ## self.store(r.SCRATCH.value, r.SP.value, frame_size +
LR_BC_OFFSET)
-
- def restore_LR_from_caller_frame(self, frame_size):
- """ Restore the LR from the calling frame.
- frame_size is the size of the current frame.
- """
- with scratch_reg(self):
- lr_offset = frame_size + LR_BC_OFFSET
- self.load(r.SCRATCH.value, r.SP.value, lr_offset)
- self.mtlr(r.SCRATCH.value)
def load(self, target_reg, base_reg, offset):
if IS_PPC_32:
@@ -1266,6 +1227,22 @@
#assert self.r0_in_use
#self.r0_in_use = False
+ def get_assembler_function(self):
+ "NOT_RPYTHON: tests only"
+ from rpython.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
+ class FakeCPU:
+ HAS_CODEMAP = False
+ asmmemmgr = AsmMemoryManager()
+ addr = self.materialize(FakeCPU(), [])
+ if IS_BIG_ENDIAN:
+ mc = PPCBuilder()
+ mc.write64(addr) # the 3-words descriptor
+ mc.write64(0)
+ mc.write64(0)
+ addr = mc.materialize(FakeCPU(), [])
+ return rffi.cast(lltype.Ptr(lltype.FuncType([], lltype.Signed)), addr)
+
+
class scratch_reg(object):
def __init__(self, mc):
self.mc = mc
diff --git a/rpython/jit/backend/ppc/opassembler.py
b/rpython/jit/backend/ppc/opassembler.py
--- a/rpython/jit/backend/ppc/opassembler.py
+++ b/rpython/jit/backend/ppc/opassembler.py
@@ -59,23 +59,23 @@
else:
self.mc.mulld(res.value, l0.value, l1.value)
- def do_emit_int_binary_ovf(self, op, arglocs, emit):
+ def do_emit_int_binary_ovf(self, op, arglocs):
l0, l1, res = arglocs[0], arglocs[1], arglocs[2]
self.mc.load_imm(r.SCRATCH, 0)
self.mc.mtxer(r.SCRATCH.value)
- emit(res.value, l0.value, l1.value)
+ return (res.value, l0.value, l1.value)
def emit_int_add_ovf(self, op, arglocs, regalloc):
- self.do_emit_int_binary_ovf(op, arglocs, self.mc.addox)
+ self.mc.addox(*self.do_emit_int_binary_ovf(op, arglocs))
def emit_int_sub_ovf(self, op, arglocs, regalloc):
- self.do_emit_int_binary_ovf(op, arglocs, self.mc.subox)
+ self.mc.subox(*self.do_emit_int_binary_ovf(op, arglocs))
def emit_int_mul_ovf(self, op, arglocs, regalloc):
if IS_PPC_32:
- self.do_emit_int_binary_ovf(op, arglocs, self.mc.mullwox)
+ self.mc.mullwox(*self.do_emit_int_binary_ovf(op, arglocs))
else:
- self.do_emit_int_binary_ovf(op, arglocs, self.mc.mulldox)
+ self.mc.mulldox(*self.do_emit_int_binary_ovf(op, arglocs))
def emit_int_floordiv(self, op, arglocs, regalloc):
l0, l1, res = arglocs
@@ -343,12 +343,11 @@
# this half-word is at offset 0 on a little-endian machine;
# but it is at offset 2 (32 bit) or 4 (64 bit) on a
# big-endian machine.
- with scratch_reg(self.mc):
- if IS_PPC_32:
- self.mc.lhz(r.SCRATCH.value, locs[0].value, 2)
- else:
- self.mc.lwz(r.SCRATCH.value, locs[0].value, 4)
- self.mc.cmp_op(0, r.SCRATCH.value, typeid.value,
imm=typeid.is_imm())
+ if IS_PPC_32:
+ self.mc.lhz(r.SCRATCH.value, locs[0].value, 2 * IS_BIG_ENDIAN)
+ else:
+ self.mc.lwz(r.SCRATCH.value, locs[0].value, 4 * IS_BIG_ENDIAN)
+ self.mc.cmp_op(0, r.SCRATCH.value, typeid.value,
imm=typeid.is_imm())
def emit_guard_not_invalidated(self, op, arglocs, regalloc):
self._emit_guard(op, arglocs, is_guard_not_invalidated=True)
@@ -461,23 +460,24 @@
pmc.overwrite()
def emit_guard_exception(self, op, arglocs, regalloc):
- # XXX FIXME
- # XXX pos_exc_value and pos_exception are 8 bytes apart, don't need
both
- loc, loc1, resloc, pos_exc_value, pos_exception = arglocs[:5]
- failargs = arglocs[5:]
- self.mc.load_imm(loc1, pos_exception.value)
- self.mc.load(r.SCRATCH.value, loc1.value, 0)
- self.mc.cmp_op(0, r.SCRATCH.value, loc.value)
+ loc, resloc = arglocs[:2]
+ failargs = arglocs[2:]
+
+ mc = self.mc
+ mc.load_imm(r.SCRATCH2, self.cpu.pos_exc_value())
+ diff = self.cpu.pos_exception() - self.cpu.pos_exc_value()
+ assert _check_imm_arg(diff)
+
+ mc.load(r.SCRATCH.value, r.SCRATCH2.value, diff)
+ mc.cmp_op(0, r.SCRATCH.value, loc.value)
self.guard_success_cc = c.EQ
self._emit_guard(op, failargs, save_exc=True)
- self.mc.load_imm(loc, pos_exc_value.value)
if resloc:
- self.mc.load(resloc.value, loc.value, 0)
-
- self.mc.load_imm(r.SCRATCH, 0)
- self.mc.store(r.SCRATCH.value, loc.value, 0)
- self.mc.store(r.SCRATCH.value, loc1.value, 0)
+ mc.load(resloc.value, r.SCRATCH2.value, 0)
+ mc.load_imm(r.SCRATCH, 0)
+ mc.store(r.SCRATCH.value, r.SCRATCH2.value, 0)
+ mc.store(r.SCRATCH.value, r.SCRATCH2.value, diff)
class CallOpAssembler(object):
@@ -687,7 +687,7 @@
if _check_imm_arg(multiply_by):
self.mc.mulli(scratch_loc.value, loc.value, multiply_by)
else:
- self.mc.load_imm(scratch_loc.value, multiply_by)
+ self.mc.load_imm(scratch_loc, multiply_by)
if IS_PPC_32:
self.mc.mullw(scratch_loc.value, loc.value,
scratch_loc.value)
@@ -766,6 +766,23 @@
self.mc.mr(r.SCRATCH2.value, loc.value)
return r.SCRATCH2
+ # RPythonic workaround for emit_zero_array()
+ def eza_stXux(self, a, b, c, itemsize):
+ if itemsize & 1: self.mc.stbux(a, b, c)
+ elif itemsize & 2: self.mc.sthux(a, b, c)
+ elif (itemsize & 4) or IS_PPC_32: self.mc.stwux(a, b, c)
+ else: self.mc.stdux(a, b, c)
+ def eza_stXu(self, a, b, c, itemsize):
+ if itemsize & 1: self.mc.stbu(a, b, c)
+ elif itemsize & 2: self.mc.sthu(a, b, c)
+ elif (itemsize & 4) or IS_PPC_32: self.mc.stwu(a, b, c)
+ else: self.mc.stdu(a, b, c)
+ def eza_stX(self, a, b, c, itemsize):
+ if itemsize & 1: self.mc.stb(a, b, c)
+ elif itemsize & 2: self.mc.sth(a, b, c)
+ elif (itemsize & 4) or IS_PPC_32: self.mc.stw(a, b, c)
+ else: self.mc.std(a, b, c)
+
def emit_zero_array(self, op, arglocs, regalloc):
base_loc, startindex_loc, length_loc, ofs_loc, itemsize_loc = arglocs
@@ -774,26 +791,10 @@
# * if N % 4 == 0, then all items are aligned to a multiple of 4
# * if N % 8 == 0, then all items are aligned to a multiple of 8
itemsize = itemsize_loc.getint()
- if itemsize & 1:
- stepsize = 1
- stXux = self.mc.stbux
- stXu = self.mc.stbu
- stX = self.mc.stb
- elif itemsize & 2:
- stepsize = 2
- stXux = self.mc.sthux
- stXu = self.mc.sthu
- stX = self.mc.sth
- elif (itemsize & 4) or IS_PPC_32:
- stepsize = 4
- stXux = self.mc.stwux
- stXu = self.mc.stwu
- stX = self.mc.stw
- else:
- stepsize = WORD
- stXux = self.mc.stdux
- stXu = self.mc.stdu
- stX = self.mc.std
+ if itemsize & 1: stepsize = 1
+ elif itemsize & 2: stepsize = 2
+ elif (itemsize & 4) or IS_PPC_32: stepsize = 4
+ else: stepsize = WORD
repeat_factor = itemsize // stepsize
if repeat_factor != 1:
@@ -816,9 +817,11 @@
if unroll > 0:
assert repeat_factor == 1
self.mc.li(r.SCRATCH.value, 0)
- stXux(r.SCRATCH.value, ofs_loc.value, base_loc.value)
+ self.eza_stXux(r.SCRATCH.value, ofs_loc.value, base_loc.value,
+ itemsize)
for i in range(1, unroll):
- stX(r.SCRATCH.value, ofs_loc.value, i * stepsize)
+ self.eza_stX(r.SCRATCH.value, ofs_loc.value, i * stepsize,
+ itemsize)
else:
if length_loc.is_imm():
@@ -836,12 +839,14 @@
self.mc.mtctr(length_loc.value)
self.mc.li(r.SCRATCH.value, 0)
- stXux(r.SCRATCH.value, ofs_loc.value, base_loc.value)
+ self.eza_stXux(r.SCRATCH.value, ofs_loc.value, base_loc.value,
+ itemsize)
bdz_location = self.mc.currpos()
self.mc.trap()
loop_location = self.mc.currpos()
- stXu(r.SCRATCH.value, ofs_loc.value, stepsize)
+ self.eza_stXu(r.SCRATCH.value, ofs_loc.value, stepsize,
+ itemsize)
self.mc.bdnz(loop_location - self.mc.currpos())
pmc = OverwritingBuilder(self.mc, bdz_location, 1)
@@ -958,10 +963,13 @@
def emit_call_malloc_nursery_varsize(self, op, arglocs, regalloc):
# registers r.RES and r.RSZ are allocated for this call
+ gc_ll_descr = self.cpu.gc_ll_descr
+ if not hasattr(gc_ll_descr, 'max_size_of_young_obj'):
+ raise Exception("unreachable code")
+ # for boehm, this function should never be called
[lengthloc] = arglocs
arraydescr = op.getdescr()
itemsize = op.getarg(1).getint()
- gc_ll_descr = self.cpu.gc_ll_descr
maxlength = (gc_ll_descr.max_size_of_young_obj - WORD * 2) / itemsize
gcmap = regalloc.get_gcmap([r.RES, r.RSZ])
self.malloc_cond_varsize(
@@ -976,6 +984,12 @@
emit_jit_debug = emit_debug_merge_point
emit_keepalive = emit_debug_merge_point
+ def emit_enter_portal_frame(self, op, arglocs, regalloc):
+ self.enter_portal_frame(op)
+
+ def emit_leave_portal_frame(self, op, arglocs, regalloc):
+ self.leave_portal_frame(op)
+
def _write_barrier_fastpath(self, mc, descr, arglocs, regalloc,
array=False,
is_frame=False):
# Write code equivalent to write_barrier() in the GC: it checks
@@ -1212,6 +1226,7 @@
StrOpAssembler, CallOpAssembler,
UnicodeOpAssembler, ForceOpAssembler,
AllocOpAssembler, FloatOpAssembler):
+ _mixin_ = True
def nop(self):
self.mc.ori(0, 0, 0)
diff --git a/rpython/jit/backend/ppc/ppc_assembler.py
b/rpython/jit/backend/ppc/ppc_assembler.py
--- a/rpython/jit/backend/ppc/ppc_assembler.py
+++ b/rpython/jit/backend/ppc/ppc_assembler.py
@@ -127,20 +127,20 @@
def _call_header_shadowstack(self, gcrootmap):
# we need to put one word into the shadowstack: the jitframe (SPP)
mc = self.mc
- mc.load_imm(r.RCS1, gcrootmap.get_root_stack_top_addr())
- mc.load(r.RCS2.value, r.RCS1.value, 0) # ld RCS2, [rootstacktop]
+ diff = mc.load_imm_plus(r.RCS1, gcrootmap.get_root_stack_top_addr())
+ mc.load(r.RCS2.value, r.RCS1.value, diff) # ld RCS2, [rootstacktop]
#
mc.addi(r.RCS3.value, r.RCS2.value, WORD) # add RCS3, RCS2, WORD
mc.store(r.SPP.value, r.RCS2.value, 0) # std SPP, RCS2
#
- mc.store(r.RCS3.value, r.RCS1.value, 0) # std RCS3, [rootstacktop]
+ mc.store(r.RCS3.value, r.RCS1.value, diff)# std RCS3, [rootstacktop]
def _call_footer_shadowstack(self, gcrootmap):
mc = self.mc
- mc.load_imm(r.RCS1, gcrootmap.get_root_stack_top_addr())
- mc.load(r.RCS2.value, r.RCS1.value, 0) # ld RCS2, [rootstacktop]
- mc.addi(r.RCS2.value, r.RCS2.value, WORD) # sub RCS2, RCS2, WORD
- mc.store(r.RCS2.value, r.RCS1.value, 0) # std RCS2, [rootstacktop]
+ diff = mc.load_imm_plus(r.RCS1, gcrootmap.get_root_stack_top_addr())
+ mc.load(r.RCS2.value, r.RCS1.value, diff) # ld RCS2, [rootstacktop]
+ mc.subi(r.RCS2.value, r.RCS2.value, WORD) # sub RCS2, RCS2, WORD
+ mc.store(r.RCS2.value, r.RCS1.value, diff) # std RCS2, [rootstacktop]
def new_stack_loc(self, i, tp):
base_ofs = self.cpu.get_baseofs_of_frame_field()
@@ -248,8 +248,8 @@
gcrootmap = self.cpu.gc_ll_descr.gcrootmap
if gcrootmap and gcrootmap.is_shadow_stack:
- mc.load_imm(r.r5, gcrootmap.get_root_stack_top_addr())
- mc.load(r.r5.value, r.r5.value, 0)
+ diff = mc.load_imm_plus(r.r5, gcrootmap.get_root_stack_top_addr())
+ mc.load(r.r5.value, r.r5.value, diff)
mc.store(r.r3.value, r.r5.value, -WORD)
mc.mtlr(r.RCS1.value) # restore LR
@@ -283,13 +283,16 @@
mc.store(excvalloc.value, r.r2.value, 0)
mc.store(exctploc.value, r.r2.value, diff)
- def _reload_frame_if_necessary(self, mc):
+ def _reload_frame_if_necessary(self, mc, shadowstack_reg=None):
gcrootmap = self.cpu.gc_ll_descr.gcrootmap
if gcrootmap:
if gcrootmap.is_shadow_stack:
- mc.load_imm(r.SPP, gcrootmap.get_root_stack_top_addr())
- mc.load(r.SPP.value, r.SPP.value, 0)
- mc.load(r.SPP.value, r.SPP.value, -WORD)
+ if shadowstack_reg is None:
+ diff = mc.load_imm_plus(r.SPP,
+
gcrootmap.get_root_stack_top_addr())
+ mc.load(r.SPP.value, r.SPP.value, diff)
+ shadowstack_reg = r.SPP
+ mc.load(r.SPP.value, shadowstack_reg.value, -WORD)
wbdescr = self.cpu.gc_ll_descr.write_barrier_descr
if gcrootmap and wbdescr:
# frame never uses card marking, so we enforce this is not
@@ -430,100 +433,38 @@
if slowpathaddr == 0 or not self.cpu.propagate_exception_descr:
return # no stack check (for tests, or non-translated)
#
- # make a "function" that is called immediately at the start of
- # an assembler function. In particular, the stack looks like:
+ # make a regular function that is called from a point near the start
+ # of an assembler function (after it adjusts the stack and saves
+ # registers).
+ mc = PPCBuilder()
#
- # | |
- # | OLD BACKCHAIN |
- # | |
- # =============================== -
- # | | |
- # | BACKCHAIN | | > MINI FRAME (BACHCHAIN SIZE *
WORD)
- # | | |
- # =============================== -
- # | |
- # | SAVED PARAM REGS |
- # | |
- # -------------------------------
- # | |
- # | BACKCHAIN |
- # | |
- # =============================== <- SP
+ # Save away the LR inside r30
+ mc.mflr(r.RCS1.value)
#
- mc = PPCBuilder()
-
- # make small frame to store data (parameter regs + LR + SCRATCH) in
- # there. Allocate additional fixed save area for PPC64.
- PARAM_AREA = len(r.PARAM_REGS)
- FIXED_AREA = BACKCHAIN_SIZE
- if IS_PPC_64:
- FIXED_AREA += MAX_REG_PARAMS
- frame_size = (FIXED_AREA + PARAM_AREA) * WORD
-
- # align the SP
- MINIFRAME_SIZE = BACKCHAIN_SIZE * WORD
- while (frame_size + MINIFRAME_SIZE) % (4 * WORD) != 0:
- frame_size += WORD
-
- # write function descriptor
- if IS_PPC_64 and IS_BIG_ENDIAN:
- for _ in range(3):
- mc.write64(0)
-
- # build frame
- mc.make_function_prologue(frame_size)
-
- # save parameter registers
- for i, reg in enumerate(r.PARAM_REGS):
- mc.store(reg.value, r.SP.value, (i + FIXED_AREA) * WORD)
-
+ # Do the call
# use SP as single parameter for the call
mc.mr(r.r3.value, r.SP.value)
-
- # stack still aligned
- mc.call(slowpathaddr)
-
- with scratch_reg(mc):
- mc.load_imm(r.SCRATCH, self.cpu.pos_exception())
- mc.loadx(r.SCRATCH.value, 0, r.SCRATCH.value)
- # if this comparison is true, then everything is ok,
- # else we have an exception
- mc.cmp_op(0, r.SCRATCH.value, 0, imm=True)
-
- jnz_location = mc.currpos()
- mc.trap()
-
- # restore parameter registers
- for i, reg in enumerate(r.PARAM_REGS):
- mc.load(reg.value, r.SP.value, (i + FIXED_AREA) * WORD)
-
- # restore LR
- mc.restore_LR_from_caller_frame(frame_size)
-
- # reset SP
- mc.addi(r.SP.value, r.SP.value, frame_size)
- #mc.blr()
- mc.b(self.propagate_exception_path)
-
- pmc = OverwritingBuilder(mc, jnz_location, 1)
- pmc.bne(mc.currpos() - jnz_location)
- pmc.overwrite()
-
- # restore link register out of preprevious frame
- offset_LR = frame_size + MINIFRAME_SIZE + LR_BC_OFFSET
-
- with scratch_reg(mc):
- mc.load(r.SCRATCH.value, r.SP.value, offset_LR)
- mc.mtlr(r.SCRATCH.value)
-
- # remove this frame and the miniframe
- both_framesizes = frame_size + MINIFRAME_SIZE
- mc.addi(r.SP.value, r.SP.value, both_framesizes)
- mc.blr()
-
+ mc.load_imm(mc.RAW_CALL_REG, slowpathaddr)
+ mc.raw_call()
+ #
+ # Restore LR
+ mc.mtlr(r.RCS1.value)
+ #
+ # Check if it raised StackOverflow
+ mc.load_imm(r.SCRATCH, self.cpu.pos_exception())
+ mc.loadx(r.SCRATCH.value, 0, r.SCRATCH.value)
+ # if this comparison is true, then everything is ok,
+ # else we have an exception
+ mc.cmp_op(0, r.SCRATCH.value, 0, imm=True)
+ #
+ # So we return to LR back to our caller, conditionally if "EQ"
+ mc.beqlr()
+ #
+ # Else, jump to propagate_exception_path
+ assert self.propagate_exception_path
+ mc.b_abs(self.propagate_exception_path)
+ #
rawstart = mc.materialize(self.cpu, [])
- if IS_PPC_64:
- self.write_64_bit_func_descr(rawstart, rawstart+3*WORD)
self.stack_check_slowpath = rawstart
def _build_wb_slowpath(self, withcards, withfloats=False, for_frame=False):
@@ -553,6 +494,10 @@
self.mc = mc
if for_frame:
+ # NOTE: don't save registers on the jitframe here! It might
+ # override already-saved values that will be restored
+ # later...
+ #
# This 'for_frame' version is called after a CALL. It does not
# need to save many registers: the registers that are anyway
# destroyed by the call can be ignored (VOLATILES), and the
@@ -560,8 +505,19 @@
# to save r.RCS1 (used below), r3 and f1 (possible results of
# the call), and two more non-volatile registers (used to store
# the RPython exception that occurred in the CALL, if any).
- saved_regs = [r.r3, r.RCS1, r.RCS2, r.RCS3]
- saved_fp_regs = [r.f1]
+ #
+ # We need to increase our stack frame size a bit to store them.
+ #
+ self.mc.load(r.SCRATCH.value, r.SP.value, 0) # SP back chain
+ self.mc.store_update(r.SCRATCH.value, r.SP.value, -6 * WORD)
+ self.mc.std(r.RCS1.value, r.SP.value, 1 * WORD)
+ self.mc.std(r.RCS2.value, r.SP.value, 2 * WORD)
+ self.mc.std(r.RCS3.value, r.SP.value, 3 * WORD)
+ self.mc.std(r.r3.value, r.SP.value, 4 * WORD)
+ self.mc.stfd(r.f1.value, r.SP.value, 5 * WORD)
+ saved_regs = None
+ saved_fp_regs = None
+
else:
# push all volatile registers, push RCS1, and sometimes push RCS2
if withcards:
@@ -573,8 +529,8 @@
else:
saved_fp_regs = []
- self._push_core_regs_to_jitframe(mc, saved_regs)
- self._push_fp_regs_to_jitframe(mc, saved_fp_regs)
+ self._push_core_regs_to_jitframe(mc, saved_regs)
+ self._push_fp_regs_to_jitframe(mc, saved_fp_regs)
if for_frame:
# note that it's safe to store the exception in register,
@@ -608,8 +564,18 @@
mc.lbz(r.RCS2.value, r.RCS2.value, descr.jit_wb_if_flag_byteofs)
mc.andix(r.RCS2.value, r.RCS2.value, card_marking_mask & 0xFF)
- self._pop_core_regs_from_jitframe(mc, saved_regs)
- self._pop_fp_regs_from_jitframe(mc, saved_fp_regs)
+ if for_frame:
+ self.mc.ld(r.RCS1.value, r.SP.value, 1 * WORD)
+ self.mc.ld(r.RCS2.value, r.SP.value, 2 * WORD)
+ self.mc.ld(r.RCS3.value, r.SP.value, 3 * WORD)
+ self.mc.ld(r.r3.value, r.SP.value, 4 * WORD)
+ self.mc.lfd(r.f1.value, r.SP.value, 5 * WORD)
+ self.mc.addi(r.SP.value, r.SP.value, 6 * WORD)
+
+ else:
+ self._pop_core_regs_from_jitframe(mc, saved_regs)
+ self._pop_fp_regs_from_jitframe(mc, saved_fp_regs)
+
mc.blr()
self.mc = old_mc
@@ -675,54 +641,19 @@
if self.stack_check_slowpath == 0:
pass # not translated
else:
- XXXX
- # this is the size for the miniframe
- frame_size = BACKCHAIN_SIZE * WORD
+ endaddr, lengthaddr, _ = self.cpu.insert_stack_check()
+ diff = lengthaddr - endaddr
+ assert _check_imm_arg(diff)
- endaddr, lengthaddr, _ = self.cpu.insert_stack_check()
-
- # save r16
- self.mc.mtctr(r.r16.value)
-
- with scratch_reg(self.mc):
- self.mc.load_imm(r.SCRATCH, endaddr) # load SCRATCH,
[start]
- self.mc.loadx(r.SCRATCH.value, 0, r.SCRATCH.value)
- self.mc.subf(r.SCRATCH.value, r.SP.value, r.SCRATCH.value)
- self.mc.load_imm(r.r16, lengthaddr)
- self.mc.load(r.r16.value, r.r16.value, 0)
- self.mc.cmp_op(0, r.SCRATCH.value, r.r16.value, signed=False)
-
- # restore r16
- self.mc.mfctr(r.r16.value)
-
- patch_loc = self.mc.currpos()
- self.mc.trap()
-
- # make minimal frame which contains the LR
- #
- # | OLD FRAME |
- # ==============================
- # | |
- # | BACKCHAIN | > BACKCHAIN_SIZE * WORD
- # | |
- # ============================== <- SP
-
- self.mc.make_function_prologue(frame_size)
-
- # make check
- self.mc.call(self.stack_check_slowpath)
-
- # restore LR
- self.mc.restore_LR_from_caller_frame(frame_size)
-
- # remove minimal frame
- self.mc.addi(r.SP.value, r.SP.value, frame_size)
-
- offset = self.mc.currpos() - patch_loc
- #
- pmc = OverwritingBuilder(self.mc, patch_loc, 1)
- pmc.ble(offset) # jump if SCRATCH <= r16, i. e. not(SCRATCH > r16)
- pmc.overwrite()
+ mc = self.mc
+ mc.load_imm(r.SCRATCH, self.stack_check_slowpath)
+ mc.load_imm(r.SCRATCH2, endaddr) # li r2, endaddr
+ mc.mtctr(r.SCRATCH.value)
+ mc.load(r.SCRATCH.value, r.SCRATCH2.value, 0) # ld r0, [end]
+ mc.load(r.SCRATCH2.value, r.SCRATCH2.value, diff)# ld r2, [length]
+ mc.subf(r.SCRATCH.value, r.SP.value, r.SCRATCH.value) # sub r0, SP
+ mc.cmp_op(0, r.SCRATCH.value, r.SCRATCH2.value, signed=False)
+ mc.bgtctrl()
def _call_footer(self):
# the return value is the jitframe
@@ -1012,8 +943,7 @@
addr = rawstart + tok.pos_jump_offset
#
# XXX see patch_jump_for_descr()
- #tok.faildescr.adr_jump_offset = addr
- tok.faildescr.adr_recovery_stub = rawstart + tok.pos_recovery_stub
+ tok.faildescr.adr_jump_offset = rawstart + tok.pos_recovery_stub
#
relative_target = tok.pos_recovery_stub - tok.pos_jump_offset
#
@@ -1039,7 +969,9 @@
# --- XXX for now we always use the second solution ---
mc = PPCBuilder()
mc.b_abs(adr_new_target)
- mc.copy_to_raw_memory(faildescr.adr_recovery_stub)
+ mc.copy_to_raw_memory(faildescr.adr_jump_offset)
+ assert faildescr.adr_jump_offset != 0
+ faildescr.adr_jump_offset = 0 # means "patched"
def get_asmmemmgr_blocks(self, looptoken):
clt = looptoken.compiled_loop_token
@@ -1390,16 +1322,7 @@
with scratch_reg(self.mc):
self.mc.load_imm(r.SCRATCH, fail_index)
self.mc.store(r.SCRATCH.value, r.SPP.value, FORCE_INDEX_OFS)
-
- def load(self, loc, value):
- assert (loc.is_reg() and value.is_imm()
- or loc.is_fp_reg() and value.is_imm_float())
- if value.is_imm():
- self.mc.load_imm(loc, value.getint())
- elif value.is_imm_float():
- with scratch_reg(self.mc):
- self.mc.load_imm(r.SCRATCH, value.getint())
- self.mc.lfdx(loc.value, 0, r.SCRATCH.value)
+
def notimplemented_op(self, op, arglocs, regalloc):
print "[PPC/asm] %s not implemented" % op.getopname()
diff --git a/rpython/jit/backend/ppc/regalloc.py
b/rpython/jit/backend/ppc/regalloc.py
--- a/rpython/jit/backend/ppc/regalloc.py
+++ b/rpython/jit/backend/ppc/regalloc.py
@@ -61,11 +61,15 @@
save_around_call_regs = r.VOLATILES_FLOAT
assert set(save_around_call_regs).issubset(all_regs)
- def convert_to_imm(self, c):
+ def convert_to_adr(self, c):
assert isinstance(c, ConstFloat)
adr = self.assembler.datablockwrapper.malloc_aligned(8, 8)
x = c.getfloatstorage()
rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), adr)[0] = x
+ return adr
+
+ def convert_to_imm(self, c):
+ adr = self.convert_to_adr(c)
return locations.ConstFloatLoc(adr)
def __init__(self, longevity, frame_manager=None, assembler=None):
@@ -77,8 +81,10 @@
def ensure_reg(self, box):
if isinstance(box, Const):
loc = self.get_scratch_reg()
- immvalue = self.convert_to_imm(box)
- self.assembler.load(loc, immvalue)
+ immadrvalue = self.convert_to_adr(box)
+ mc = self.assembler.mc
+ mc.load_imm(r.SCRATCH, immadrvalue)
+ mc.lfdx(loc.value, 0, r.SCRATCH.value)
else:
assert box in self.temp_boxes
loc = self.make_sure_var_in_reg(box,
@@ -134,19 +140,22 @@
def call_result_location(self, v):
return r.r3
- def convert_to_imm(self, c):
+ def convert_to_int(self, c):
if isinstance(c, ConstInt):
- val = rffi.cast(lltype.Signed, c.value)
- return locations.ImmLocation(val)
+ return rffi.cast(lltype.Signed, c.value)
else:
assert isinstance(c, ConstPtr)
- return locations.ImmLocation(rffi.cast(lltype.Signed, c.value))
+ return rffi.cast(lltype.Signed, c.value)
+
+ def convert_to_imm(self, c):
+ val = self.convert_to_int(c)
+ return locations.ImmLocation(val)
def ensure_reg(self, box):
if isinstance(box, Const):
loc = self.get_scratch_reg()
- immvalue = self.convert_to_imm(box)
- self.assembler.load(loc, immvalue)
+ 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,
@@ -593,15 +602,11 @@
def prepare_guard_exception(self, op):
loc = self.ensure_reg(op.getarg(0))
- loc1 = r.SCRATCH2
if op.result in self.longevity:
resloc = self.force_allocate_reg(op.result)
else:
resloc = None
- pos_exc_value = imm(self.cpu.pos_exc_value())
- pos_exception = imm(self.cpu.pos_exception())
- arglocs = self._prepare_guard(op,
- [loc, loc1, resloc, pos_exc_value, pos_exception])
+ arglocs = self._prepare_guard(op, [loc, resloc])
return arglocs
def prepare_guard_no_exception(self, op):
@@ -644,7 +649,7 @@
# offset in type_info_group
# - add 16/32 bytes, to go past the TYPE_INFO structure
classptr = y_val
- from pypy.rpython.memory.gctypelayout import GCData
+ from rpython.memory.gctypelayout import GCData
sizeof_ti = rffi.sizeof(GCData.TYPE_INFO)
type_info_group = llop.gc_get_type_info_group(llmemory.Address)
type_info_group = rffi.cast(lltype.Signed, type_info_group)
@@ -962,10 +967,6 @@
return [sizeloc]
def prepare_call_malloc_nursery_varsize(self, op):
- gc_ll_descr = self.assembler.cpu.gc_ll_descr
- if not hasattr(gc_ll_descr, 'max_size_of_young_obj'):
- raise Exception("unreachable code")
- # for boehm, this function should never be called
# the result will be in r.RES
self.rm.force_allocate_reg(op.result, selected_reg=r.RES)
self.rm.temp_boxes.append(op.result)
@@ -984,6 +985,8 @@
prepare_debug_merge_point = void
prepare_jit_debug = void
prepare_keepalive = void
+ prepare_enter_portal_frame = void
+ prepare_leave_portal_frame = void
def prepare_cond_call_gc_wb(self, op):
arglocs = [self.ensure_reg(op.getarg(0))]
@@ -1019,9 +1022,8 @@
#
# we need to make sure that no variable is stored in spp (=r31)
for arg in inputargs:
- if self.loc(arg) is r.SPP:
- loc2 = self.fm.loc(arg)
- self.assembler.mc.store(r.SPP, loc2)
+ assert self.loc(arg) is not r.SPP, (
+ "variable stored in spp in prepare_label")
self.rm.bindings_to_frame_reg.clear()
#
for i in range(len(inputargs)):
@@ -1062,18 +1064,6 @@
resloc = self.after_call(op.result)
return [resloc] + locs
- def _prepare_args_for_new_op(self, new_args):
- gc_ll_descr = self.cpu.gc_ll_descr
- args = gc_ll_descr.args_for_new(new_args)
- arglocs = []
- for i in range(len(args)):
- arg = args[i]
- t = TempInt()
- l = self.force_allocate_reg(t, selected_reg=r.MANAGED_REGS[i])
- self.assembler.load(l, imm(arg))
- arglocs.append(t)
- return arglocs
-
def prepare_force_spill(self, op):
self.force_spill_var(op.getarg(0))
return []
diff --git a/rpython/jit/backend/ppc/runner.py
b/rpython/jit/backend/ppc/runner.py
--- a/rpython/jit/backend/ppc/runner.py
+++ b/rpython/jit/backend/ppc/runner.py
@@ -2,6 +2,7 @@
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.rtyper.llinterp import LLInterpreter
from rpython.rlib import rgc
+from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER
from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU
from rpython.jit.backend.ppc.ppc_assembler import AssemblerPPC
from rpython.jit.backend.ppc.arch import WORD
@@ -79,3 +80,7 @@
mc.copy_to_raw_memory(jmp)
# positions invalidated
looptoken.compiled_loop_token.invalidate_positions = []
+
+ def get_all_loop_runs(self):
+ # not implemented
+ return lltype.malloc(LOOP_RUN_CONTAINER, 0)
diff --git a/rpython/jit/backend/ppc/test/autopath.py
b/rpython/jit/backend/ppc/test/autopath.py
deleted file mode 100644
--- a/rpython/jit/backend/ppc/test/autopath.py
+++ /dev/null
@@ -1,114 +0,0 @@
-"""
-self cloning, automatic path configuration
-
-copy this into any subdirectory of pypy from which scripts need
-to be run, typically all of the test subdirs.
-The idea is that any such script simply issues
-
- import autopath
-
-and this will make sure that the parent directory containing "pypy"
-is in sys.path.
-
-If you modify the master "autopath.py" version (in pypy/tool/autopath.py)
-you can directly run it which will copy itself on all autopath.py files
-it finds under the pypy root directory.
-
-This module always provides these attributes:
-
- pypydir pypy root directory path
- this_dir directory where this autopath.py resides
-
-"""
-
-
-def __dirinfo(part):
- """ return (partdir, this_dir) and insert parent of partdir
- into sys.path. If the parent directories don't have the part
- an EnvironmentError is raised."""
-
- import sys, os
- try:
- head = this_dir = os.path.realpath(os.path.dirname(__file__))
- except NameError:
- head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
-
- while head:
- partdir = head
- head, tail = os.path.split(head)
- if tail == part:
- break
- else:
- raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir)
-
- pypy_root = os.path.join(head, '')
- try:
- sys.path.remove(head)
- except ValueError:
- pass
- sys.path.insert(0, head)
-
- munged = {}
- for name, mod in sys.modules.items():
- if '.' in name:
- continue
- fn = getattr(mod, '__file__', None)
- if not isinstance(fn, str):
- continue
- newname = os.path.splitext(os.path.basename(fn))[0]
- if not newname.startswith(part + '.'):
- continue
- path = os.path.join(os.path.dirname(os.path.realpath(fn)), '')
- if path.startswith(pypy_root) and newname != part:
- modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep)
- if newname != '__init__':
- modpaths.append(newname)
- modpath = '.'.join(modpaths)
- if modpath not in sys.modules:
- munged[modpath] = mod
-
- for name, mod in munged.iteritems():
- if name not in sys.modules:
- sys.modules[name] = mod
- if '.' in name:
- prename = name[:name.rfind('.')]
- postname = name[len(prename)+1:]
- if prename not in sys.modules:
- __import__(prename)
- if not hasattr(sys.modules[prename], postname):
- setattr(sys.modules[prename], postname, mod)
-
- return partdir, this_dir
-
-def __clone():
- """ clone master version of autopath.py into all subdirs """
- from os.path import join, walk
- if not this_dir.endswith(join('pypy','tool')):
- raise EnvironmentError("can only clone master version "
- "'%s'" % join(pypydir, 'tool',_myname))
-
-
- def sync_walker(arg, dirname, fnames):
- if _myname in fnames:
- fn = join(dirname, _myname)
- f = open(fn, 'rwb+')
- try:
- if f.read() == arg:
- print "checkok", fn
- else:
- print "syncing", fn
- f = open(fn, 'w')
- f.write(arg)
- finally:
- f.close()
- s = open(join(pypydir, 'tool', _myname), 'rb').read()
- walk(pypydir, sync_walker, s)
-
-_myname = 'autopath.py'
-
-# set guaranteed attributes
-
-pypydir, this_dir = __dirinfo('pypy')
-
-if __name__ == '__main__':
- __clone()
diff --git a/rpython/jit/backend/ppc/test/test_call_assembler.py
b/rpython/jit/backend/ppc/test/test_call_assembler.py
deleted file mode 100644
--- a/rpython/jit/backend/ppc/test/test_call_assembler.py
+++ /dev/null
@@ -1,76 +0,0 @@
-import py
-from rpython.jit.metainterp.history import BoxInt, ConstInt
-from rpython.jit.metainterp.history import (BoxPtr, ConstPtr, BasicFailDescr,
- BasicFinalDescr)
-from rpython.jit.metainterp.history import JitCellToken
-from rpython.jit.metainterp.resoperation import rop, ResOperation
-from rpython.jit.codewriter import heaptracker
-from rpython.jit.backend.llsupport.descr import GcCache
-from rpython.jit.backend.llsupport.gc import GcLLDescription
-from rpython.jit.backend.detect_cpu import getcpuclass
-from rpython.jit.tool.oparser import parse
-from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
-from rpython.rtyper.annlowlevel import llhelper
-from rpython.rtyper.lltypesystem import rclass, rstr
-from rpython.jit.backend.llsupport.gc import GcLLDescr_framework
-
-from rpython.jit.codewriter.effectinfo import EffectInfo
-from rpython.jit.backend.ppc.runner import PPC_CPU
-from rpython.jit.backend.ppc.test.test_runner import FakeStats
-
-class TestAssembler(object):
-
- type_system = 'lltype'
-
- def setup_class(cls):
- cls.cpu = PPC_CPU(rtyper=None, stats=FakeStats())
- cls.cpu.setup_once()
-
- def interpret_direct_entry_point(self, ops, args, namespace):
- loop = self.parse(ops, namespace)
- looptoken = JitCellToken()
- self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
- param_sign_list = []
- for i, arg in enumerate(args):
- if isinstance(arg, int):
- param_sign_list.append(lltype.Signed)
- elif isinstance(arg, float):
- assert 0, "not implemented yet"
- else:
- assert 0, "not implemented yet"
-
- signature = lltype.FuncType(param_sign_list, lltype.Signed)
- fail_descr = self.cpu.execute_token(looptoken, *args)
- return fail_descr
-
- def parse(self, s, namespace, boxkinds=None):
- return parse(s, self.cpu, namespace,
- type_system=self.type_system,
- boxkinds=boxkinds)
-
- # XXX this test should also be used by the other backends
- def test_call_assembler_vary_arguments(self):
- namespace = {}
- numargs = 20
-
- for i in range(numargs + 1):
- namespace["fdescr%d" % i] = BasicFailDescr(i)
- namespace["finishdescr"] = BasicFinalDescr(numargs + 1)
-
- for i in range(1, numargs + 1):
- arglist = []
- guardlist = []
-
- for k in range(i):
- name = "i%d" % k
- arglist.append(name)
- guardlist.append("guard_value(%s, %d, descr=fdescr%d) [%s]"
- % (name, k, k, name))
-
- argstr = "".join(("[", ", ".join(arglist), "]\n"))
- guardstr = "\n".join(guardlist) + "\n"
- finish = "finish(descr=finishdescr)\n"
-
- trace = "".join((argstr, guardstr, finish))
- fail_descr = self.interpret_direct_entry_point(trace, range(i),
namespace)
- assert fail_descr.identifier == namespace["finishdescr"].identifier
diff --git a/rpython/jit/backend/ppc/test/test_calling_convention.py
b/rpython/jit/backend/ppc/test/test_calling_convention.py
--- a/rpython/jit/backend/ppc/test/test_calling_convention.py
+++ b/rpython/jit/backend/ppc/test/test_calling_convention.py
@@ -1,5 +1,6 @@
from rpython.jit.backend.test.calling_convention_test import CallingConvTests
from rpython.jit.backend.ppc.codebuilder import PPCBuilder
+from rpython.rtyper.lltypesystem import lltype, rffi
import rpython.jit.backend.ppc.register as r
@@ -10,7 +11,7 @@
mc = PPCBuilder()
mc.mr(r.r3.value, r.r1.value)
mc.blr()
- return mc.materialize(self.cpu, [])
+ return rffi.cast(lltype.Signed, mc.get_assembler_function())
def get_alignment_requirements(self):
return 16
diff --git a/rpython/jit/backend/ppc/test/test_field.py
b/rpython/jit/backend/ppc/test/test_field.py
--- a/rpython/jit/backend/ppc/test/test_field.py
+++ b/rpython/jit/backend/ppc/test/test_field.py
@@ -1,5 +1,3 @@
-import autopath
-
from rpython.jit.backend.ppc.field import Field
from py.test import raises
diff --git a/rpython/jit/backend/ppc/test/test_form.py
b/rpython/jit/backend/ppc/test/test_form.py
--- a/rpython/jit/backend/ppc/test/test_form.py
+++ b/rpython/jit/backend/ppc/test/test_form.py
@@ -1,11 +1,11 @@
-import autopath
from rpython.jit.backend.ppc.codebuilder import b
import random
import sys
+from py.test import raises
from rpython.jit.backend.ppc.form import Form, FormException
from rpython.jit.backend.ppc.field import Field
-from rpython.jit.backend.ppc.assembler import Assembler
+from rpython.jit.backend.ppc.opassembler import OpAssembler as Assembler
# 0 31
# +-------------------------------+
@@ -23,9 +23,9 @@
'hh': Field('hh', 0, 7),
}
-def p(w):
+def p(a):
import struct
- w = w.assemble()
+ w = a.insts[-1].assemble()
return struct.pack('>i', w)
class TestForm(Form):
@@ -43,26 +43,28 @@
j = i(h=1)
k = i(l=3)
raises(FormException, k, l=0)
+ insts = []
a = T()
a.i(5, 6)
- assert p(a.assemble0()[0]) == '\000\005\000\006'
+ assert p(a) == '\000\005\000\006'
a = T()
a.j(2)
- assert p(a.assemble0()[0]) == '\000\001\000\002'
+ assert p(a) == '\000\001\000\002'
a = T()
a.k(4)
- assert p(a.assemble0()[0]) == '\000\004\000\003'
+ assert p(a) == '\000\004\000\003'
def test_defdesc(self):
class T(Assembler):
i = TestForm('hh', 'hl', 'lh', 'll')()
i.default(hl=0).default(hh=1)
+ insts = []
a = T()
a.i(1, 2, 3, 4)
- assert p(a.assemble0()[0]) == '\001\002\003\004'
+ assert p(a) == '\001\002\003\004'
a = T()
a.i(1, 3, 4)
- assert p(a.assemble0()[0]) == '\001\000\003\004'
+ assert p(a) == '\001\000\003\004'
a = T()
a.i(3, 4)
- assert p(a.assemble0()[0]) == '\001\000\003\004'
+ assert p(a) == '\001\000\003\004'
diff --git a/rpython/jit/backend/ppc/test/test_generated.py
b/rpython/jit/backend/ppc/test/test_generated.py
deleted file mode 100644
--- a/rpython/jit/backend/ppc/test/test_generated.py
+++ /dev/null
@@ -1,525 +0,0 @@
-import py
-from rpython.jit.metainterp.history import (AbstractFailDescr,
- AbstractDescr,
- BasicFailDescr,
- BoxInt, Box, BoxPtr,
- ConstInt, ConstPtr,
- BoxObj, Const,
- ConstObj, BoxFloat, ConstFloat)
-from rpython.jit.metainterp.history import JitCellToken
-from rpython.jit.metainterp.resoperation import ResOperation, rop
-from rpython.rtyper.test.test_llinterp import interpret
-from rpython.jit.backend.detect_cpu import getcpuclass
-
-CPU = getcpuclass()
-class TestStuff(object):
-
- def test0(self):
- faildescr1 = BasicFailDescr(1)
- faildescr2 = BasicFailDescr(2)
- v1 = BoxInt()
- v2 = BoxInt()
- v3 = BoxInt()
- v4 = BoxInt()
- v5 = BoxInt()
- v6 = BoxInt()
- v7 = BoxInt()
- v8 = BoxInt()
- v9 = BoxInt()
- v10 = BoxInt()
- v11 = BoxInt()
- v12 = BoxInt()
- cpu = CPU(None, None)
- cpu.setup_once()
- inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
- operations = [
- ResOperation(rop.INT_SUB, [ConstInt(-1073741824), v7], v11),
- ResOperation(rop.INT_GE, [v3, ConstInt(23)], v12),
- ResOperation(rop.GUARD_TRUE, [v12], None, descr=faildescr1),
- ResOperation(rop.FINISH, [v9, v6, v10, v2, v8, v5, v1, v4], None,
descr=faildescr2),
- ]
- looptoken = JitCellToken()
- operations[2].setfailargs([v12, v8, v3, v2, v1, v11])
- cpu.compile_loop(inputargs, operations, looptoken)
- args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12]
- op = cpu.execute_token(looptoken, *args)
- assert cpu.get_latest_value_int(0) == 0
- assert cpu.get_latest_value_int(1) == 62
- assert cpu.get_latest_value_int(2) == -19
- assert cpu.get_latest_value_int(3) == -26
- assert cpu.get_latest_value_int(4) == -12
- assert cpu.get_latest_value_int(5) == -1073741787
-
- def test_overflow(self):
- faildescr1 = BasicFailDescr(1)
- faildescr2 = BasicFailDescr(2)
- faildescr3 = BasicFailDescr(3)
- v1 = BoxInt()
- v2 = BoxInt()
- v3 = BoxInt()
- v4 = BoxInt()
- v5 = BoxInt()
- v6 = BoxInt()
- v7 = BoxInt()
- v8 = BoxInt()
- v9 = BoxInt()
- v10 = BoxInt()
- v11 = BoxInt()
- v12 = BoxInt()
- v13 = BoxInt()
- v14 = BoxInt()
- v15 = BoxInt()
- v16 = BoxInt()
- v17 = BoxInt()
- v18 = BoxInt()
- cpu = CPU(None, None)
- cpu.setup_once()
- inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
- operations = [
- ResOperation(rop.INT_SUB, [ConstInt(21), v5], v11),
- ResOperation(rop.INT_MUL_OVF, [v8, v4], v12),
- ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1),
- ResOperation(rop.UINT_LT, [v10, v3], v13),
- ResOperation(rop.INT_IS_TRUE, [v3], v14),
- ResOperation(rop.INT_XOR, [v9, v8], v15),
- ResOperation(rop.INT_LE, [v12, v6], v16),
- ResOperation(rop.UINT_GT, [v15, v5], v17),
- ResOperation(rop.UINT_LE, [ConstInt(-9), v13], v18),
- ResOperation(rop.GUARD_FALSE, [v13], None, descr=faildescr2),
- ResOperation(rop.FINISH, [v7, v1, v2], None, descr=faildescr3),
- ]
- operations[2].setfailargs([v10, v6])
- operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1])
- looptoken = JitCellToken()
- cpu.compile_loop(inputargs, operations, looptoken)
- args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0]
- op = cpu.execute_token(looptoken, *args)
- assert cpu.get_latest_value_int(0) == 105
- assert cpu.get_latest_value_int(1) == 63
- assert cpu.get_latest_value_int(2) == 0
- assert cpu.get_latest_value_int(3) == 0
- assert cpu.get_latest_value_int(4) == 16
- assert cpu.get_latest_value_int(5) == 1
- assert cpu.get_latest_value_int(6) == 16
-
- def test_sub_with_neg_const_first_arg(self):
- faildescr1 = BasicFailDescr(1)
- faildescr2 = BasicFailDescr(2)
- faildescr3 = BasicFailDescr(3)
- v1 = BoxInt()
- v2 = BoxInt()
- v3 = BoxInt()
- v4 = BoxInt()
- v5 = BoxInt()
- v6 = BoxInt()
- v7 = BoxInt()
- v8 = BoxInt()
- v9 = BoxInt()
- v10 = BoxInt()
- v11 = BoxInt()
- v12 = BoxInt()
- tmp13 = BoxInt()
- cpu = CPU(None, None)
- cpu.setup_once()
- inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
- operations = [
- ResOperation(rop.INT_EQ, [ConstInt(17), v9], v11),
- ResOperation(rop.INT_SUB_OVF, [ConstInt(-32), v7], v12),
- ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1),
- ResOperation(rop.INT_IS_ZERO, [v12], tmp13),
- ResOperation(rop.GUARD_TRUE, [tmp13], None, descr=faildescr2),
- ResOperation(rop.FINISH, [v5, v2, v1, v10, v3, v8, v4, v6], None,
descr=faildescr3)
- ]
- operations[2].setfailargs([v8, v3])
- operations[4].setfailargs([v2, v12, v1, v3, v4])
- looptoken = JitCellToken()
- cpu.compile_loop(inputargs, operations, looptoken)
- args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6]
- op = cpu.execute_token(looptoken, *args)
- assert op.identifier == 2
- assert cpu.get_latest_value_int(0) == 24
- assert cpu.get_latest_value_int(1) == -32
- assert cpu.get_latest_value_int(2) == -5
- assert cpu.get_latest_value_int(3) == 46
- assert cpu.get_latest_value_int(4) == -15
-
- def test_tempbox_spilling_in_sub(self):
- faildescr1 = BasicFailDescr(1)
- faildescr2 = BasicFailDescr(2)
- v1 = BoxInt()
- v2 = BoxInt()
- v3 = BoxInt()
- v4 = BoxInt()
- v5 = BoxInt()
- v6 = BoxInt()
- v7 = BoxInt()
- v8 = BoxInt()
- v9 = BoxInt()
- v10 = BoxInt()
- v11 = BoxInt()
- v12 = BoxInt()
- v13 = BoxInt()
- v14 = BoxInt()
- v15 = BoxInt()
- cpu = CPU(None, None)
- cpu.setup_once()
- inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
- operations = [
- ResOperation(rop.INT_LT, [v9, v9], v11),
- ResOperation(rop.INT_ADD, [ConstInt(715827882), v4], v12),
- ResOperation(rop.INT_NEG, [v11], v13),
- ResOperation(rop.INT_IS_TRUE, [v3], v14),
- ResOperation(rop.INT_SUB_OVF, [v3, ConstInt(-95)], v15),
- ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1),
- ResOperation(rop.FINISH, [v8, v2, v6, v5, v7, v1, v10], None,
descr=faildescr2),
- ]
- operations[5].setfailargs([])
- looptoken = JitCellToken()
- cpu.compile_loop(inputargs, operations, looptoken)
- args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64]
- op = cpu.execute_token(looptoken, *args)
- assert cpu.get_latest_value_int(0) == -29
- assert cpu.get_latest_value_int(1) == -3
- assert cpu.get_latest_value_int(2) == 22
- assert cpu.get_latest_value_int(3) == 12
- assert cpu.get_latest_value_int(4) == -54
- assert cpu.get_latest_value_int(5) == 19
- assert cpu.get_latest_value_int(6) == -64
-
- def test_tempbox2(self):
- faildescr1 = BasicFailDescr(1)
- faildescr2 = BasicFailDescr(2)
- v1 = BoxInt()
- v2 = BoxInt()
- v3 = BoxInt()
- v4 = BoxInt()
- v5 = BoxInt()
- v6 = BoxInt()
- v7 = BoxInt()
- v8 = BoxInt()
- v9 = BoxInt()
- v10 = BoxInt()
- v11 = BoxInt()
- v12 = BoxInt()
- v13 = BoxInt()
- v14 = BoxInt()
- v15 = BoxInt()
- cpu = CPU(None, None)
- cpu.setup_once()
- inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
- operations = [
- ResOperation(rop.INT_LT, [v5, ConstInt(-67)], v11),
- ResOperation(rop.INT_INVERT, [v2], v12),
- ResOperation(rop.INT_SUB, [ConstInt(-45), v2], v13),
- ResOperation(rop.INT_SUB, [ConstInt(99), v6], v14),
- ResOperation(rop.INT_MUL_OVF, [v6, v9], v15),
- ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1),
- ResOperation(rop.FINISH, [v1, v4, v10, v8, v7, v3], None,
descr=faildescr2),
- ]
- looptoken = JitCellToken()
- operations[5].setfailargs([])
- cpu.compile_loop(inputargs, operations, looptoken)
- args = [1073741824 , 95 , -16 , 5 , 92 , 12 , 32 , 17 , 37 , -63]
- op = cpu.execute_token(looptoken, *args)
- assert cpu.get_latest_value_int(0) == 1073741824
- assert cpu.get_latest_value_int(1) == 5
- assert cpu.get_latest_value_int(2) == -63
- assert cpu.get_latest_value_int(3) == 17
- assert cpu.get_latest_value_int(4) == 32
- assert cpu.get_latest_value_int(5) == -16
-
- def test_wrong_guard(self):
- # generated by:
- # ../test/ test/test_zll_random.py -l -k arm -s --block-length=10
--random-seed=4338
-
- faildescr1 = BasicFailDescr(1)
- faildescr2 = BasicFailDescr(2)
- faildescr3 = BasicFailDescr(3)
- faildescr4 = BasicFailDescr(4)
- v1 = BoxInt(32)
- v2 = BoxInt(41)
- v3 = BoxInt(-9)
- v4 = BoxInt(12)
- v5 = BoxInt(-18)
- v6 = BoxInt(46)
- v7 = BoxInt(15)
- v8 = BoxInt(17)
- v9 = BoxInt(10)
- v10 = BoxInt(12)
- v11 = BoxInt()
- v12 = BoxInt()
- v13 = BoxInt()
- v14 = BoxInt()
- tmp15 = BoxInt()
- tmp16 = BoxInt()
- tmp17 = BoxInt()
- cpu = CPU(None, None)
- cpu.setup_once()
- inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
- operations = [
- ResOperation(rop.INT_IS_TRUE, [v1], tmp15),
- ResOperation(rop.GUARD_TRUE, [tmp15], None, descr=faildescr1),
- ResOperation(rop.INT_GT, [v4, v5], v11),
- ResOperation(rop.INT_XOR, [ConstInt(-4), v7], v12),
- ResOperation(rop.INT_MUL, [ConstInt(23), v11], v13),
- ResOperation(rop.UINT_GE, [ConstInt(1), v13], v14),
- ResOperation(rop.INT_IS_ZERO, [v14], tmp16),
- ResOperation(rop.GUARD_TRUE, [tmp16], None, descr=faildescr2),
- ResOperation(rop.INT_IS_TRUE, [v12], tmp17),
- ResOperation(rop.GUARD_FALSE, [tmp17], None, descr=faildescr3),
- ResOperation(rop.FINISH, [v8, v10, v6, v3, v2, v9], None,
descr=faildescr4),
- ]
- looptoken = JitCellToken()
- operations[1].setfailargs([v8, v6, v1])
- operations[7].setfailargs([v4])
- operations[9].setfailargs([v10, v13])
- args = [32 , 41 , -9 , 12 , -18 , 46 , 15 , 17 , 10 , 12]
- cpu.compile_loop(inputargs, operations, looptoken)
- op = cpu.execute_token(looptoken, *args)
- assert op.identifier == 3
- assert cpu.get_latest_value_int(0) == 12
- assert cpu.get_latest_value_int(1) == 23
-
- def test_wrong_guard2(self):
- # random seed: 8029
- # block length: 10
- faildescr1 = BasicFailDescr(1)
- faildescr2 = BasicFailDescr(2)
- faildescr3 = BasicFailDescr(3)
- v1 = BoxInt()
- v2 = BoxInt()
- v3 = BoxInt()
- v4 = BoxInt()
- v5 = BoxInt()
- v6 = BoxInt()
- v7 = BoxInt()
- v8 = BoxInt()
- v9 = BoxInt()
- v10 = BoxInt()
- v11 = BoxInt()
- v12 = BoxInt()
- v13 = BoxInt()
- v14 = BoxInt()
- v15 = BoxInt()
- v16 = BoxInt()
- tmp17 = BoxInt()
- cpu = CPU(None, None)
- cpu.setup_once()
- inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
- operations = [
- ResOperation(rop.INT_ADD_OVF, [v8, ConstInt(-30)], v11),
- ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1),
- ResOperation(rop.UINT_LE, [v11, v1], v12),
- ResOperation(rop.INT_AND, [v11, ConstInt(31)], tmp17),
- ResOperation(rop.UINT_RSHIFT, [v12, tmp17], v13),
- ResOperation(rop.INT_NE, [v3, v2], v14),
- ResOperation(rop.INT_NE, [ConstInt(1), v11], v15),
- ResOperation(rop.INT_NE, [ConstInt(23), v15], v16),
- ResOperation(rop.GUARD_FALSE, [v15], None, descr=faildescr2),
- ResOperation(rop.FINISH, [v4, v10, v6, v5, v9, v7], None,
descr=faildescr3),
- ]
- operations[1].setfailargs([v6, v8, v1, v4])
- operations[8].setfailargs([v5, v9])
- looptoken = JitCellToken()
- cpu.compile_loop(inputargs, operations, looptoken)
- args = [-8 , 0 , 62 , 35 , 16 , 9 , 30 , 581610154 , -1 , 738197503]
- op = cpu.execute_token(looptoken, *args)
- assert op.identifier == 2
- assert cpu.get_latest_value_int(0) == 16
- assert cpu.get_latest_value_int(1) == -1
-
- def test_wrong_guard3(self):
- # random seed: 8029
- # block length: 10
- faildescr1 = BasicFailDescr(1)
- faildescr2 = BasicFailDescr(2)
- faildescr3 = BasicFailDescr(3)
- faildescr4 = BasicFailDescr(4)
- v1 = BoxInt()
- v2 = BoxInt()
- v3 = BoxInt()
- v4 = BoxInt()
- v5 = BoxInt()
- v6 = BoxInt()
- v7 = BoxInt()
- v8 = BoxInt()
- v9 = BoxInt()
- v10 = BoxInt()
- v11 = BoxInt()
- v12 = BoxInt()
- v13 = BoxInt()
- v14 = BoxInt()
- v15 = BoxInt()
- v16 = BoxInt()
- cpu = CPU(None, None)
- cpu.setup_once()
- inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
- operations = [
- ResOperation(rop.UINT_LT, [ConstInt(-11), v7], v11),
- ResOperation(rop.INT_GE, [v3, v5], v12),
- ResOperation(rop.INT_INVERT, [v9], v13),
- ResOperation(rop.GUARD_VALUE, [v13, ConstInt(14)], None,
descr=faildescr3),
- ResOperation(rop.INT_IS_ZERO, [v12], v14),
- ResOperation(rop.INT_SUB, [v2, v13], v15),
- ResOperation(rop.GUARD_VALUE, [v15, ConstInt(-32)], None,
descr=faildescr4),
- ResOperation(rop.INT_FLOORDIV, [v3, ConstInt(805306366)], v16),
- ResOperation(rop.GUARD_VALUE, [v15, ConstInt(0)], None,
descr=faildescr1),
- ResOperation(rop.FINISH, [v10, v8, v1, v6, v4], None,
descr=faildescr2),
- ]
- operations[3].setfailargs([])
- operations[-4].setfailargs([v15])
- operations[-2].setfailargs([v9, v4, v10, v11, v14])
- looptoken = JitCellToken()
- cpu.compile_loop(inputargs, operations, looptoken)
- args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882
, -15 , 536870912]
- op = cpu.execute_token(looptoken, *args)
- assert op.identifier == 1
- assert cpu.get_latest_value_int(0) == -15
- assert cpu.get_latest_value_int(1) == -9
- assert cpu.get_latest_value_int(2) == 536870912
- assert cpu.get_latest_value_int(3) == 0
- assert cpu.get_latest_value_int(4) == 0
-
- def test_wrong_result(self):
- # generated by:
- # ../test/ test/test_zll_random.py -l -k arm -s --block-length=10
--random-seed=7389
- faildescr1 = BasicFailDescr(1)
- faildescr2 = BasicFailDescr(2)
- faildescr3 = BasicFailDescr(3)
- faildescr4 = BasicFailDescr(4)
- v1 = BoxInt()
- v2 = BoxInt()
- v3 = BoxInt()
- v4 = BoxInt()
- v5 = BoxInt()
- v6 = BoxInt()
- v7 = BoxInt()
- v8 = BoxInt()
- v9 = BoxInt()
- v10 = BoxInt()
- v11 = BoxInt()
- v12 = BoxInt()
- v13 = BoxInt()
- v14 = BoxInt()
- v15 = BoxInt()
- tmp16 = BoxInt()
- tmp17 = BoxInt()
- cpu = CPU(None, None)
- cpu.setup_once()
- inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
- operations = [
- ResOperation(rop.INT_IS_TRUE, [v3], tmp16),
- ResOperation(rop.GUARD_TRUE, [tmp16], None, descr=faildescr1),
- ResOperation(rop.INT_AND, [v7, ConstInt(31)], tmp17),
- ResOperation(rop.INT_RSHIFT, [v5, tmp17], v11),
- ResOperation(rop.INT_OR, [v6, v8], v12),
- ResOperation(rop.GUARD_VALUE, [v11, ConstInt(-2)], None,
descr=faildescr2),
- ResOperation(rop.INT_LE, [ConstInt(1789569706), v10], v13),
- ResOperation(rop.INT_IS_TRUE, [v4], v14),
- ResOperation(rop.INT_XOR, [v14, v3], v15),
- ResOperation(rop.GUARD_VALUE, [v8, ConstInt(-8)], None,
descr=faildescr3),
- ResOperation(rop.FINISH, [v1, v2, v9], None, descr=faildescr4),
- ]
- operations[1].setfailargs([v9, v1])
- operations[5].setfailargs([v10, v2, v11, v3])
- operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8])
- looptoken = JitCellToken()
- cpu.compile_loop(inputargs, operations, looptoken)
- args = [0 , -2 , 24 , 1 , -4 , 13 , -95 , 33 , 2 , -44]
- op = cpu.execute_token(looptoken, *args)
- assert op.identifier == 3
- assert cpu.get_latest_value_int(0) == -4
- assert cpu.get_latest_value_int(1) == -95
- assert cpu.get_latest_value_int(2) == 45
- assert cpu.get_latest_value_int(3) == 1
- assert cpu.get_latest_value_int(4) == -2
- assert cpu.get_latest_value_int(5) == 0
- assert cpu.get_latest_value_int(6) == 33
-
- def test_int_add(self):
- # random seed: 1202
- # block length: 4
- # AssertionError: Got 1431655764, expected 357913940 for value #3
- faildescr1 = BasicFailDescr(1)
- faildescr2 = BasicFailDescr(2)
- v1 = BoxInt()
- v2 = BoxInt()
- v3 = BoxInt()
- v4 = BoxInt()
- v5 = BoxInt()
- v6 = BoxInt()
- v7 = BoxInt()
- v8 = BoxInt()
- v9 = BoxInt()
- v10 = BoxInt()
- v11 = BoxInt()
- tmp12 = BoxInt()
- cpu = CPU(None, None)
- cpu.setup_once()
- inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
- operations = [
- ResOperation(rop.INT_ADD, [ConstInt(-1073741825), v3], v11),
- ResOperation(rop.INT_IS_TRUE, [v1], tmp12),
- ResOperation(rop.GUARD_FALSE, [tmp12], None, descr=faildescr1),
- ResOperation(rop.FINISH, [v8, v2, v10, v6, v7, v9, v5, v4], None,
descr=faildescr2),
- ]
- operations[2].setfailargs([v10, v3, v6, v11, v9, v2])
- looptoken = JitCellToken()
- cpu.compile_loop(inputargs, operations, looptoken)
- args = [3 , -5 , 1431655765 , 47 , 12 , 1789569706 , 15 , 939524096 ,
16 , -43]
- op = cpu.execute_token(looptoken, *args)
- assert op.identifier == 1
- assert cpu.get_latest_value_int(0) == -43
- assert cpu.get_latest_value_int(1) == 1431655765
- assert cpu.get_latest_value_int(2) == 1789569706
- assert cpu.get_latest_value_int(3) == 357913940
- assert cpu.get_latest_value_int(4) == 16
- assert cpu.get_latest_value_int(5) == -5
-
- def test_wrong_result2(self):
- # block length 10
- # random seed 1
- f1 = BasicFailDescr(1)
- f2 = BasicFailDescr(2)
- f3 = BasicFailDescr(3)
- v1 = BoxInt()
- v2 = BoxInt()
- v3 = BoxInt()
- v4 = BoxInt()
- v5 = BoxInt()
- v6 = BoxInt()
- v7 = BoxInt()
- v8 = BoxInt()
- v9 = BoxInt()
- v10 = BoxInt()
- v11 = BoxInt()
- v12 = BoxInt()
- v13 = BoxInt()
- v14 = BoxInt()
- v15 = BoxInt()
- cpu = CPU(None, None)
- cpu.setup_once()
- inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
- operations = [
- ResOperation(rop.INT_LE, [v6, v1], v11),
- ResOperation(rop.SAME_AS, [ConstInt(-14)], v12),
- ResOperation(rop.INT_ADD, [ConstInt(24), v4], v13),
- ResOperation(rop.UINT_RSHIFT, [v6, ConstInt(0)], v14),
- ResOperation(rop.GUARD_VALUE, [v14, ConstInt(1)], None, descr=f3),
- ResOperation(rop.INT_MUL, [v13, ConstInt(12)], v15),
- ResOperation(rop.GUARD_FALSE, [v11], None, descr=f1),
- ResOperation(rop.FINISH, [v2, v3, v5, v7, v10, v8, v9], None,
descr=f2),
- ]
- operations[-2].setfailargs([v4, v10, v3, v9, v14, v2])
- operations[4].setfailargs([v14])
- looptoken = JitCellToken()
- cpu.compile_loop(inputargs, operations, looptoken)
- args = [14 , -20 , 18 , -2058005163 , 6 , 1 , -16 , 11 , 0 , 19]
- op = cpu.execute_token(looptoken, *args)
- assert op.identifier == 1
- assert cpu.get_latest_value_int(0) == -2058005163
- assert cpu.get_latest_value_int(1) == 19
- assert cpu.get_latest_value_int(2) == 18
- assert cpu.get_latest_value_int(3) == 0
- assert cpu.get_latest_value_int(4) == 1
- assert cpu.get_latest_value_int(5) == -20
diff --git a/rpython/jit/backend/ppc/test/test_ppc.py
b/rpython/jit/backend/ppc/test/test_ppc.py
--- a/rpython/jit/backend/ppc/test/test_ppc.py
+++ b/rpython/jit/backend/ppc/test/test_ppc.py
@@ -6,7 +6,8 @@
from rpython.jit.backend.ppc.register import *
from rpython.jit.backend.ppc import form
from rpython.jit.backend import detect_cpu
-from rpython.jit.backend.ppc.arch import IS_PPC_32, IS_PPC_64, WORD
+from rpython.jit.backend.ppc.arch import IS_PPC_32, IS_PPC_64, IS_BIG_ENDIAN
+from rpython.jit.backend.ppc.arch import WORD
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rtyper.annlowlevel import llhelper
@@ -15,7 +16,8 @@
class TestDisassemble(object):
def test_match(self):
- A = BasicPPCAssembler
+ class A(BasicPPCAssembler):
+ insts = []
a = A()
a.add(1, 2, 3)
inst = a.insts[-1]
@@ -29,12 +31,11 @@
- Create a function and call it
- Compare the return value with the expected result
"""
-def asmtest(expected=-1):
+def asmtest(expected):
def testmaker(test):
def newtest(self):
a = PPCBuilder()
test(self, a)
- #f = a.assemble()
f = a.get_assembler_function()
assert f() == expected
return newtest
@@ -196,10 +197,16 @@
a.li(3, 50)
if IS_PPC_32:
a.load_imm(r10, call_addr)
- else:
+ elif IS_BIG_ENDIAN:
+ # load the 3-words descriptor
a.load_from_addr(r10, call_addr)
a.load_from_addr(r2, call_addr+WORD)
a.load_from_addr(r11, call_addr+2*WORD)
+ else:
+ # no descriptor on little-endian, but the ABI says r12 must
+ # contain the function pointer
+ a.load_imm(r10, call_addr)
+ a.mr(12, 10)
a.mtctr(10)
a.bctr()
a.blr()
@@ -306,21 +313,6 @@
lltype.free(p, flavor="raw")
-class AsmCode(object):
- def __init__(self, size):
- self.code = MachineCodeBlockWrapper()
-
- def emit(self, insn):
- bytes = struct.pack("i", insn)
- for byte in bytes:
- self.code.writechar(byte)
-
- def get_function(self):
- i = self.code.materialize(AsmMemoryManager(), [])
- t = lltype.FuncType([], lltype.Signed)
- return rffi.cast(lltype.Ptr(t), i)
-
-
def func(arg):
return arg + 15
diff --git a/rpython/jit/backend/ppc/test/test_rassemblermaker.py
b/rpython/jit/backend/ppc/test/test_rassemblermaker.py
deleted file mode 100644
--- a/rpython/jit/backend/ppc/test/test_rassemblermaker.py
+++ /dev/null
@@ -1,39 +0,0 @@
-from rpython.jit.backend.ppc.rassemblermaker import make_rassembler
-from rpython.jit.backend.ppc.codebuilder import PPCAssembler
-
-RPPCAssembler = make_rassembler(PPCAssembler)
-
-_a = PPCAssembler()
-_a.add(3, 3, 4)
-add_r3_r3_r4 = _a.insts[0]
-
-def test_simple():
- ra = RPPCAssembler()
- ra.add(3, 3, 4)
- assert ra.insts == [add_r3_r3_r4]
-
-def test_rtyped():
- from rpython.rtyper.test.test_llinterp import interpret
- def f():
- ra = RPPCAssembler()
- ra.add(3, 3, 4)
- ra.lwz(1, 1, 1) # ensure that high bit doesn't produce long but r_uint
- return ra.insts[0]
- res = interpret(f, [])
- assert res == add_r3_r3_r4
-
-def test_mnemonic():
- mrs = []
- for A in PPCAssembler, RPPCAssembler:
- a = A()
- a.mr(3, 4)
- mrs.append(a.insts[0])
- assert mrs[0] == mrs[1]
-
-def test_spr_coding():
- mrs = []
- for A in PPCAssembler, RPPCAssembler:
- a = A()
- a.mtctr(3)
- mrs.append(a.insts[0])
- assert mrs[0] == mrs[1]
diff --git a/rpython/jit/backend/ppc/test/test_regalloc.py
b/rpython/jit/backend/ppc/test/test_regalloc.py
--- a/rpython/jit/backend/ppc/test/test_regalloc.py
+++ b/rpython/jit/backend/ppc/test/test_regalloc.py
@@ -1,5 +1,6 @@
from rpython.rtyper.lltypesystem import lltype, llmemory
-from rpython.rtyper.lltypesystem import rclass, rstr
+from rpython.rtyper.lltypesystem import rstr
+from rpython.rtyper import rclass
from rpython.rtyper.annlowlevel import llhelper
from rpython.rlib.objectmodel import instantiate
from rpython.jit.backend.ppc.locations import (imm, RegisterLocation,
@@ -8,8 +9,6 @@
from rpython.jit.backend.ppc.codebuilder import hi, lo
from rpython.jit.backend.ppc.ppc_assembler import AssemblerPPC
from rpython.jit.backend.ppc.arch import WORD
-from rpython.jit.backend.ppc.locations import get_spp_offset
-from rpython.jit.backend.detect_cpu import getcpuclass
from rpython.jit.codewriter.effectinfo import EffectInfo
from rpython.jit.codewriter import longlong
from rpython.jit.metainterp.history import BasicFailDescr, \
@@ -118,8 +117,8 @@
def test_mem_to_reg(self):
self.asm.regalloc_mov(stack(5), reg(10))
self.asm.regalloc_mov(stack(0), reg(0))
- exp_instrs = [MI("load", r10.value, SPP.value, -(5 * WORD + WORD)),
- MI("load", r0.value, SPP.value, -(WORD))]
+ exp_instrs = [MI("load", r10.value, SPP.value, get_spp_offset(5)),
+ MI("load", r0.value, SPP.value, get_spp_offset(0))]
assert self.asm.mc.instrs == exp_instrs
def test_mem_to_mem(self):
@@ -141,143 +140,15 @@
def test_reg_to_mem(self):
self.asm.regalloc_mov(reg(5), stack(10))
self.asm.regalloc_mov(reg(0), stack(2))
- exp_instrs = [MI("store", r5.value, SPP.value, -(10 * WORD + WORD)),
- MI("store", r0.value, SPP.value, -(2 * WORD + WORD))]
+ exp_instrs = [MI("store", r5.value, SPP.value, get_spp_offset(10)),
+ MI("store", r0.value, SPP.value, get_spp_offset(2))]
assert self.asm.mc.instrs == exp_instrs
def reg(i):
return RegisterLocation(i)
def stack(i):
- return StackLocation(i)
+ return StackLocation(i, get_spp_offset(i))
-CPU = getcpuclass()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit