void emitFuncGuard(const Func* func, CodeBlock& cb, CGMeta& fixups) { ppc64_asm::Assembler a { cb }; const auto tmp1 = ppc64_asm::reg::r3; const auto tmp2 = ppc64_asm::reg::r4; assertx(ppc64::abi(CodeKind::CrossTrace).gpUnreserved.contains(tmp1)); assertx(ppc64::abi(CodeKind::CrossTrace).gpUnreserved.contains(tmp2)); emitSmashableMovq(a.code(), fixups, uint64_t(func), tmp1); a. ld (tmp2, rvmfp()[AROFF(m_func)]); a. cmpd (tmp1, tmp2); a. branchFar(tc::ustubs().funcPrologueRedispatch, ppc64_asm::BranchConditions::NotEqual); DEBUG_ONLY auto guard = funcGuardFromPrologue(a.frontier(), func); assertx(funcGuardMatches(guard, func)); }
void emitFuncGuard(const Func* func, CodeBlock& cb, CGMeta& fixups) { vixl::MacroAssembler a { cb }; vixl::Label after_data; vixl::Label target_data; auto const begin = cb.frontier(); assertx(arm::abi(CodeKind::CrossTrace).gpUnreserved.contains(vixl::x0)); emitSmashableMovq(cb, fixups, uint64_t(func), vixl::x0); a. Ldr (rAsm, M(rvmfp()[AROFF(m_func)])); a. Cmp (vixl::x0, rAsm); a. B (&after_data, convertCC(CC_Z)); a. Ldr (rAsm_w, &target_data); a. Br (rAsm); a. bind (&target_data); a. dc32 (makeTarget32(tc::ustubs().funcPrologueRedispatch)); a. bind (&after_data); cb.sync(begin); }