void cgStElem(IRLS& env, const IRInstruction* inst) { auto const rbase = srcLoc(env, inst, 0).reg(); auto const ridx = srcLoc(env, inst, 1).reg(); auto const idx = inst->src(1); auto& v = vmain(env); if (idx->hasConstVal() && deltaFits(idx->intVal(), sz::dword)) { storeTV(v, rbase[idx->intVal()], srcLoc(env, inst, 2), inst->src(2)); } else { storeTV(v, rbase[ridx], srcLoc(env, inst, 2), inst->src(2)); } }
void cgStLocRange(IRLS& env, const IRInstruction* inst) { auto const range = inst->extra<StLocRange>(); if (range->start >= range->end) return; auto const fp = srcLoc(env, inst, 0).reg(); auto const loc = srcLoc(env, inst, 1); auto const val = inst->src(1); auto& v = vmain(env); auto ireg = v.makeReg(); auto nreg = v.makeReg(); v << lea{fp[localOffset(range->start)], ireg}; v << lea{fp[localOffset(range->end)], nreg}; doWhile(v, CC_NE, {ireg}, [&] (const VregList& in, const VregList& out) { auto const i = in[0]; auto const res = out[0]; auto const sf = v.makeReg(); storeTV(v, i[0], loc, val); v << subqi{int32_t{sizeof(Cell)}, i, res, v.makeReg()}; v << cmpq{res, nreg, sf}; return sf; } ); }
void cgStOutValue(IRLS& env, const IRInstruction* inst) { auto const fp = srcLoc(env, inst, 0).reg(); auto const off = cellsToBytes( inst->extra<StOutValue>()->index + kNumActRecCells ); storeTV(vmain(env), fp[off], srcLoc(env, inst, 1), inst->src(1)); }
void cgStRef(IRLS& env, const IRInstruction* inst) { auto const ptr = srcLoc(env, inst, 0).reg(); auto const valLoc = srcLoc(env, inst, 1); always_assert(!srcLoc(env, inst, 1).isFullSIMD()); storeTV(vmain(env), ptr[RefData::tvOffset()], valLoc, inst->src(1)); }
void cgInitClosureStaticLoc(IRLS& env, const IRInstruction* inst) { auto const ref = srcLoc(env, inst, 0).reg(); auto& v = vmain(env); always_assert(!srcLoc(env, inst, 1).isFullSIMD()); storeTV(v, ref[RefData::tvOffset()], srcLoc(env, inst, 1), inst->src(1)); }
void cgStMem(IRLS& env, const IRInstruction* inst) { auto const ptr = inst->src(0); auto const ptrLoc = tmpLoc(env, ptr); auto const src = inst->src(1); auto const srcLoc = tmpLoc(env, src); storeTV(vmain(env), src->type(), srcLoc, memTVTypePtr(ptr, ptrLoc), memTVValPtr(ptr, ptrLoc)); }
void cgInitStaticLoc(IRLS& env, const IRInstruction* inst) { auto const extra = inst->extra<InitStaticLoc>(); auto const link = rds::bindStaticLocal(extra->func, extra->name); auto& v = vmain(env); // Initialize the RefData by storing the new value into it's TypedValue and // incrementing the RefData reference count (which will set it to 1). auto mem = rvmtl()[link.handle() + rds::StaticLocalData::ref_offset()]; storeTV(v, mem + RefData::tvOffset(), srcLoc(env, inst, 0), inst->src(0)); emitStoreRefCount(v, OneReference, mem); v << storebi{uint8_t(HeaderKind::Ref), mem + (int)HeaderKindOffset}; markRDSHandleInitialized(v, link.handle()); static_assert(sizeof(HeaderKind) == 1, ""); }
void cgStAsyncArResult(IRLS& env, const IRInstruction* inst) { auto const ar = srcLoc(env, inst, 0).reg(); storeTV(vmain(env), ar[ar_rel(AFWH::resultOff())], srcLoc(env, inst, 1), inst->src(1)); }
void cgStContArKey(IRLS& env, const IRInstruction* inst) { auto const contAR = srcLoc(env, inst, 0).reg(); auto const keyOff = GENDATAOFF(m_key) - Generator::arOff(); storeTV(vmain(env), contAR[keyOff], srcLoc(env, inst, 1), inst->src(1)); }
void cgStStk(IRLS& env, const IRInstruction* inst) { auto const sp = srcLoc(env, inst, 0).reg(); auto const off = cellsToBytes(inst->extra<StStk>()->offset.offset); storeTV(vmain(env), sp[off], srcLoc(env, inst, 1), inst->src(1)); }
void cgStLocPseudoMain(IRLS& env, const IRInstruction* inst) { auto const fp = srcLoc(env, inst, 0).reg(); auto const off = localOffset(inst->extra<StLocPseudoMain>()->locId); storeTV(vmain(env), fp[off], srcLoc(env, inst, 1), inst->src(1)); }