void loadTV(Vout& v, const SSATmp* dst, Vloc dstLoc, Vptr src, bool aux /* = false */) { auto const type = dst->type(); if (dstLoc.isFullSIMD()) { // The whole TV is loaded into a single SIMD reg. assertx(RuntimeOption::EvalHHIRAllocSIMDRegs); v << loadups{src, dstLoc.reg()}; return; } if (type.needsReg()) { assertx(dstLoc.hasReg(1)); if (aux) { v << load{src + TVOFF(m_type), dstLoc.reg(1)}; } else { v << loadb{src + TVOFF(m_type), dstLoc.reg(1)}; } } if (type <= TBool) { v << loadtqb{src + TVOFF(m_data), dstLoc.reg(0)}; } else { v << load{src + TVOFF(m_data), dstLoc.reg(0)}; } }
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 storeTV(Vout& v, Vptr dst, Vloc srcLoc, const SSATmp* src) { auto const type = src->type(); if (srcLoc.isFullSIMD()) { // The whole TV is stored in a single SIMD reg. assertx(RuntimeOption::EvalHHIRAllocSIMDRegs); v << storeups{srcLoc.reg(), dst}; return; } if (type.needsReg()) { assertx(srcLoc.hasReg(1)); v << storeb{srcLoc.reg(1), dst + TVOFF(m_type)}; } else { v << storeb{v.cns(type.toDataType()), dst + TVOFF(m_type)}; } // We ignore the values of statically nullish types. if (src->isA(TNull) || src->isA(TNullptr)) return; // Store the value. if (src->hasConstVal()) { // Skip potential zero-extend if we know the value. v << store{v.cns(src->rawVal()), dst + TVOFF(m_data)}; } else { assertx(srcLoc.hasReg(0)); auto const extended = zeroExtendIfBool(v, src->type(), srcLoc.reg(0)); v << store{extended, dst + TVOFF(m_data)}; } }