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; }
PhysRegSaverParity::PhysRegSaverParity(int parity, X64Assembler& as, RegSet regs) : m_as(as) , m_regs(regs) , m_adjust((parity & 0x1) == (regs.size() & 0x1) ? 8 : 0) { m_regs.forEach([&] (PhysReg pr) { m_as. push (pr); }); if (m_adjust) { // Maintain stack evenness for SIMD compatibility. m_as. subq (m_adjust, reg::rsp); } }