int ExprFuncSimple::buildInterpreter(const ExprFuncNode *node, Interpreter *interpreter) const { std::vector<int> operands; for (int c = 0; c < node->numChildren(); c++) { int operand = node->child(c)->buildInterpreter(interpreter); #if 0 // debug std::cerr<<"we are "<<node->promote(c)<<" "<<c<<std::endl; #endif if (node->promote(c) != 0) { interpreter->addOp(getTemplatizedOp<Promote>(node->promote(c))); int promotedOperand = interpreter->allocFP(node->promote(c)); interpreter->addOperand(operand); interpreter->addOperand(promotedOperand); operand = promotedOperand; interpreter->endOp(); } operands.push_back(operand); } int outoperand = -1; int nargsData = interpreter->allocFP(1); interpreter->d[nargsData] = node->numChildren(); if (node->type().isFP()) outoperand = interpreter->allocFP(node->type().dim()); else if (node->type().isString()) outoperand = interpreter->allocPtr(); else assert(false); interpreter->addOp(EvalOp); int ptrLoc = interpreter->allocPtr(); int ptrDataLoc = interpreter->allocPtr(); interpreter->s[ptrLoc] = (char *)this; interpreter->addOperand(ptrLoc); interpreter->addOperand(ptrDataLoc); interpreter->addOperand(outoperand); interpreter->addOperand(nargsData); for (size_t c = 0; c < operands.size(); c++) { interpreter->addOperand(operands[c]); } interpreter->endOp(false); // do not eval because the function may not be evaluatable! // call into interpreter eval int pc = interpreter->nextPC() - 1; int *opCurr = (&interpreter->opData[0]) + interpreter->ops[pc].second; ArgHandle args(opCurr, &interpreter->d[0], &interpreter->s[0], interpreter->callStack); interpreter->s[ptrDataLoc] = reinterpret_cast<char *>(evalConstant(node, args)); return outoperand; }
ref<ConstantExpr> Executor::evalConstantExpr(const llvm::ConstantExpr *ce) { LLVM_TYPE_Q llvm::Type *type = ce->getType(); ref<ConstantExpr> op1(0), op2(0), op3(0); int numOperands = ce->getNumOperands(); if (numOperands > 0) op1 = evalConstant(ce->getOperand(0)); if (numOperands > 1) op2 = evalConstant(ce->getOperand(1)); if (numOperands > 2) op3 = evalConstant(ce->getOperand(2)); switch (ce->getOpcode()) { default : ce->dump(); std::cerr << "error: unknown ConstantExpr type\n" << "opcode: " << ce->getOpcode() << "\n"; abort(); case Instruction::Trunc: return op1->Extract(0, getWidthForLLVMType(type)); case Instruction::ZExt: return op1->ZExt(getWidthForLLVMType(type)); case Instruction::SExt: return op1->SExt(getWidthForLLVMType(type)); case Instruction::Add: return op1->Add(op2); case Instruction::Sub: return op1->Sub(op2); case Instruction::Mul: return op1->Mul(op2); case Instruction::SDiv: return op1->SDiv(op2); case Instruction::UDiv: return op1->UDiv(op2); case Instruction::SRem: return op1->SRem(op2); case Instruction::URem: return op1->URem(op2); case Instruction::And: return op1->And(op2); case Instruction::Or: return op1->Or(op2); case Instruction::Xor: return op1->Xor(op2); case Instruction::Shl: return op1->Shl(op2); case Instruction::LShr: return op1->LShr(op2); case Instruction::AShr: return op1->AShr(op2); case Instruction::BitCast: return op1; case Instruction::IntToPtr: return op1->ZExt(getWidthForLLVMType(type)); case Instruction::PtrToInt: return op1->ZExt(getWidthForLLVMType(type)); case Instruction::GetElementPtr: { ref<ConstantExpr> base = op1->ZExt(Context::get().getPointerWidth()); for (gep_type_iterator ii = gep_type_begin(ce), ie = gep_type_end(ce); ii != ie; ++ii) { ref<ConstantExpr> addend = ConstantExpr::alloc(0, Context::get().getPointerWidth()); if (LLVM_TYPE_Q StructType *st = dyn_cast<StructType>(*ii)) { const StructLayout *sl = kmodule->targetData->getStructLayout(st); const ConstantInt *ci = cast<ConstantInt>(ii.getOperand()); addend = ConstantExpr::alloc(sl->getElementOffset((unsigned) ci->getZExtValue()), Context::get().getPointerWidth()); } else { const SequentialType *set = cast<SequentialType>(*ii); ref<ConstantExpr> index = evalConstant(cast<Constant>(ii.getOperand())); unsigned elementSize = kmodule->targetData->getTypeStoreSize(set->getElementType()); index = index->ZExt(Context::get().getPointerWidth()); addend = index->Mul(ConstantExpr::alloc(elementSize, Context::get().getPointerWidth())); } base = base->Add(addend); } return base; } case Instruction::ICmp: { switch(ce->getPredicate()) { default: assert(0 && "unhandled ICmp predicate"); case ICmpInst::ICMP_EQ: return op1->Eq(op2); case ICmpInst::ICMP_NE: return op1->Ne(op2); case ICmpInst::ICMP_UGT: return op1->Ugt(op2); case ICmpInst::ICMP_UGE: return op1->Uge(op2); case ICmpInst::ICMP_ULT: return op1->Ult(op2); case ICmpInst::ICMP_ULE: return op1->Ule(op2); case ICmpInst::ICMP_SGT: return op1->Sgt(op2); case ICmpInst::ICMP_SGE: return op1->Sge(op2); case ICmpInst::ICMP_SLT: return op1->Slt(op2); case ICmpInst::ICMP_SLE: return op1->Sle(op2); } } case Instruction::Select: return op1->isTrue() ? op2 : op3; case Instruction::FAdd: case Instruction::FSub: case Instruction::FMul: case Instruction::FDiv: case Instruction::FRem: case Instruction::FPTrunc: case Instruction::FPExt: case Instruction::UIToFP: case Instruction::SIToFP: case Instruction::FPToUI: case Instruction::FPToSI: case Instruction::FCmp: assert(0 && "floating point ConstantExprs unsupported"); } }