//===-- Execution.cpp - Implement code to simulate the program ------------===//
//
// This file contains the actual instruction interpreter.
//
//===----------------------------------------------------------------------===//
#include "Interpreter.h"
#include "ExecutionAnnotations.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Assembly/Writer.h"
#include "Support/CommandLine.h"
#include "Support/Statistic.h"
#include <cmath> // For fmod
Interpreter *TheEE = 0;
namespace {
Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed");
cl::opt<bool>
QuietMode("quiet", cl::desc("Do not emit any non-program output"),
cl::init(true));
cl::alias
QuietModeA("q", cl::desc("Alias for -quiet"), cl::aliasopt(QuietMode));
cl::opt<bool>
ArrayChecksEnabled("array-checks", cl::desc("Enable array bound checks"));
}
// Create a TargetData structure to handle memory addressing and size/alignment
// computations
//
CachedWriter CW; // Object to accelerate printing of LLVM
//===----------------------------------------------------------------------===//
// Value Manipulation code
//===----------------------------------------------------------------------===//
static unsigned getOperandSlot(Value *V) {
SlotNumber *SN = (SlotNumber*)V->getAnnotation(SlotNumberAID);
assert(SN && "Operand does not have a slot number annotation!");
return SN->SlotNum;
}
// Operations used by constant expr implementations...
static GenericValue executeCastOperation(Value *Src, const Type *DestTy,
ExecutionContext &SF);
static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2,
const Type *Ty);
GenericValue Interpreter::getOperandValue(Value *V, ExecutionContext &SF) {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
switch (CE->getOpcode()) {
case Instruction::Cast:
return executeCastOperation(CE->getOperand(0), CE->getType(), SF);
case Instruction::GetElementPtr:
return TheEE->executeGEPOperation(CE->getOperand(0), CE->op_begin()+1,
CE->op_end(), SF);
case Instruction::Add:
return executeAddInst(getOperandValue(CE->getOperand(0), SF),
getOperandValue(CE->getOperand(1), SF),
CE->getType());
default:
std::cerr << "Unhandled ConstantExpr: " << CE << "\n";
abort();
return GenericValue();
}
} else if (Constant *CPV = dyn_cast<Constant>(V)) {
return TheEE->getConstantValue(CPV);
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
return PTOGV(TheEE->getPointerToGlobal(GV));
} else {
unsigned TyP = V->getType()->getUniqueID(); // TypePlane for value
unsigned OpSlot = getOperandSlot(V);
assert(TyP < SF.Values.size() &&
OpSlot < SF.Values[TyP].size() && "Value out of range!");
return SF.Values[TyP][getOperandSlot(V)];
}
}
static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) {
unsigned TyP = V->getType()->getUniqueID(); // TypePlane for value
//std::cout << "Setting value: " << &SF.Values[TyP][getOperandSlot(V)]<< "\n";
SF.Values[TyP][getOperandSlot(V)] = Val;
}
//===----------------------------------------------------------------------===//
// Annotation Wrangling code
//===----------------------------------------------------------------------===//
void Interpreter::initializeExecutionEngine() {
TheEE = this;
}
//===----------------------------------------------------------------------===//
// Binary Instruction Implementations
//===----------------------------------------------------------------------===//
#define IMPLEMENT_BINARY_OPERATOR(OP, TY) \
case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.TY##Val; break
static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getPrimitiveID()) {
IMPLEMENT_BINARY_OPERATOR(+, UByte);
IMPLEMENT_BINARY_OPERATOR(