//===-- 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 <math.h> // For fmod
#include <signal.h>
#include <setjmp.h>
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
sigjmp_buf SignalRecoverBuffer;
static bool InInstruction = false;
extern "C" {
static void SigHandler(int Signal) {
if (InInstruction)
siglongjmp(SignalRecoverBuffer, Signal);
}
}
static void initializeSignalHandlers() {
struct sigaction Action;
Action.sa_handler = SigHandler;
Action.sa_flags = SA_SIGINFO;
sigemptyset(&Action.sa_mask);
sigaction(SIGSEGV, &Action, 0);
sigaction(SIGBUS, &Action, 0);
sigaction(SIGINT, &Action, 0);
sigaction(SIGFPE, &Action, 0);
}
//===----------------------------------------------------------------------===//
// 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);
static GenericValue 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