//===-- Execution.cpp - Implement code to simulate the program ------------===//
//
// This file contains the actual instruction interpreter.
//
//===----------------------------------------------------------------------===//
#include "Interpreter.h"
#include "ExecutionAnnotations.h"
#include "llvm/iOther.h"
#include "llvm/iTerminators.h"
#include "llvm/iMemory.h"
#include "llvm/Type.h"
#include "llvm/ConstPoolVals.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/GlobalVariable.h"
// Create a TargetData structure to handle memory addressing and size/alignment
// computations
//
static TargetData TD("lli Interpreter");
//===----------------------------------------------------------------------===//
// 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;
}
#define GET_CONST_VAL(TY, CLASS) \
case Type::TY##TyID: Result.TY##Val = cast<CLASS>(CPV)->getValue(); break
static GenericValue getOperandValue(Value *V, ExecutionContext &SF) {
if (ConstPoolVal *CPV = dyn_cast<ConstPoolVal>(V)) {
GenericValue Result;
switch (CPV->getType()->getPrimitiveID()) {
GET_CONST_VAL(Bool , ConstPoolBool);
GET_CONST_VAL(UByte , ConstPoolUInt);
GET_CONST_VAL(SByte , ConstPoolSInt);
GET_CONST_VAL(UShort , ConstPoolUInt);
GET_CONST_VAL(Short , ConstPoolSInt);
GET_CONST_VAL(UInt , ConstPoolUInt);
GET_CONST_VAL(Int , ConstPoolSInt);
GET_CONST_VAL(ULong , ConstPoolUInt);
GET_CONST_VAL(Long , ConstPoolSInt);
GET_CONST_VAL(Float , ConstPoolFP);
GET_CONST_VAL(Double , ConstPoolFP);
case Type::PointerTyID:
if (isa<ConstPoolPointerNull>(CPV)) {
Result.PointerVal = 0;
} else if (ConstPoolPointerRef *CPR =dyn_cast<ConstPoolPointerRef>(CPV)) {
assert(0 && "Not implemented!");
} else {
assert(0 && "Unknown constant pointer type!");
}
break;
default:
cout << "ERROR: Constant unimp for type: " << CPV->getType() << endl;
}
return Result;
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
GlobalAddress *Address =
(GlobalAddress*)GV->getOrCreateAnnotation(GlobalAddressAID);
GenericValue Result;
Result.PointerVal = (GenericValue*)Address->Ptr;
return Result;
} else {
unsigned TyP = V->getType()->getUniqueID(); // TypePlane for value
return SF.Values[TyP][getOperandSlot(V)];
}
}
static void printOperandInfo(Value *V, ExecutionContext &SF) {
if (isa<ConstPoolVal>(V)) {
cout << "Constant Pool Value\n";
} else if (isa<GlobalValue>(V)) {
cout << "Global Value\n";
} else {
unsigned TyP = V->getType()->getUniqueID(); // TypePlane for value
unsigned Slot = getOperandSlot(V);
cout << "Value=" << (void*)V << " TypeID=" << TyP << " Slot=" << Slot
<< " Addr=" << &SF.Values[TyP][Slot] << " SF=" << &SF << endl;
}
}
static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) {
unsigned TyP = V->getType()->getUniqueID(); // TypePlane for value
//cout << "Setting value: " << &SF.Values[TyP][getOperandSlot(V)] << endl;
SF.Values[TyP][getOperandSlot(V)] = Val;
}
//===----------------------------------------------------------------------===//
// Annotation Wrangling code
//===----------------------------------------------------------------------===//
void Interpreter::initializeExecutionEngine() {
AnnotationManager::registerAnnotationFactory(MethodInfoAID,
&MethodInfo::Create);
AnnotationManager::registerAnnotationFactory(GlobalAddressAID,
&GlobalAddress::Create);
}
// InitializeMemory - Recursive function to apply a ConstPool value into the