예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
 def emit_guard_false(self, op, arglocs, regalloc):
     self.guard_success_cc = c.negate(self.guard_success_cc)
     self._emit_guard(op, arglocs)
예제 #6
0
 def emit_guard_false(self, op, arglocs, regalloc):
     self.guard_success_cc = c.negate(self.guard_success_cc)
     self._emit_guard(op, arglocs)