void cgContEnter(IRLS& env, const IRInstruction* inst) { auto const sp = srcLoc(env, inst, 0).reg(); auto const fp = srcLoc(env, inst, 1).reg(); auto const genFP = srcLoc(env, inst, 2).reg(); auto const target = srcLoc(env, inst, 3).reg(); auto const extra = inst->extra<ContEnter>(); auto const spOff = extra->spOffset; auto const returnOff = extra->returnBCOffset; auto& v = vmain(env); auto const next = v.makeBlock(); v << store{fp, genFP[AROFF(m_sfp)]}; v << storeli{returnOff, genFP[AROFF(m_soff)]}; v << copy{genFP, fp}; auto const sync_sp = v.makeReg(); v << lea{sp[cellsToBytes(spOff.offset)], sync_sp}; v << syncvmsp{sync_sp}; v << contenter{fp, target, cross_trace_regs_resumed(), {next, label(env, inst->taken())}}; v = next; auto const dst = dstLoc(env, inst, 0); auto const type = inst->dst()->type(); if (!type.admitsSingleVal()) { v << defvmretdata{dst.reg(0)}; } if (type.needsReg()) { v << defvmrettype{dst.reg(1)}; } }
void cgContEnter(IRLS& env, const IRInstruction* inst) { auto const sp = srcLoc(env, inst, 0).reg(); auto const fp = srcLoc(env, inst, 1).reg(); auto const genFP = srcLoc(env, inst, 2).reg(); auto const target = srcLoc(env, inst, 3).reg(); auto const extra = inst->extra<ContEnter>(); auto const spOff = extra->spOffset; auto const returnOff = extra->returnBCOffset; auto& v = vmain(env); auto const next = v.makeBlock(); v << store{fp, genFP[AROFF(m_sfp)]}; v << storeli{returnOff, genFP[AROFF(m_soff)]}; v << copy{genFP, fp}; auto const sync_sp = v.makeReg(); v << lea{sp[cellsToBytes(spOff.offset)], sync_sp}; v << syncvmsp{sync_sp}; v << contenter{fp, target, cross_trace_regs_resumed(), {next, label(env, inst->taken())}}; env.catch_calls[inst->taken()] = CatchCall::PHP; v = next; }