aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ExecutionEngine
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-10-30 20:27:31 +0000
committerChris Lattner <sabre@nondot.org>2001-10-30 20:27:31 +0000
commitbb76f02756dded5d43d1032ac1c8bfcfd4e76e5d (patch)
treea696f453f5a6896b88909777a5aaf92807c56b4a /lib/ExecutionEngine
parent6e39070b091645bbaeb36300d8ae5fe78abcc394 (diff)
downloadexternal_llvm-bb76f02756dded5d43d1032ac1c8bfcfd4e76e5d.zip
external_llvm-bb76f02756dded5d43d1032ac1c8bfcfd4e76e5d.tar.gz
external_llvm-bb76f02756dded5d43d1032ac1c8bfcfd4e76e5d.tar.bz2
* Add some assertions for checking internal error conditions
* Implement the 'rem' instruction * Fix getelementptr to work right * Copy the return result of an external function call into the receiving value * Convert stuff to new style casts git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1046 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r--lib/ExecutionEngine/Interpreter/Execution.cpp122
1 files changed, 90 insertions, 32 deletions
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp
index a3d8d3f..d7a60c7 100644
--- a/lib/ExecutionEngine/Interpreter/Execution.cpp
+++ b/lib/ExecutionEngine/Interpreter/Execution.cpp
@@ -15,6 +15,7 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/GlobalVariable.h"
+#include <math.h> // For fmod
// Create a TargetData structure to handle memory addressing and size/alignment
// computations
@@ -70,6 +71,9 @@ static GenericValue getOperandValue(Value *V, ExecutionContext &SF) {
return Result;
} 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)];
}
}
@@ -298,7 +302,32 @@ static GenericValue executeDivInst(GenericValue Src1, GenericValue Src2,
IMPLEMENT_BINARY_OPERATOR(/, Double);
IMPLEMENT_BINARY_OPERATOR(/, Pointer);
default:
- cout << "Unhandled type for Mul instruction: " << Ty << endl;
+ cout << "Unhandled type for Div instruction: " << Ty << endl;
+ }
+ return Dest;
+}
+
+static GenericValue executeRemInst(GenericValue Src1, GenericValue Src2,
+ const Type *Ty, ExecutionContext &SF) {
+ 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(%, Pointer);
+ case Type::FloatTyID:
+ Dest.FloatVal = fmod(Src1.FloatVal, Src2.FloatVal);
+ break;
+ case Type::DoubleTyID:
+ Dest.DoubleVal = fmod(Src1.DoubleVal, Src2.DoubleVal);
+ break;
+ default:
+ cout << "Unhandled type for Rem instruction: " << Ty << endl;
}
return Dest;
}
@@ -439,10 +468,11 @@ static void executeBinaryInst(BinaryOperator *I, ExecutionContext &SF) {
GenericValue R; // Result
switch (I->getOpcode()) {
- case Instruction::Add: R = executeAddInst(Src1, Src2, Ty, SF); break;
- case Instruction::Sub: R = executeSubInst(Src1, Src2, Ty, SF); break;
- case Instruction::Mul: R = executeMulInst(Src1, Src2, Ty, SF); break;
- case Instruction::Div: R = executeDivInst(Src1, Src2, Ty, SF); break;
+ case Instruction::Add: R = executeAddInst (Src1, Src2, Ty, SF); break;
+ case Instruction::Sub: R = executeSubInst (Src1, Src2, Ty, SF); break;
+ case Instruction::Mul: R = executeMulInst (Src1, Src2, Ty, SF); break;
+ case Instruction::Div: R = executeDivInst (Src1, Src2, Ty, SF); break;
+ case Instruction::Rem: R = executeRemInst (Src1, Src2, Ty, SF); break;
case Instruction::SetEQ: R = executeSetEQInst(Src1, Src2, Ty, SF); break;
case Instruction::SetNE: R = executeSetNEInst(Src1, Src2, Ty, SF); break;
case Instruction::SetLE: R = executeSetLEInst(Src1, Src2, Ty, SF); break;
@@ -525,7 +555,9 @@ void Interpreter::executeBrInst(BranchInst *I, ExecutionContext &SF) {
Dest = I->getSuccessor(0); // Uncond branches have a fixed dest...
if (!I->isUnconditional()) {
- if (getOperandValue(I->getCondition(), SF).BoolVal == 0) // If false cond...
+ Value *Cond = I->getCondition();
+ GenericValue CondVal = getOperandValue(Cond, SF);
+ if (CondVal.BoolVal == 0) // If false cond...
Dest = I->getSuccessor(1);
}
SF.CurBB = Dest; // Update CurBB to branch destination
@@ -588,7 +620,9 @@ static uint64_t getElementOffset(Instruction *I, unsigned ArgOff) {
// Indicies must be ubyte constants...
const ConstPoolUInt *CPU = cast<ConstPoolUInt>(I->getOperand(ArgOff++));
assert(CPU->getType() == Type::UByteTy);
- Total += SLO->MemberOffsets[CPU->getValue()];
+ unsigned Index = CPU->getValue();
+ Total += SLO->MemberOffsets[Index];
+ Ty = STy->getElementTypes()[Index];
}
return Total;
@@ -604,7 +638,8 @@ static void executeGEPInst(GetElementPtrInst *I, ExecutionContext &SF) {
static void executeLoadInst(LoadInst *I, ExecutionContext &SF) {
uint64_t SrcPtr = getOperandValue(I->getPtrOperand(), SF).ULongVal;
- SrcPtr += getElementOffset(I, 0); // Handle any structure indices
+ uint64_t Offset = getElementOffset(I, 0); // Handle any structure indices
+ SrcPtr += Offset;
GenericValue *Ptr = (GenericValue*)SrcPtr;
GenericValue Result;
@@ -619,7 +654,7 @@ static void executeLoadInst(LoadInst *I, ExecutionContext &SF) {
case Type::IntTyID: Result.IntVal = Ptr->IntVal; break;
case Type::ULongTyID:
case Type::LongTyID:
- case Type::PointerTyID: Result.ULongVal = Ptr->ULongVal; break;
+ case Type::PointerTyID: Result.ULongVal = Ptr->PointerVal; break;
case Type::FloatTyID: Result.FloatVal = Ptr->FloatVal; break;
case Type::DoubleTyID: Result.DoubleVal = Ptr->DoubleVal; break;
default:
@@ -769,17 +804,17 @@ static void executeCastInst(CastInst *I, ExecutionContext &SF) {
GenericValue Dest;
switch (Ty->getPrimitiveID()) {
- IMPLEMENT_CAST_CASE(UByte , unsigned char);
- IMPLEMENT_CAST_CASE(SByte , signed char);
- IMPLEMENT_CAST_CASE(UShort, unsigned short);
- IMPLEMENT_CAST_CASE(Short , signed char);
- IMPLEMENT_CAST_CASE(UInt , unsigned int );
- IMPLEMENT_CAST_CASE(Int , signed int );
- IMPLEMENT_CAST_CASE(ULong , uint64_t );
- IMPLEMENT_CAST_CASE(Long , int64_t );
+ IMPLEMENT_CAST_CASE(UByte , unsigned char);
+ IMPLEMENT_CAST_CASE(SByte , signed char);
+ IMPLEMENT_CAST_CASE(UShort , unsigned short);
+ IMPLEMENT_CAST_CASE(Short , signed char);
+ IMPLEMENT_CAST_CASE(UInt , unsigned int );
+ IMPLEMENT_CAST_CASE(Int , signed int );
+ IMPLEMENT_CAST_CASE(ULong , uint64_t);
+ IMPLEMENT_CAST_CASE(Long , int64_t);
IMPLEMENT_CAST_CASE(Pointer, uint64_t);
- IMPLEMENT_CAST_CASE(Float , float);
- IMPLEMENT_CAST_CASE(Double, double);
+ IMPLEMENT_CAST_CASE(Float , float);
+ IMPLEMENT_CAST_CASE(Double , double);
default:
cout << "Unhandled dest type for cast instruction: " << Ty << endl;
}
@@ -827,7 +862,30 @@ void Interpreter::callMethod(Method *M, const vector<GenericValue> &ArgVals) {
ECStack.back().Caller->getNumOperands()-1 == ArgVals.size()) &&
"Incorrect number of arguments passed into function call!");
if (M->isExternal()) {
- callExternalMethod(M, ArgVals);
+ GenericValue Result = callExternalMethod(M, ArgVals);
+ const Type *RetTy = M->getReturnType();
+
+ // Copy the result back into the result variable if we are not returning
+ // void.
+ if (RetTy != Type::VoidTy) {
+ if (!ECStack.empty() && ECStack.back().Caller) {
+ ExecutionContext &SF = ECStack.back();
+ CallInst *Caller = SF.Caller;
+ SetValue(SF.Caller, Result, SF);
+
+ SF.Caller = 0; // We returned from the call...
+ } else {
+ // print it.
+ cout << "Method " << M->getType() << " \"" << M->getName()
+ << "\" returned ";
+ print(RetTy, Result);
+ cout << endl;
+
+ if (RetTy->isIntegral())
+ ExitCode = Result.SByteVal; // Capture the exit code of the program
+ }
+ }
+
return;
}
@@ -874,27 +932,27 @@ bool Interpreter::executeInstruction() {
cout << "Run:" << I;
if (I->isBinaryOp()) {
- executeBinaryInst((BinaryOperator*)I, SF);
+ executeBinaryInst(cast<BinaryOperator>(I), SF);
} else {
switch (I->getOpcode()) {
// Terminators
- case Instruction::Ret: executeRetInst ((ReturnInst*)I, SF); break;
- case Instruction::Br: executeBrInst ((BranchInst*)I, SF); break;
+ case Instruction::Ret: executeRetInst (cast<ReturnInst>(I), SF); break;
+ case Instruction::Br: executeBrInst (cast<BranchInst>(I), SF); break;
// Memory Instructions
case Instruction::Alloca:
- case Instruction::Malloc: executeAllocInst ((AllocationInst*)I, SF); break;
- case Instruction::Free: executeFreeInst (cast<FreeInst> (I), SF); break;
- case Instruction::Load: executeLoadInst (cast<LoadInst> (I), SF); break;
- case Instruction::Store: executeStoreInst (cast<StoreInst>(I), SF); break;
+ case Instruction::Malloc: executeAllocInst((AllocationInst*)I, SF); break;
+ case Instruction::Free: executeFreeInst (cast<FreeInst> (I), SF); break;
+ case Instruction::Load: executeLoadInst (cast<LoadInst> (I), SF); break;
+ case Instruction::Store: executeStoreInst(cast<StoreInst>(I), SF); break;
case Instruction::GetElementPtr:
executeGEPInst(cast<GetElementPtrInst>(I), SF); break;
// Miscellaneous Instructions
- case Instruction::Call: executeCallInst (cast<CallInst> (I), SF); break;
- case Instruction::PHINode: executePHINode (cast<PHINode> (I), SF); break;
- case Instruction::Shl: executeShlInst (cast<ShiftInst>(I), SF); break;
- case Instruction::Shr: executeShrInst (cast<ShiftInst>(I), SF); break;
- case Instruction::Cast: executeCastInst (cast<CastInst> (I), SF); break;
+ case Instruction::Call: executeCallInst (cast<CallInst> (I), SF); break;
+ case Instruction::PHINode: executePHINode (cast<PHINode> (I), SF); break;
+ case Instruction::Shl: executeShlInst (cast<ShiftInst>(I), SF); break;
+ case Instruction::Shr: executeShrInst (cast<ShiftInst>(I), SF); break;
+ case Instruction::Cast: executeCastInst (cast<CastInst> (I), SF); break;
default:
cout << "Don't know how to execute this instruction!\n-->" << I;
}