void interpOne(IRGS& env, folly::Optional<Type> outType, int popped, int pushed, InterpOneData& idata) { auto const unit = curUnit(env); spillStack(env); env.irb->exceptionStackBoundary(); auto const op = unit->getOpcode(bcOff(env)); auto& iInfo = getInstrInfo(op); if (iInfo.type == jit::InstrFlags::OutFDesc) { env.fpiStack.push(FPIInfo { sp(env), env.irb->spOffset(), nullptr }); } else if (isFCallStar(op) && !env.fpiStack.empty()) { env.fpiStack.pop(); } idata.bcOff = bcOff(env); idata.cellsPopped = popped; idata.cellsPushed = pushed; idata.opcode = op; gen( env, opcodeChangesPC(idata.opcode) ? InterpOneCF : InterpOne, outType, idata, sp(env), fp(env) ); assertx(env.irb->stackDeficit() == 0); }
int64_t getStackPopped(PC pc) { auto const op = peek_op(pc); switch (op) { case Op::FCall: return getImm(pc, 0).u_IVA + kNumActRecCells; case Op::FCallD: return getImm(pc, 0).u_IVA + kNumActRecCells; case Op::FCallAwait: return getImm(pc, 0).u_IVA + kNumActRecCells; case Op::FCallArray: return kNumActRecCells + 1; case Op::QueryM: case Op::VGetM: case Op::IncDecM: case Op::UnsetM: case Op::NewPackedArray: case Op::NewVecArray: case Op::NewKeysetArray: case Op::ConcatN: case Op::FCallBuiltin: case Op::CreateCl: return getImm(pc, 0).u_IVA; case Op::FPassM: // imm[0] is argument index return getImm(pc, 1).u_IVA; case Op::SetM: case Op::SetOpM: case Op::BindM: return getImm(pc, 0).u_IVA + 1; case Op::NewStructArray: return getImmVector(pc).size(); case Op::BaseSC: case Op::BaseSL: return getImm(pc, 1).u_IVA + 1; default: break; } uint64_t mask = getInstrInfo(op).in; int64_t count = 0; // All instructions with these properties are handled above assertx((mask & (StackN | BStackN)) == 0); return count + countOperands(mask); }
LLVMState::LLVMState(const std::string &Triple, const std::string &CpuName, const std::string &Features) { std::string Error; const llvm::Target *const TheTarget = llvm::TargetRegistry::lookupTarget(Triple, Error); assert(TheTarget && "unknown target for host"); const llvm::TargetOptions Options; TargetMachine.reset( static_cast<llvm::LLVMTargetMachine *>(TheTarget->createTargetMachine( Triple, CpuName, Features, Options, llvm::Reloc::Model::Static))); TheExegesisTarget = ExegesisTarget::lookup(TargetMachine->getTargetTriple()); if (!TheExegesisTarget) { llvm::errs() << "no exegesis target for " << Triple << ", using default\n"; TheExegesisTarget = &ExegesisTarget::getDefault(); } PfmCounters = &TheExegesisTarget->getPfmCounters(CpuName); RATC.reset(new RegisterAliasingTrackerCache( getRegInfo(), getFunctionReservedRegs(getTargetMachine()))); IC.reset(new InstructionsCache(getInstrInfo(), getRATC())); }
int isInstruction(const char * name) { return getInstrInfo(name, NULL); }
int64_t getStackPushed(PC pc) { auto const op = peek_op(pc); if (op == Op::BaseSC || op == Op::BaseSL) return getImm(pc, 1).u_IVA; return countOperands(getInstrInfo(op).out); }