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)}; } }
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 copyTV(Vout& v, Vreg data, Vreg type, Vloc srcLoc, const SSATmp* src) { // SIMD register are not supported here. assertx(!srcLoc.isFullSIMD()); if (src->type().needsReg()) { assertx(srcLoc.hasReg(1)); v << copy{srcLoc.reg(1), type}; } else { v << copy{v.cns(src->type().toDataType()), type}; } // Ignore the values for nulls. if (src->isA(TNull)) return; if (src->hasConstVal()) { // Skip potential zero-extend if we know the value. v << copy{v.cns(src->rawVal()), data}; } else { assertx(srcLoc.hasReg(0)); auto const extended = zeroExtendIfBool(v, src->type(), srcLoc.reg(0)); v << copy{extended, data}; } }