//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "interpreter"
#include "Interpreter.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/IntrinsicLowering.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cmath>
using namespace llvm;
+#define DEBUG_TYPE "interpreter"
+
STATISTIC(NumDynamicInsts, "Number of dynamic instructions executed");
static cl::opt<bool> PrintVolatile("interpreter-print-volatile", cl::Hidden,
IMPLEMENT_BINARY_OPERATOR(+, Double);
default:
dbgs() << "Unhandled type for FAdd instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
IMPLEMENT_BINARY_OPERATOR(-, Double);
default:
dbgs() << "Unhandled type for FSub instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
IMPLEMENT_BINARY_OPERATOR(*, Double);
default:
dbgs() << "Unhandled type for FMul instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
IMPLEMENT_BINARY_OPERATOR(/, Double);
default:
dbgs() << "Unhandled type for FDiv instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
break;
default:
dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
IMPLEMENT_POINTER_ICMP(==);
default:
dbgs() << "Unhandled type for ICMP_EQ predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(!=);
default:
dbgs() << "Unhandled type for ICMP_NE predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(<);
default:
dbgs() << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(<);
default:
dbgs() << "Unhandled type for ICMP_SLT predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(>);
default:
dbgs() << "Unhandled type for ICMP_UGT predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(>);
default:
dbgs() << "Unhandled type for ICMP_SGT predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(<=);
default:
dbgs() << "Unhandled type for ICMP_ULE predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(<=);
default:
dbgs() << "Unhandled type for ICMP_SLE predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(>=);
default:
dbgs() << "Unhandled type for ICMP_UGE predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(>=);
default:
dbgs() << "Unhandled type for ICMP_SGE predicate: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
case ICmpInst::ICMP_SGE: R = executeICMP_SGE(Src1, Src2, Ty); break;
default:
dbgs() << "Don't know how to handle this ICmp predicate!\n-->" << I;
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
SetValue(&I, R, SF);
#define IMPLEMENT_VECTOR_FCMP(OP) \
case Type::VectorTyID: \
- if(dyn_cast<VectorType>(Ty)->getElementType()->isFloatTy()) { \
+ if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) { \
IMPLEMENT_VECTOR_FCMP_T(OP, Float); \
} else { \
IMPLEMENT_VECTOR_FCMP_T(OP, Double); \
IMPLEMENT_VECTOR_FCMP(==);
default:
dbgs() << "Unhandled type for FCmp EQ instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
#define MASK_VECTOR_NANS(TY, X,Y, FLAG) \
if (TY->isVectorTy()) { \
- if (dyn_cast<VectorType>(TY)->getElementType()->isFloatTy()) { \
+ if (cast<VectorType>(TY)->getElementType()->isFloatTy()) { \
MASK_VECTOR_NANS_T(X, Y, Float, FLAG) \
} else { \
MASK_VECTOR_NANS_T(X, Y, Double, FLAG) \
IMPLEMENT_VECTOR_FCMP(!=);
default:
dbgs() << "Unhandled type for FCmp NE instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
// in vector case mask out NaN elements
if (Ty->isVectorTy())
IMPLEMENT_VECTOR_FCMP(<=);
default:
dbgs() << "Unhandled type for FCmp LE instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_VECTOR_FCMP(>=);
default:
dbgs() << "Unhandled type for FCmp GE instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_VECTOR_FCMP(<);
default:
dbgs() << "Unhandled type for FCmp LT instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
IMPLEMENT_VECTOR_FCMP(>);
default:
dbgs() << "Unhandled type for FCmp GT instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
return Dest;
}
return Dest; \
}
-#define IMPLEMENT_VECTOR_UNORDERED(TY, X,Y, _FUNC) \
- if (TY->isVectorTy()) { \
- GenericValue DestMask = Dest; \
- Dest = _FUNC(Src1, Src2, Ty); \
- for( size_t _i=0; _i<Src1.AggregateVal.size(); _i++) \
- if (DestMask.AggregateVal[_i].IntVal == true) \
- Dest.AggregateVal[_i].IntVal = APInt(1,true); \
- return Dest; \
+#define IMPLEMENT_VECTOR_UNORDERED(TY, X, Y, FUNC) \
+ if (TY->isVectorTy()) { \
+ GenericValue DestMask = Dest; \
+ Dest = FUNC(Src1, Src2, Ty); \
+ for (size_t _i = 0; _i < Src1.AggregateVal.size(); _i++) \
+ if (DestMask.AggregateVal[_i].IntVal == true) \
+ Dest.AggregateVal[_i].IntVal = APInt(1, true); \
+ return Dest; \
}
static GenericValue executeFCMP_UEQ(GenericValue Src1, GenericValue Src2,
if(Ty->isVectorTy()) {
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
Dest.AggregateVal.resize( Src1.AggregateVal.size() );
- if(dyn_cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
+ if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
Dest.AggregateVal[_i].IntVal = APInt(1,
( (Src1.AggregateVal[_i].FloatVal ==
if(Ty->isVectorTy()) {
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
Dest.AggregateVal.resize( Src1.AggregateVal.size() );
- if(dyn_cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
+ if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
Dest.AggregateVal[_i].IntVal = APInt(1,
( (Src1.AggregateVal[_i].FloatVal !=
}
static GenericValue executeFCMP_BOOL(GenericValue Src1, GenericValue Src2,
- const Type *Ty, const bool val) {
+ Type *Ty, const bool val) {
GenericValue Dest;
if(Ty->isVectorTy()) {
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
switch (I.getPredicate()) {
default:
dbgs() << "Don't know how to handle this FCmp predicate!\n-->" << I;
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
break;
case FCmpInst::FCMP_FALSE: R = executeFCMP_BOOL(Src1, Src2, Ty, false);
break;
case FCmpInst::FCMP_TRUE: return executeFCMP_BOOL(Src1, Src2, Ty, true);
default:
dbgs() << "Unhandled Cmp predicate\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
// Macros to choose appropriate TY: float or double and run operation
// execution
#define FLOAT_VECTOR_OP(OP) { \
- if (dyn_cast<VectorType>(Ty)->getElementType()->isFloatTy()) \
+ if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) \
FLOAT_VECTOR_FUNCTION(OP, FloatVal) \
else { \
- if (dyn_cast<VectorType>(Ty)->getElementType()->isDoubleTy()) \
+ if (cast<VectorType>(Ty)->getElementType()->isDoubleTy()) \
FLOAT_VECTOR_FUNCTION(OP, DoubleVal) \
else { \
dbgs() << "Unhandled type for OP instruction: " << *Ty << "\n"; \
switch(I.getOpcode()){
default:
dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
break;
case Instruction::Add: INTEGER_VECTOR_OPERATION(+) break;
case Instruction::Sub: INTEGER_VECTOR_OPERATION(-) break;
case Instruction::FMul: FLOAT_VECTOR_OP(*) break;
case Instruction::FDiv: FLOAT_VECTOR_OP(/) break;
case Instruction::FRem:
- if (dyn_cast<VectorType>(Ty)->getElementType()->isFloatTy())
+ if (cast<VectorType>(Ty)->getElementType()->isFloatTy())
for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
R.AggregateVal[i].FloatVal =
fmod(Src1.AggregateVal[i].FloatVal, Src2.AggregateVal[i].FloatVal);
else {
- if (dyn_cast<VectorType>(Ty)->getElementType()->isDoubleTy())
+ if (cast<VectorType>(Ty)->getElementType()->isDoubleTy())
for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
R.AggregateVal[i].DoubleVal =
fmod(Src1.AggregateVal[i].DoubleVal, Src2.AggregateVal[i].DoubleVal);
else {
dbgs() << "Unhandled type for Rem instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
}
break;
switch (I.getOpcode()) {
default:
dbgs() << "Don't know how to handle this binary operator!\n-->" << I;
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
break;
case Instruction::Add: R.IntVal = Src1.IntVal + Src2.IntVal; break;
case Instruction::Sub: R.IntVal = Src1.IntVal - Src2.IntVal; break;
}
static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2,
- GenericValue Src3, const Type *Ty) {
+ GenericValue Src3, Type *Ty) {
GenericValue Dest;
if(Ty->isVectorTy()) {
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
void Interpreter::visitSelectInst(SelectInst &I) {
ExecutionContext &SF = ECStack.back();
- const Type * Ty = I.getOperand(0)->getType();
+ Type * Ty = I.getOperand(0)->getType();
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
GenericValue CondVal = getOperandValue(Cond, SF);
// Check to see if any of the cases match...
- BasicBlock *Dest = 0;
+ BasicBlock *Dest = nullptr;
for (SwitchInst::CaseIt i = I.case_begin(), e = I.case_end(); i != e; ++i) {
GenericValue CaseVal = getOperandValue(i.getCaseValue(), SF);
if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) {
unsigned NumElements =
getOperandValue(I.getOperand(0), SF).IntVal.getZExtValue();
- unsigned TypeSize = (size_t)TD.getTypeAllocSize(Ty);
+ unsigned TypeSize = (size_t)getDataLayout().getTypeAllocSize(Ty);
// Avoid malloc-ing zero bytes, use max()...
unsigned MemToAlloc = std::max(1U, NumElements * TypeSize);
<< uintptr_t(Memory) << '\n');
GenericValue Result = PTOGV(Memory);
- assert(Result.PointerVal != 0 && "Null pointer returned by malloc!");
+ assert(Result.PointerVal && "Null pointer returned by malloc!");
SetValue(&I, Result, SF);
if (I.getOpcode() == Instruction::Alloca)
for (; I != E; ++I) {
if (StructType *STy = dyn_cast<StructType>(*I)) {
- const StructLayout *SLO = TD.getStructLayout(STy);
+ const StructLayout *SLO = getDataLayout().getStructLayout(STy);
const ConstantInt *CPU = cast<ConstantInt>(I.getOperand());
unsigned Index = unsigned(CPU->getZExtValue());
assert(BitWidth == 64 && "Invalid index type for getelementptr");
Idx = (int64_t)IdxGV.IntVal.getZExtValue();
}
- Total += TD.getTypeAllocSize(ST->getElementType())*Idx;
+ Total += getDataLayout().getTypeAllocSize(ST->getElementType()) * Idx;
}
}
callFunction((Function*)GVTOP(SRC), ArgVals);
}
-// auxilary function for shift operations
+// auxiliary function for shift operations
static unsigned getShiftAmount(uint64_t orgShiftAmount,
llvm::APInt valueToShift) {
unsigned valueWidth = valueToShift.getBitWidth();
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
GenericValue Dest;
- const Type *Ty = I.getType();
+ Type *Ty = I.getType();
if (Ty->isVectorTy()) {
uint32_t src1Size = uint32_t(Src1.AggregateVal.size());
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
GenericValue Dest;
- const Type *Ty = I.getType();
+ Type *Ty = I.getType();
if (Ty->isVectorTy()) {
uint32_t src1Size = uint32_t(Src1.AggregateVal.size());
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
GenericValue Dest;
- const Type *Ty = I.getType();
+ Type *Ty = I.getType();
if (Ty->isVectorTy()) {
size_t src1Size = Src1.AggregateVal.size();
GenericValue Interpreter::executeSExtInst(Value *SrcVal, Type *DstTy,
ExecutionContext &SF) {
- const Type *SrcTy = SrcVal->getType();
+ Type *SrcTy = SrcVal->getType();
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
if (SrcTy->isVectorTy()) {
- const Type *DstVecTy = DstTy->getScalarType();
+ Type *DstVecTy = DstTy->getScalarType();
unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
unsigned size = Src.AggregateVal.size();
// the sizes of src and dst vectors must be equal.
for (unsigned i = 0; i < size; i++)
Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.sext(DBitWidth);
} else {
- const IntegerType *DITy = cast<IntegerType>(DstTy);
+ auto *DITy = cast<IntegerType>(DstTy);
unsigned DBitWidth = DITy->getBitWidth();
Dest.IntVal = Src.IntVal.sext(DBitWidth);
}
GenericValue Interpreter::executeZExtInst(Value *SrcVal, Type *DstTy,
ExecutionContext &SF) {
- const Type *SrcTy = SrcVal->getType();
+ Type *SrcTy = SrcVal->getType();
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
if (SrcTy->isVectorTy()) {
- const Type *DstVecTy = DstTy->getScalarType();
+ Type *DstVecTy = DstTy->getScalarType();
unsigned DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
unsigned size = Src.AggregateVal.size();
for (unsigned i = 0; i < size; i++)
Dest.AggregateVal[i].IntVal = Src.AggregateVal[i].IntVal.zext(DBitWidth);
} else {
- const IntegerType *DITy = cast<IntegerType>(DstTy);
+ auto *DITy = cast<IntegerType>(DstTy);
unsigned DBitWidth = DITy->getBitWidth();
Dest.IntVal = Src.IntVal.zext(DBitWidth);
}
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
if (SrcTy->getTypeID() == Type::VectorTyID) {
- const Type *DstVecTy = DstTy->getScalarType();
- const Type *SrcVecTy = SrcTy->getScalarType();
+ Type *DstVecTy = DstTy->getScalarType();
+ Type *SrcVecTy = SrcTy->getScalarType();
uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
unsigned size = Src.AggregateVal.size();
// the sizes of src and dst vectors must be equal.
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
if (SrcTy->getTypeID() == Type::VectorTyID) {
- const Type *DstVecTy = DstTy->getScalarType();
- const Type *SrcVecTy = SrcTy->getScalarType();
+ Type *DstVecTy = DstTy->getScalarType();
+ Type *SrcVecTy = SrcTy->getScalarType();
uint32_t DBitWidth = cast<IntegerType>(DstVecTy)->getBitWidth();
unsigned size = Src.AggregateVal.size();
// the sizes of src and dst vectors must be equal
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
if (SrcVal->getType()->getTypeID() == Type::VectorTyID) {
- const Type *DstVecTy = DstTy->getScalarType();
+ Type *DstVecTy = DstTy->getScalarType();
unsigned size = Src.AggregateVal.size();
// the sizes of src and dst vectors must be equal
Dest.AggregateVal.resize(size);
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
if (SrcVal->getType()->getTypeID() == Type::VectorTyID) {
- const Type *DstVecTy = DstTy->getScalarType();
+ Type *DstVecTy = DstTy->getScalarType();
unsigned size = Src.AggregateVal.size();
// the sizes of src and dst vectors must be equal
Dest.AggregateVal.resize(size);
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
assert(DstTy->isPointerTy() && "Invalid PtrToInt instruction");
- uint32_t PtrSize = TD.getPointerSizeInBits();
+ uint32_t PtrSize = getDataLayout().getPointerSizeInBits();
if (PtrSize != Src.IntVal.getBitWidth())
Src.IntVal = Src.IntVal.zextOrTrunc(PtrSize);
(DstTy->getTypeID() == Type::VectorTyID)) {
// vector src bitcast to vector dst or vector src bitcast to scalar dst or
// scalar src bitcast to vector dst
- bool isLittleEndian = TD.isLittleEndian();
+ bool isLittleEndian = getDataLayout().isLittleEndian();
GenericValue TempDst, TempSrc, SrcVec;
- const Type *SrcElemTy;
- const Type *DstElemTy;
+ Type *SrcElemTy;
+ Type *DstElemTy;
unsigned SrcBitSize;
unsigned DstBitSize;
unsigned SrcNum;
IMPLEMENT_VAARG(Double);
default:
dbgs() << "Unhandled dest type for vaarg instruction: " << *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
}
// Set the Value of this Instruction.
default:
dbgs() << "Unhandled destination type for extractelement instruction: "
<< *Ty << "\n";
- llvm_unreachable(0);
+ llvm_unreachable(nullptr);
break;
case Type::IntegerTyID:
Dest.IntVal = Src1.AggregateVal[indx].IntVal;
SetValue(&I, Dest, SF);
}
+void Interpreter::visitExtractValueInst(ExtractValueInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ Value *Agg = I.getAggregateOperand();
+ GenericValue Dest;
+ GenericValue Src = getOperandValue(Agg, SF);
+
+ ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
+ unsigned Num = I.getNumIndices();
+ GenericValue *pSrc = &Src;
+
+ for (unsigned i = 0 ; i < Num; ++i) {
+ pSrc = &pSrc->AggregateVal[*IdxBegin];
+ ++IdxBegin;
+ }
+
+ Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
+ switch (IndexedType->getTypeID()) {
+ default:
+ llvm_unreachable("Unhandled dest type for extractelement instruction");
+ break;
+ case Type::IntegerTyID:
+ Dest.IntVal = pSrc->IntVal;
+ break;
+ case Type::FloatTyID:
+ Dest.FloatVal = pSrc->FloatVal;
+ break;
+ case Type::DoubleTyID:
+ Dest.DoubleVal = pSrc->DoubleVal;
+ break;
+ case Type::ArrayTyID:
+ case Type::StructTyID:
+ case Type::VectorTyID:
+ Dest.AggregateVal = pSrc->AggregateVal;
+ break;
+ case Type::PointerTyID:
+ Dest.PointerVal = pSrc->PointerVal;
+ break;
+ }
+
+ SetValue(&I, Dest, SF);
+}
+
+void Interpreter::visitInsertValueInst(InsertValueInst &I) {
+
+ ExecutionContext &SF = ECStack.back();
+ Value *Agg = I.getAggregateOperand();
+
+ GenericValue Src1 = getOperandValue(Agg, SF);
+ GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
+ GenericValue Dest = Src1; // Dest is a slightly changed Src1
+
+ ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
+ unsigned Num = I.getNumIndices();
+
+ GenericValue *pDest = &Dest;
+ for (unsigned i = 0 ; i < Num; ++i) {
+ pDest = &pDest->AggregateVal[*IdxBegin];
+ ++IdxBegin;
+ }
+ // pDest points to the target value in the Dest now
+
+ Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
+
+ switch (IndexedType->getTypeID()) {
+ default:
+ llvm_unreachable("Unhandled dest type for insertelement instruction");
+ break;
+ case Type::IntegerTyID:
+ pDest->IntVal = Src2.IntVal;
+ break;
+ case Type::FloatTyID:
+ pDest->FloatVal = Src2.FloatVal;
+ break;
+ case Type::DoubleTyID:
+ pDest->DoubleVal = Src2.DoubleVal;
+ break;
+ case Type::ArrayTyID:
+ case Type::StructTyID:
+ case Type::VectorTyID:
+ pDest->AggregateVal = Src2.AggregateVal;
+ break;
+ case Type::PointerTyID:
+ pDest->PointerVal = Src2.PointerVal;
+ break;
+ }
+
+ SetValue(&I, Dest, SF);
+}
+
GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
ExecutionContext &SF) {
switch (CE->getOpcode()) {
//===----------------------------------------------------------------------===//
// callFunction - Execute the specified function...
//
-void Interpreter::callFunction(Function *F,
- const std::vector<GenericValue> &ArgVals) {
- assert((ECStack.empty() || ECStack.back().Caller.getInstruction() == 0 ||
+void Interpreter::callFunction(Function *F, ArrayRef<GenericValue> ArgVals) {
+ assert((ECStack.empty() || !ECStack.back().Caller.getInstruction() ||
ECStack.back().Caller.arg_size() == ArgVals.size()) &&
"Incorrect number of arguments passed into function call!");
// Make a new stack frame... and fill it in.
- ECStack.push_back(ExecutionContext());
+ ECStack.emplace_back();
ExecutionContext &StackFrame = ECStack.back();
StackFrame.CurFunction = F;
}
// Get pointers to first LLVM BB & Instruction in function.
- StackFrame.CurBB = F->begin();
+ StackFrame.CurBB = &F->front();
StackFrame.CurInst = StackFrame.CurBB->begin();
// Run through the function arguments and initialize their values...
unsigned i = 0;
for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
AI != E; ++AI, ++i)
- SetValue(AI, ArgVals[i], StackFrame);
+ SetValue(&*AI, ArgVals[i], StackFrame);
// Handle varargs arguments...
StackFrame.VarArgs.assign(ArgVals.begin()+i, ArgVals.end());
DEBUG(dbgs() << "About to interpret: " << I);
visit(I); // Dispatch to one of the visit* methods...
-#if 0
- // This is not safe, as visiting the instruction could lower it and free I.
-DEBUG(
- if (!isa<CallInst>(I) && !isa<InvokeInst>(I) &&
- I.getType() != Type::VoidTy) {
- dbgs() << " --> ";
- const GenericValue &Val = SF.Values[&I];
- switch (I.getType()->getTypeID()) {
- default: llvm_unreachable("Invalid GenericValue Type");
- case Type::VoidTyID: dbgs() << "void"; break;
- case Type::FloatTyID: dbgs() << "float " << Val.FloatVal; break;
- case Type::DoubleTyID: dbgs() << "double " << Val.DoubleVal; break;
- case Type::PointerTyID: dbgs() << "void* " << intptr_t(Val.PointerVal);
- break;
- case Type::IntegerTyID:
- dbgs() << "i" << Val.IntVal.getBitWidth() << " "
- << Val.IntVal.toStringUnsigned(10)
- << " (0x" << Val.IntVal.toStringUnsigned(16) << ")\n";
- break;
- }
- });
-#endif
}
}