//===-- Execution.cpp - Implement code to simulate the program ------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the actual instruction interpreter.
//
//===----------------------------------------------------------------------===//
#include "Interpreter.h"
#include "llvm/Instructions.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "Support/Statistic.h"
#include <cmath> // For fmod
using namespace llvm;
namespace {
Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed");
}
namespace llvm {
Interpreter *TheEE = 0;
}
//===----------------------------------------------------------------------===//
// Value Manipulation code
//===----------------------------------------------------------------------===//
// 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), gep_type_begin(CE),
gep_type_end(CE), 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 {
return SF.Values[V];
}
}
static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) {
SF.Values[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(+, SByte);
IMPLEMENT_BINARY_OPERATOR(+, UShort);
IMPLEMENT_BINARY_OPERATOR(+, Short);
IMPLEMENT_BINARY_OPERATOR(+, UInt);
IMPLEMENT_BINARY_OPERATOR(+, Int);
IMPLEMENT_BINARY_OPERATOR(+, ULong);
IMPLEMENT_BINARY_OPERATOR(+, Long);
IMPLEMENT_BINARY_OPERATOR(+, Float);
IMPLEMENT_BINARY_OPERATOR(+, Double);
default:
std::cout << "Unhandled type for Add instruction: " << *Ty << "\n";
abort();
}
return Dest;
}
static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getPrimitiveID()) {
IMPLEMENT_BINARY_OPERATOR(-, UByte);
IMPLEMENT_BINARY_OPERATOR(-, SByte);
IMPLEMENT_BINARY_OPERATOR(-, UShort);
IMPLEMENT_BINARY_OPERATOR(-, Short);
IMPLEMENT_BINARY_OPERATOR(-, UInt);
IMPLEMENT_BINARY_OPERATOR(-, Int);
IMPLEMENT_BINARY_OPERATOR(-, ULong);
IMPLEMENT_BINARY_OPERATOR(-, Long);
IMPLEMENT_BINARY_OPERATOR(-, Float);
IMPLEMENT_BINARY_OPERATOR(-, Double);
default:
std::cout << "Unhandled type for Sub instruction: " << *Ty << "\n";
abort();
}
return Dest;
}
static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getPrimitiveID()) {
IMPLEMENT_BINARY_OPERATOR(*, UByte);
IMPLEMENT_BINARY_OPERATOR(*, SByte);
IMPLEMENT_BINARY_OPERATOR(*, UShort);
IMPLEMENT_BINARY_OPERATOR