Exemple #1
0
Vpoint emitCall(Vout& v, CppCall call, RegSet args) {
  PhysReg arg0(argReg(0));
  PhysReg rHostCall(rHostCallReg);
  switch (call.kind()) {
  case CppCall::Kind::Direct:
    v << ldimm{reinterpret_cast<intptr_t>(call.address()), rHostCall};
    break;
  case CppCall::Kind::Virtual:
    v << loadq{arg0[0], rHostCall};
    v << loadq{rHostCall[call.vtableOffset()], rHostCall};
    break;
  case CppCall::Kind::IndirectReg:
  case CppCall::Kind::IndirectVreg:
    // call indirect currently not implemented. It'll be something like
    // a.Br(x2a(call.getReg()))
    not_implemented();
    always_assert(0);
    break;
  case CppCall::Kind::ArrayVirt:
  case CppCall::Kind::Destructor:
    not_implemented();
    always_assert(0);
    break;
  }
  uint8_t argc = args.size();
  args.add(rHostCall);
  auto fixupAddr = v.makePoint();
  v << hostcall{args, argc, fixupAddr};
  return fixupAddr;
}
Exemple #2
0
void emitCallNativeImpl(Vout& v, Vout& vc, SrcKey srcKey,
                        const Func* func, int numArgs) {
  assert(isNativeImplCall(func, numArgs));

  // We need to store the return address into the AR, but we don't know it
  // yet. Use ldpoint, and point{} below, to get the address.
  PhysReg sp{rVmSp}, fp{rVmFp}, rds{rVmTl};
  auto ret_point = v.makePoint();
  auto ret_addr = v.makeReg();
  v << ldpoint{ret_point, ret_addr};
  v << store{ret_addr, sp[cellsToBytes(numArgs) + AROFF(m_savedRip)]};

  v << lea{sp[cellsToBytes(numArgs)], fp};
  emitCheckSurpriseFlagsEnter(v, vc, Fixup(0, numArgs));
  // rVmSp is already correctly adjusted, because there's no locals other than
  // the arguments passed.

  BuiltinFunction builtinFuncPtr = func->builtinFuncPtr();
  v << copy{fp, PhysReg{argReg(0)}};
  if (mcg->fixupMap().eagerRecord(func)) {
    v << store{v.cns(func->getEntry()), rds[RDS::kVmpcOff]};
    v << store{fp, rds[RDS::kVmfpOff]};
    v << store{sp, rds[RDS::kVmspOff]};
  }
  auto syncPoint = emitCall(v, CppCall::direct(builtinFuncPtr), argSet(1));

  Offset pcOffset = 0;
  Offset stackOff = func->numLocals();
  v << hcsync{Fixup{pcOffset, stackOff}, syncPoint};

  int nLocalCells = func->numSlotsInFrame();
  v << load{fp[AROFF(m_sfp)], fp};
  v << point{ret_point};

  int adjust = sizeof(ActRec) + cellsToBytes(nLocalCells - 1);
  if (adjust != 0) {
    v << addqi{adjust, sp, sp, v.makeReg()};
  }
}