Example #1
0
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)};
  }
}
Example #2
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)};
  }
}
Example #3
0
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)};
  }
}