def _emit_guard(self, op, arglocs, is_guard_not_invalidated=False): if is_guard_not_invalidated: fcond = c.cond_none else: fcond = self.guard_success_cc self.guard_success_cc = c.cond_none assert fcond.value != c.cond_none.value fcond = c.negate(fcond) 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.reserve_guard_branch() # has to be patched later on self.pending_guard_tokens.append(token)
def emit_cond_call(self, op, arglocs, regalloc): fcond = self.guard_success_cc self.guard_success_cc = c.cond_none assert fcond.value != c.cond_none.value fcond = c.negate(fcond) jmp_adr = self.mc.get_relative_pos() self.mc.reserve_cond_jump() # patched later to a relative branch # save away r2, r3, r4, r5, r11 into the jitframe should_be_saved = [ reg for reg in self._regalloc.rm.reg_bindings.itervalues() if reg in self._COND_CALL_SAVE_REGS ] self._push_core_regs_to_jitframe(self.mc, should_be_saved) # load gc map into unusual location: r0 self.load_gcmap(self.mc, r.SCRATCH2, regalloc.get_gcmap()) # # load the 0-to-4 arguments into these registers, with the address of # the function to call into r11 remap_frame_layout(self, arglocs, [r.r11, r.r2, r.r3, r.r4, r.r5][:len(arglocs)], r.SCRATCH) # # figure out which variant of cond_call_slowpath to call, and call it callee_only = False floats = False for reg in regalloc.rm.reg_bindings.values(): if reg not in regalloc.rm.save_around_call_regs: break else: callee_only = True if regalloc.fprm.reg_bindings: floats = True cond_call_adr = self.cond_call_slowpath[floats * 2 + callee_only] self.mc.load_imm(r.r14, cond_call_adr) self.mc.BASR(r.r14, r.r14) # restoring the registers saved above, and doing pop_gcmap(), is left # to the cond_call_slowpath helper. We never have any result value. relative_target = self.mc.currpos() - jmp_adr pmc = OverwritingBuilder(self.mc, jmp_adr, 1) pmc.BRCL(fcond, l.imm(relative_target)) pmc.overwrite() # might be overridden again to skip over the following # guard_no_exception too self.previous_cond_call_jcond = jmp_adr, fcond
def emit_cond_call(self, op, arglocs, regalloc): fcond = self.guard_success_cc self.guard_success_cc = c.cond_none assert fcond.value != c.cond_none.value fcond = c.negate(fcond) jmp_adr = self.mc.get_relative_pos() self.mc.reserve_cond_jump() # patched later to a relative branch # save away r2, r3, r4, r5, r11 into the jitframe should_be_saved = [ reg for reg in self._regalloc.rm.reg_bindings.itervalues() if reg in self._COND_CALL_SAVE_REGS] self._push_core_regs_to_jitframe(self.mc, should_be_saved) # load gc map into unusual location: r0 self.load_gcmap(self.mc, r.SCRATCH2, regalloc.get_gcmap()) # # load the 0-to-4 arguments into these registers, with the address of # the function to call into r11 remap_frame_layout(self, arglocs, [r.r11, r.r2, r.r3, r.r4, r.r5][:len(arglocs)], r.SCRATCH) # # figure out which variant of cond_call_slowpath to call, and call it callee_only = False floats = False for reg in regalloc.rm.reg_bindings.values(): if reg not in regalloc.rm.save_around_call_regs: break else: callee_only = True if regalloc.fprm.reg_bindings: floats = True cond_call_adr = self.cond_call_slowpath[floats * 2 + callee_only] self.mc.load_imm(r.r14, cond_call_adr) self.mc.BASR(r.r14, r.r14) # restoring the registers saved above, and doing pop_gcmap(), is left # to the cond_call_slowpath helper. We never have any result value. relative_target = self.mc.currpos() - jmp_adr pmc = OverwritingBuilder(self.mc, jmp_adr, 1) pmc.BRCL(fcond, l.imm(relative_target)) pmc.overwrite() # might be overridden again to skip over the following # guard_no_exception too self.previous_cond_call_jcond = jmp_adr, fcond
def emit_guard_false(self, op, arglocs, regalloc): self.guard_success_cc = c.negate(self.guard_success_cc) self._emit_guard(op, arglocs)