Author: Armin Rigo <ar...@tunes.org> Branch: ppc-updated-backend Changeset: r80083:69f522aef55b Date: 2015-10-09 15:01 +0200 http://bitbucket.org/pypy/pypy/changeset/69f522aef55b/
Log: PPC Backend #7: PyPy Translation All tests pass, and a full PyPy translation works. Some hard gdb- ing but not too bad. 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 @@ -913,7 +913,7 @@ descr.adr_jump_offset = failure_recovery_pos relative_offset = tok.pos_recovery_stub - tok.offset guard_pos = block_start + tok.offset - if not tok.is_guard_not_invalidated: + if not tok.guard_not_invalidated(): # patch the guard jump to the stub # overwrite the generate NOP with a B_offs to the pos of the # stub diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -36,11 +36,9 @@ class ArmGuardToken(GuardToken): def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, - offset, exc, frame_depth, is_guard_not_invalidated=False, - is_guard_not_forced=False, fcond=c.AL): + offset, guard_opnum, frame_depth, fcond=c.AL): GuardToken.__init__(self, cpu, gcmap, faildescr, failargs, fail_locs, - exc, frame_depth, is_guard_not_invalidated, - is_guard_not_forced) + guard_opnum, frame_depth) self.fcond = fcond self.offset = offset @@ -175,10 +173,7 @@ self.mc.RSB_ri(resloc.value, l0.value, imm=0) return fcond - def build_guard_token(self, op, frame_depth, arglocs, offset, fcond, save_exc, - is_guard_not_invalidated=False, - is_guard_not_forced=False): - assert isinstance(save_exc, bool) + def build_guard_token(self, op, frame_depth, arglocs, offset, fcond): assert isinstance(fcond, int) descr = op.getdescr() assert isinstance(descr, AbstractFailDescr) @@ -189,16 +184,12 @@ failargs=op.getfailargs(), fail_locs=arglocs, offset=offset, - exc=save_exc, + guard_opnum=op.getopnum(), frame_depth=frame_depth, - is_guard_not_invalidated=is_guard_not_invalidated, - is_guard_not_forced=is_guard_not_forced, fcond=fcond) return token - def _emit_guard(self, op, arglocs, save_exc, - is_guard_not_invalidated=False, - is_guard_not_forced=False): + def _emit_guard(self, op, arglocs, is_guard_not_invalidated=False): if is_guard_not_invalidated: fcond = c.cond_none else: @@ -206,10 +197,9 @@ self.guard_success_cc = c.cond_none assert fcond != c.cond_none pos = self.mc.currpos() - token = self.build_guard_token(op, arglocs[0].value, arglocs[1:], pos, fcond, save_exc, - is_guard_not_invalidated, - is_guard_not_forced) + token = self.build_guard_token(op, arglocs[0].value, arglocs[1:], pos, fcond) self.pending_guards.append(token) + assert token.guard_not_invalidated() == is_guard_not_invalidated # For all guards that are not GUARD_NOT_INVALIDATED we emit a # breakpoint to ensure the location is patched correctly. In the case # of GUARD_NOT_INVALIDATED we use just a NOP, because it is only @@ -221,12 +211,12 @@ return c.AL def emit_op_guard_true(self, op, arglocs, regalloc, fcond): - fcond = self._emit_guard(op, arglocs, save_exc=False) + fcond = self._emit_guard(op, arglocs) return fcond def emit_op_guard_false(self, op, arglocs, regalloc, fcond): self.guard_success_cc = c.get_opposite_of(self.guard_success_cc) - fcond = self._emit_guard(op, arglocs, save_exc=False) + fcond = self._emit_guard(op, arglocs) return fcond def emit_op_guard_value(self, op, arglocs, regalloc, fcond): @@ -244,7 +234,7 @@ self.mc.VCMP(l0.value, l1.value) self.mc.VMRS(cond=fcond) self.guard_success_cc = c.EQ - fcond = self._emit_guard(op, failargs, save_exc=False) + fcond = self._emit_guard(op, failargs) return fcond emit_op_guard_nonnull = emit_op_guard_true @@ -256,14 +246,14 @@ def emit_op_guard_class(self, op, arglocs, regalloc, fcond): self._cmp_guard_class(op, arglocs, regalloc, fcond) self.guard_success_cc = c.EQ - self._emit_guard(op, arglocs[2:], save_exc=False) + self._emit_guard(op, arglocs[2:]) return fcond def emit_op_guard_nonnull_class(self, op, arglocs, regalloc, fcond): self.mc.CMP_ri(arglocs[0].value, 1) self._cmp_guard_class(op, arglocs, regalloc, c.HS) self.guard_success_cc = c.EQ - self._emit_guard(op, arglocs[2:], save_exc=False) + self._emit_guard(op, arglocs[2:]) return fcond def _cmp_guard_class(self, op, locs, regalloc, fcond): @@ -288,7 +278,7 @@ def emit_op_guard_gc_type(self, op, arglocs, regalloc, fcond): self._cmp_guard_gc_type(arglocs[0], arglocs[1].value, fcond) self.guard_success_cc = c.EQ - self._emit_guard(op, arglocs[2:], save_exc=False) + self._emit_guard(op, arglocs[2:]) return fcond def emit_op_guard_is_object(self, op, arglocs, regalloc, fcond): @@ -309,7 +299,7 @@ self.mc.LDRB_rr(r.ip.value, r.ip.value, r.lr.value) self.mc.TST_ri(r.ip.value, imm=(IS_OBJECT_FLAG & 0xff)) self.guard_success_cc = c.NE - self._emit_guard(op, arglocs[1:], save_exc=False) + self._emit_guard(op, arglocs[1:]) return fcond def emit_op_guard_subclass(self, op, arglocs, regalloc, fcond): @@ -353,12 +343,11 @@ self.mc.CMP_rr(r.ip.value, r.lr.value) # the guard passes if we get a result of "below or equal" self.guard_success_cc = c.LS - self._emit_guard(op, arglocs[2:], save_exc=False) + self._emit_guard(op, arglocs[2:]) return fcond def emit_op_guard_not_invalidated(self, op, locs, regalloc, fcond): - return self._emit_guard(op, locs, save_exc=False, - is_guard_not_invalidated=True) + return self._emit_guard(op, locs, is_guard_not_invalidated=True) def emit_op_label(self, op, arglocs, regalloc, fcond): self._check_frame_depth_debug(self.mc) @@ -498,7 +487,7 @@ self.mc.LDR_ri(loc.value, loc.value) self.mc.CMP_ri(loc.value, 0) self.guard_success_cc = c.EQ - fcond = self._emit_guard(op, failargs, save_exc=True) + fcond = self._emit_guard(op, failargs) # If the previous operation was a COND_CALL, overwrite its conditional # jump to jump over this GUARD_NO_EXCEPTION as well, if we can if self._find_nearby_operation(-1).getopnum() == rop.COND_CALL: @@ -515,7 +504,7 @@ self.mc.CMP_rr(r.ip.value, loc.value) self.guard_success_cc = c.EQ - self._emit_guard(op, failargs, save_exc=True) + self._emit_guard(op, failargs) self._store_and_reset_exception(self.mc, resloc) return fcond @@ -1047,7 +1036,7 @@ def store_force_descr(self, op, fail_locs, frame_depth): pos = self.mc.currpos() - guard_token = self.build_guard_token(op, frame_depth, fail_locs, pos, c.AL, True, False, True) + guard_token = self.build_guard_token(op, frame_depth, fail_locs, pos, c.AL) #self.pending_guards.append(guard_token) self._finish_gcmap = guard_token.gcmap self._store_force_index(op) @@ -1152,7 +1141,7 @@ self.mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs) self.mc.CMP_ri(r.ip.value, 0) self.guard_success_cc = c.EQ - self._emit_guard(op, arglocs, save_exc=True, is_guard_not_forced=True) + self._emit_guard(op, arglocs) return fcond def _genop_call_may_force(self, op, arglocs, regalloc, fcond): diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -23,8 +23,8 @@ class GuardToken(object): - def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, exc, - frame_depth, is_guard_not_invalidated, is_guard_not_forced): + def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, + guard_opnum, frame_depth): assert isinstance(faildescr, AbstractFailDescr) self.cpu = cpu self.faildescr = faildescr @@ -32,9 +32,16 @@ self.fail_locs = fail_locs self.gcmap = self.compute_gcmap(gcmap, failargs, fail_locs, frame_depth) - self.exc = exc - self.is_guard_not_invalidated = is_guard_not_invalidated - self.is_guard_not_forced = is_guard_not_forced + self.guard_opnum = guard_opnum + + def guard_not_invalidated(self): + return self.guard_opnum == rop.GUARD_NOT_INVALIDATED + + def must_save_exception(self): + guard_opnum = self.guard_opnum + return (guard_opnum == rop.GUARD_EXCEPTION or + guard_opnum == rop.GUARD_NO_EXCEPTION or + guard_opnum == rop.GUARD_NOT_FORCED) def compute_gcmap(self, gcmap, failargs, fail_locs, frame_depth): # note that regalloc has a very similar compute, but @@ -172,7 +179,7 @@ if box is not None and box.type == FLOAT: withfloats = True break - exc = guardtok.exc + exc = guardtok.must_save_exception() target = self.failure_recovery_code[exc + 2 * withfloats] fail_descr = cast_instance_to_gcref(guardtok.faildescr) fail_descr = rffi.cast(lltype.Signed, fail_descr) diff --git a/rpython/jit/backend/ppc/arch.py b/rpython/jit/backend/ppc/arch.py --- a/rpython/jit/backend/ppc/arch.py +++ b/rpython/jit/backend/ppc/arch.py @@ -70,7 +70,8 @@ LR_BC_OFFSET = 16 _GAP = 0 if IS_BIG_ENDIAN else 16 PARAM_SAVE_AREA_OFFSET = 48 - _GAP -THREADLOCAL_ADDR_OFFSET = 112 - _GAP +LOCAL_VARS_OFFSET = 112 - _GAP +THREADLOCAL_ADDR_OFFSET = LOCAL_VARS_OFFSET GPR_SAVE_AREA_OFFSET = 120 - _GAP REGISTERS_SAVED = [r.r25, r.r26, r.r27, r.r28, r.r29, r.r30, r.r31] 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 @@ -124,9 +124,9 @@ gcrootmap = self.asm.cpu.gc_ll_descr.gcrootmap if gcrootmap: if gcrootmap.is_shadow_stack and self.is_call_release_gil: - # in this mode, 'ebx' happens to contain the shadowstack + # in this mode, RSHADOWOLD happens to contain the shadowstack # top at this point, so reuse it instead of loading it again - ssreg = self.RSHADOWPTR + ssreg = self.RSHADOWOLD self.asm._reload_frame_if_necessary(self.mc, shadowstack_reg=ssreg) def emit_raw_call(self): 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 @@ -936,11 +936,9 @@ class PPCGuardToken(GuardToken): def __init__(self, cpu, gcmap, descr, failargs, faillocs, - exc, frame_depth, is_guard_not_invalidated=False, - is_guard_not_forced=False, fcond=c.cond_none): - GuardToken.__init__(self, cpu, gcmap, descr, failargs, faillocs, exc, - frame_depth, is_guard_not_invalidated, - is_guard_not_forced) + guard_opnum, frame_depth, fcond=c.cond_none): + GuardToken.__init__(self, cpu, gcmap, descr, failargs, faillocs, + guard_opnum, frame_depth) self.fcond = fcond 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 @@ -254,9 +254,7 @@ _mixin_ = True - def _emit_guard(self, op, arglocs, save_exc=False, - is_guard_not_invalidated=False, - is_guard_not_forced=False): + def _emit_guard(self, op, arglocs, is_guard_not_invalidated=False): if is_guard_not_invalidated: fcond = c.cond_none else: @@ -264,22 +262,18 @@ self.guard_success_cc = c.cond_none assert fcond != c.cond_none fcond = c.negate(fcond) - token = self.build_guard_token(op, arglocs[0].value, arglocs[1:], - fcond, save_exc, is_guard_not_invalidated, - is_guard_not_forced) + token = self.build_guard_token(op, arglocs[0].value, arglocs[1:], fcond) token.pos_jump_offset = self.mc.currpos() + assert token.guard_not_invalidated() == is_guard_not_invalidated if not is_guard_not_invalidated: self.mc.trap() # has to be patched later on self.pending_guard_tokens.append(token) - def build_guard_token(self, op, frame_depth, arglocs, fcond, save_exc, - is_guard_not_invalidated=False, - is_guard_not_forced=False): + def build_guard_token(self, op, frame_depth, arglocs, fcond): descr = op.getdescr() gcmap = allocate_gcmap(self, frame_depth, r.JITFRAME_FIXED_SIZE) token = PPCGuardToken(self.cpu, gcmap, descr, op.getfailargs(), - arglocs, save_exc, frame_depth, - is_guard_not_invalidated, is_guard_not_forced, + arglocs, op.getopnum(), frame_depth, fcond) return token @@ -440,7 +434,7 @@ def emit_guard_not_forced_2(self, op, arglocs, regalloc): guard_token = self.build_guard_token(op, arglocs[0].value, arglocs[1:], - c.cond_none, save_exc=False) + c.cond_none) self._finish_gcmap = guard_token.gcmap self._store_force_index(op) self.store_info_on_descr(0, guard_token) @@ -531,7 +525,7 @@ self.mc.load_from_addr(r.SCRATCH2, self.cpu.pos_exception()) self.mc.cmp_op(0, r.SCRATCH2.value, 0, imm=True) self.guard_success_cc = c.EQ - self._emit_guard(op, arglocs, save_exc=True) + self._emit_guard(op, arglocs) # If the previous operation was a COND_CALL, overwrite its conditional # jump to jump over this GUARD_NO_EXCEPTION as well, if we can if self._find_nearby_operation(regalloc,-1).getopnum() == rop.COND_CALL: @@ -553,7 +547,7 @@ 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._emit_guard(op, failargs) if resloc: mc.load(resloc.value, r.SCRATCH2.value, 0) @@ -1281,12 +1275,12 @@ self.mc.load_imm(r.r4, value) self.mc.cmp_op(0, r.r5.value, r.r4.value, imm=False) jump_if_eq = self.mc.currpos() - self.mc.nop() # patched later + self.mc.trap() # patched later return jump_if_eq def _call_assembler_patch_je(self, result_loc, je_location): jump_to_done = self.mc.currpos() - self.mc.nop() # patched later + self.mc.trap() # patched later # currpos = self.mc.currpos() pmc = OverwritingBuilder(self.mc, je_location, 1) @@ -1325,23 +1319,26 @@ baseofs = self.cpu.get_baseofs_of_frame_field() newlooptoken.compiled_loop_token.update_frame_info( oldlooptoken.compiled_loop_token, baseofs) - if IS_PPC_32 or not IS_BIG_ENDIAN: - # we overwrite the instructions at the old _ll_function_addr - # to start with a JMP to the new _ll_function_addr. - # Ideally we should rather patch all existing CALLs, but well. - mc = PPCBuilder() - mc.b_abs(target) - mc.copy_to_raw_memory(oldadr) - else: + if IS_PPC_64 and IS_BIG_ENDIAN: # PPC64 big-endian trampolines are data so overwrite the code # address in the function descriptor at the old address. # Copy the whole 3-word trampoline, even though the other - # words are always zero so far. + # words are always zero so far. That's not enough in all + # cases: if the "target" trampoline is itself redirected + # later, then the "old" trampoline won't be updated; so + # we still need the jump below to be safe. odata = rffi.cast(rffi.CArrayPtr(lltype.Signed), oldadr) tdata = rffi.cast(rffi.CArrayPtr(lltype.Signed), target) odata[0] = tdata[0] odata[1] = tdata[1] odata[2] = tdata[2] + oldadr += 3 * WORD + target += 3 * WORD + # we overwrite the instructions at the old _ll_function_addr + # to start with a JMP to the new _ll_function_addr. + mc = PPCBuilder() + mc.b_abs(target) + mc.copy_to_raw_memory(oldadr) class OpAssembler(IntOpAssembler, GuardOpAssembler, 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 @@ -8,7 +8,8 @@ GPR_SAVE_AREA_OFFSET, THREADLOCAL_ADDR_OFFSET, STD_FRAME_SIZE_IN_BYTES, - IS_BIG_ENDIAN) + IS_BIG_ENDIAN, + LOCAL_VARS_OFFSET) from rpython.jit.backend.ppc.helper.assembler import Saved_Volatiles from rpython.jit.backend.ppc.helper.regalloc import _check_imm_arg import rpython.jit.backend.ppc.register as r @@ -233,6 +234,7 @@ # Second argument is the new size, which is still in r0 here mc.mr(r.r4.value, r.r0.value) + # This trashes r0 and r2 self._store_and_reset_exception(mc, r.RCS2, r.RCS3) # Do the call @@ -283,6 +285,7 @@ mc.store(exctploc.value, r.r2.value, diff) def _reload_frame_if_necessary(self, mc, shadowstack_reg=None): + # might trash the VOLATILE registers different from r3 and f1 gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap: if gcrootmap.is_shadow_stack: @@ -492,6 +495,8 @@ old_mc = self.mc self.mc = mc + extra_stack_size = LOCAL_VARS_OFFSET + 4 * WORD + 8 + extra_stack_size = (extra_stack_size + 15) & ~15 if for_frame: # NOTE: don't save registers on the jitframe here! It might # override already-saved values that will be restored @@ -508,12 +513,12 @@ # 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) + self.mc.store_update(r.SCRATCH.value, r.SP.value, -extra_stack_size) + self.mc.std(r.RCS1.value, r.SP.value, LOCAL_VARS_OFFSET + 0 * WORD) + self.mc.std(r.RCS2.value, r.SP.value, LOCAL_VARS_OFFSET + 1 * WORD) + self.mc.std(r.RCS3.value, r.SP.value, LOCAL_VARS_OFFSET + 2 * WORD) + self.mc.std(r.r3.value, r.SP.value, LOCAL_VARS_OFFSET + 3 * WORD) + self.mc.stfd(r.f1.value, r.SP.value, LOCAL_VARS_OFFSET + 4 * WORD) saved_regs = None saved_fp_regs = None @@ -536,6 +541,8 @@ # since the call to write barrier can't collect # (and this is assumed a bit left and right here, like lack # of _reload_frame_if_necessary) + # This trashes r0 and r2, which is fine in this case + assert argument_loc is not r.r0 self._store_and_reset_exception(mc, r.RCS2, r.RCS3) if withcards: @@ -545,6 +552,8 @@ mc.mflr(r.RCS1.value) # func = rffi.cast(lltype.Signed, func) + # Note: if not 'for_frame', argument_loc is r0, which must carefully + # not be overwritten above mc.mr(r.r3.value, argument_loc.value) mc.load_imm(mc.RAW_CALL_REG, func) mc.raw_call() @@ -564,12 +573,12 @@ mc.andix(r.RCS2.value, r.RCS2.value, card_marking_mask & 0xFF) 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) + self.mc.ld(r.RCS1.value, r.SP.value, LOCAL_VARS_OFFSET + 0 * WORD) + self.mc.ld(r.RCS2.value, r.SP.value, LOCAL_VARS_OFFSET + 1 * WORD) + self.mc.ld(r.RCS3.value, r.SP.value, LOCAL_VARS_OFFSET + 2 * WORD) + self.mc.ld(r.r3.value, r.SP.value, LOCAL_VARS_OFFSET + 3 * WORD) + self.mc.lfd(r.f1.value, r.SP.value, LOCAL_VARS_OFFSET + 4 * WORD) + self.mc.addi(r.SP.value, r.SP.value, extra_stack_size) else: self._pop_core_regs_from_jitframe(mc, saved_regs) @@ -875,13 +884,12 @@ def target_arglocs(self, looptoken): return looptoken._ppc_arglocs - def materialize_loop(self, looptoken, show=False): + def materialize_loop(self, looptoken): self.datablockwrapper.done() self.datablockwrapper = None allblocks = self.get_asmmemmgr_blocks(looptoken) start = self.mc.materialize(self.cpu, allblocks, self.cpu.gc_ll_descr.gcrootmap) - #print "=== Loop start is at %s ===" % hex(r_uint(start)) return start def load_gcmap(self, mc, reg, gcmap): @@ -946,7 +954,7 @@ # relative_target = tok.pos_recovery_stub - tok.pos_jump_offset # - if not tok.is_guard_not_invalidated: + if not tok.guard_not_invalidated(): mc = PPCBuilder() mc.b_cond_offset(relative_target, tok.fcond) mc.copy_to_raw_memory(addr) @@ -1219,7 +1227,7 @@ force_realignment = (itemsize % WORD) != 0 if force_realignment: constsize += WORD - 1 - mc.addi(r.RSZ.value, r.RSZ.value, constsize) + mc.addi(r.RSZ.value, varsizeloc.value, constsize) if force_realignment: # "& ~(WORD-1)" bit_limit = 60 if WORD == 8 else 61 @@ -1324,8 +1332,10 @@ def notimplemented_op(self, op, arglocs, regalloc): - print "[PPC/asm] %s not implemented" % op.getopname() - raise NotImplementedError(op) + msg = '[PPC/asm] %s not implemented\n' % op.getopname() + if we_are_translated(): + llop.debug_print(lltype.Void, msg) + raise NotImplementedError(msg) operations = [notimplemented_op] * (rop._LAST + 1) 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 @@ -25,6 +25,7 @@ from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.rlib.objectmodel import we_are_translated +from rpython.rlib.debug import debug_print from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.rlib import rgc from rpython.rlib.rarithmetic import r_uint @@ -1115,8 +1116,10 @@ return locs def notimplemented(self, op): - print "[PPC/regalloc] %s not implemented" % op.getopname() - raise NotImplementedError(op) + msg = '[PPC/regalloc] %s not implemented\n' % op.getopname() + if we_are_translated(): + llop.debug_print(lltype.Void, msg) + raise NotImplementedError(msg) def force_int(intvalue): # a hack before transaction: force the intvalue argument through diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -3903,6 +3903,30 @@ x = self.cpu.get_float_value(deadframe, 0) assert longlong.getrealfloat(x) == 13.5 assert called == [finish_descr2] + del called[:] + + # compile a second replacement + ops = ''' + [f0, f1] + f2 = float_mul(f0, f1) + finish(f2)''' + loop3 = parse(ops) + looptoken3 = JitCellToken() + looptoken3.outermost_jitdriver_sd = FakeJitDriverSD() + self.cpu.compile_loop(loop3.inputargs, loop3.operations, looptoken3) + finish_descr3 = loop3.operations[-1].getdescr() + + # install it + self.cpu.redirect_call_assembler(looptoken2, looptoken3) + + # now, our call_assembler should go to looptoken3 + args = [longlong.getfloatstorage(0.5), + longlong.getfloatstorage(9.0)] # 0.5*9.0 == 1.25+3.25 + deadframe = self.cpu.execute_token(othertoken, *args) + x = self.cpu.get_float_value(deadframe, 0) + assert longlong.getrealfloat(x) == 13.5 + assert called == [finish_descr3] + del called[:] def test_short_result_of_getfield_direct(self): # Test that a getfield that returns a CHAR, SHORT or INT, signed diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -602,7 +602,7 @@ relative_target = tok.pos_recovery_stub - (tok.pos_jump_offset + 4) assert rx86.fits_in_32bits(relative_target) # - if not tok.is_guard_not_invalidated: + if not tok.guard_not_invalidated(): mc = codebuf.MachineCodeBlockWrapper() mc.writeimm32(relative_target) mc.copy_to_raw_memory(addr) @@ -1774,15 +1774,9 @@ def implement_guard_recovery(self, guard_opnum, faildescr, failargs, fail_locs, frame_depth): - exc = (guard_opnum == rop.GUARD_EXCEPTION or - guard_opnum == rop.GUARD_NO_EXCEPTION or - guard_opnum == rop.GUARD_NOT_FORCED) - is_guard_not_invalidated = guard_opnum == rop.GUARD_NOT_INVALIDATED - is_guard_not_forced = guard_opnum == rop.GUARD_NOT_FORCED gcmap = allocate_gcmap(self, frame_depth, JITFRAME_FIXED_SIZE) - return GuardToken(self.cpu, gcmap, faildescr, failargs, - fail_locs, exc, frame_depth, - is_guard_not_invalidated, is_guard_not_forced) + return GuardToken(self.cpu, gcmap, faildescr, failargs, fail_locs, + guard_opnum, frame_depth) def generate_propagate_error_64(self): assert WORD == 8 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit