def emit_op_cond_call(self, op, arglocs, regalloc, fcond): [call_loc] = arglocs gcmap = regalloc.get_gcmap([call_loc]) assert call_loc is r.r4 jmp_adr = self.mc.currpos() self.mc.BKPT() # patched later: the conditional jump # self.push_gcmap(self.mc, gcmap, store=True) # callee_only = False floats = False if self._regalloc is not None: for reg in self._regalloc.rm.reg_bindings.values(): if reg not in self._regalloc.rm.save_around_call_regs: break else: callee_only = True if self._regalloc.vfprm.reg_bindings: floats = True cond_call_adr = self.cond_call_slowpath[floats * 2 + callee_only] self.mc.BL(cond_call_adr) self.pop_gcmap(self.mc) # never any result value cond = c.get_opposite_of(self.guard_success_cc) self.guard_success_cc = c.cond_none pmc = OverwritingBuilder(self.mc, jmp_adr, WORD) pmc.B_offs(self.mc.currpos(), cond) # might be overridden again to skip over the following # guard_no_exception too self.previous_cond_call_jcond = jmp_adr, cond return fcond
def gen_emit_float_cmp_op(name, cond): inv = c.get_opposite_of(cond) def f(self, op, arglocs, regalloc, fcond): arg1, arg2, res = arglocs self.mc.VCMP(arg1.value, arg2.value) self.mc.VMRS(cond=fcond) self.mc.MOV_ri(res.value, 1, cond=cond) self.mc.MOV_ri(res.value, 0, cond=inv) return fcond f.__name__ = 'emit_op_%s' % name return f
def gen_emit_op_unary_cmp(name, true_cond): false_cond = c.get_opposite_of(true_cond) def f(self, op, arglocs, regalloc, fcond): assert fcond is not None reg, res = arglocs self.mc.CMP_ri(reg.value, 0) self.mc.MOV_ri(res.value, 1, true_cond) self.mc.MOV_ri(res.value, 0, false_cond) return fcond f.__name__ = 'emit_op_%s' % name return f
def flush_cc(asm, condition, result_loc): # After emitting an instruction that leaves a boolean result in # a condition code (cc), call this. In the common case, result_loc # will be set to 'fp' by the regalloc, which in this case means # "propagate it between this operation and the next guard by keeping # it in the cc". In the uncommon case, result_loc is another # register, and we emit a load from the cc into this register. assert asm.guard_success_cc == c.cond_none if result_loc is r.fp: asm.guard_success_cc = condition else: asm.mc.MOV_ri(result_loc.value, 1, condition) asm.mc.MOV_ri(result_loc.value, 0, c.get_opposite_of(condition))
def gen_emit_guard_unary_cmp(name, true_cond): false_cond = c.get_opposite_of(true_cond) def f(self, op, guard, arglocs, regalloc, fcond): assert fcond is not None assert guard is not None reg = arglocs[0] self.mc.CMP_ri(reg.value, 0) cond = true_cond guard_opnum = guard.getopnum() if guard_opnum == rop.GUARD_FALSE: cond = false_cond return self._emit_guard(guard, arglocs[1:], cond, save_exc=False) f.__name__ = 'emit_guard_%s' % name return f
def gen_emit_cmp_op(name, condition): inv = c.get_opposite_of(condition) def f(self, op, arglocs, regalloc, fcond): l0, l1, res = arglocs if l1.is_imm(): self.mc.CMP_ri(l0.value, imm=l1.getint(), cond=fcond) else: self.mc.CMP_rr(l0.value, l1.value, cond=fcond) self.mc.MOV_ri(res.value, 1, cond=condition) self.mc.MOV_ri(res.value, 0, cond=inv) return fcond f.__name__ = 'emit_op_%s' % name return f
def gen_emit_float_cmp_op_guard(name, true_cond): false_cond = c.get_opposite_of(true_cond) def f(self, op, guard, arglocs, regalloc, fcond): assert guard is not None arg1 = arglocs[0] arg2 = arglocs[1] self.mc.VCMP(arg1.value, arg2.value) self.mc.VMRS(cond=fcond) cond = true_cond guard_opnum = guard.getopnum() if guard_opnum == rop.GUARD_FALSE: cond = false_cond return self._emit_guard(guard, arglocs[2:], cond, save_exc=False) f.__name__ = 'emit_guard_%s' % name return f
def gen_emit_cmp_op_guard(name, true_cond): false_cond = c.get_opposite_of(true_cond) def f(self, op, guard, arglocs, regalloc, fcond): assert guard is not None l0 = arglocs[0] l1 = arglocs[1] assert l0.is_core_reg() if l1.is_imm(): self.mc.CMP_ri(l0.value, imm=l1.getint(), cond=fcond) else: self.mc.CMP_rr(l0.value, l1.value, cond=fcond) guard_opnum = guard.getopnum() cond = true_cond if guard_opnum == rop.GUARD_FALSE: cond = false_cond return self._emit_guard(guard, arglocs[2:], cond, save_exc=False) f.__name__ = 'emit_guard_%s' % name return f
def emit_op(self, op, arglocs): l0, l1, res = arglocs self.emit_float_comp_op(op, l0, l1) self.mc.CSET_r_flag(res.value, c.get_opposite_of(flag))
def emit_guard_op_guard_false(self, op, guard_op, fcond, arglocs): self._emit_guard(guard_op, c.get_opposite_of(fcond), arglocs)
def emit_guard_op_cond_call(self, prevop, op, fcond, arglocs): self._emit_op_cond_call(op, arglocs, c.get_opposite_of(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) return fcond