Changes For Bug 352
[oota-llvm.git] / lib / ExecutionEngine / Interpreter / Execution.cpp
index b04f974911d6b0b5a6ef98125fa4cf2cee733145..5e1ae0629f8ee532379fb627ec6cf080b2740488 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "interpreter"
 #include "Interpreter.h"
-#include "llvm/Instructions.h"
-#include "llvm/DerivedTypes.h"
 #include "llvm/Constants.h"
-#include "Support/Statistic.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Debug.h"
 #include <cmath>  // For fmod
-
-Interpreter *TheEE = 0;
+using namespace llvm;
 
 namespace {
   Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed");
+
+  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);
+static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeRemInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeDivInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeAndInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeOrInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeXorInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeSetEQInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeSetNEInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeSetLTInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeSetGTInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeSetLEInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeSetGEInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeShlInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeShrInst(GenericValue Src1, GenericValue Src2, 
+                                  const Type *Ty);
+static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2, 
+                                      GenericValue Src3);
+
+GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
+                                                ExecutionContext &SF) {
+  switch (CE->getOpcode()) {
+  case Instruction::Cast:
+    return executeCastOperation(CE->getOperand(0), CE->getType(), SF);
+  case Instruction::GetElementPtr:
+    return 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->getOperand(0)->getType());
+  case Instruction::Sub:
+    return executeSubInst(getOperandValue(CE->getOperand(0), SF),
+                          getOperandValue(CE->getOperand(1), SF),
+                          CE->getOperand(0)->getType());
+  case Instruction::Mul:
+    return executeMulInst(getOperandValue(CE->getOperand(0), SF),
+                          getOperandValue(CE->getOperand(1), SF),
+                          CE->getOperand(0)->getType());
+  case Instruction::Div:
+    return executeDivInst(getOperandValue(CE->getOperand(0), SF),
+                          getOperandValue(CE->getOperand(1), SF),
+                          CE->getOperand(0)->getType());
+  case Instruction::Rem:
+    return executeRemInst(getOperandValue(CE->getOperand(0), SF),
+                          getOperandValue(CE->getOperand(1), SF),
+                          CE->getOperand(0)->getType());
+  case Instruction::And:
+    return executeAndInst(getOperandValue(CE->getOperand(0), SF),
+                          getOperandValue(CE->getOperand(1), SF),
+                          CE->getOperand(0)->getType());
+  case Instruction::Or:
+    return executeOrInst(getOperandValue(CE->getOperand(0), SF),
+                         getOperandValue(CE->getOperand(1), SF),
+                         CE->getOperand(0)->getType());
+  case Instruction::Xor:
+    return executeXorInst(getOperandValue(CE->getOperand(0), SF),
+                          getOperandValue(CE->getOperand(1), SF),
+                          CE->getOperand(0)->getType());
+  case Instruction::SetEQ:
+    return executeSetEQInst(getOperandValue(CE->getOperand(0), SF),
+                            getOperandValue(CE->getOperand(1), SF),
+                            CE->getOperand(0)->getType());
+  case Instruction::SetNE:
+    return executeSetNEInst(getOperandValue(CE->getOperand(0), SF),
+                            getOperandValue(CE->getOperand(1), SF),
+                            CE->getOperand(0)->getType());
+  case Instruction::SetLE:
+    return executeSetLEInst(getOperandValue(CE->getOperand(0), SF),
+                            getOperandValue(CE->getOperand(1), SF),
+                            CE->getOperand(0)->getType());
+  case Instruction::SetGE:
+    return executeSetGEInst(getOperandValue(CE->getOperand(0), SF),
+                            getOperandValue(CE->getOperand(1), SF),
+                            CE->getOperand(0)->getType());
+  case Instruction::SetLT:
+    return executeSetLTInst(getOperandValue(CE->getOperand(0), SF),
+                            getOperandValue(CE->getOperand(1), SF),
+                            CE->getOperand(0)->getType());
+  case Instruction::SetGT:
+    return executeSetGTInst(getOperandValue(CE->getOperand(0), SF),
+                            getOperandValue(CE->getOperand(1), SF),
+                            CE->getOperand(0)->getType());
+  case Instruction::Shl:
+    return executeShlInst(getOperandValue(CE->getOperand(0), SF),
+                          getOperandValue(CE->getOperand(1), SF),
+                          CE->getOperand(0)->getType());
+  case Instruction::Shr:
+    return executeShrInst(getOperandValue(CE->getOperand(0), SF),
+                          getOperandValue(CE->getOperand(1), SF),
+                          CE->getOperand(0)->getType());
+  case Instruction::Select:
+    return executeSelectInst(getOperandValue(CE->getOperand(0), SF),
+                             getOperandValue(CE->getOperand(1), SF),
+                             getOperandValue(CE->getOperand(2), SF));
+  default:
+    std::cerr << "Unhandled ConstantExpr: " << *CE << "\n";
+    abort();
+    return GenericValue();
+  }
+}
 
 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();
-    }
+    return getConstantExprValue(CE, SF);
   } else if (Constant *CPV = dyn_cast<Constant>(V)) {
-    return TheEE->getConstantValue(CPV);
+    return getConstantValue(CPV);
   } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
-    return PTOGV(TheEE->getPointerToGlobal(GV));
+    return PTOGV(getPointerToGlobal(GV));
   } else {
     return SF.Values[V];
   }
@@ -64,10 +168,6 @@ static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) {
   SF.Values[V] = Val;
 }
 
-//===----------------------------------------------------------------------===//
-//                    Annotation Wrangling code
-//===----------------------------------------------------------------------===//
-
 void Interpreter::initializeExecutionEngine() {
   TheEE = this;
 }
@@ -82,7 +182,7 @@ void Interpreter::initializeExecutionEngine() {
 static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2, 
                                   const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_BINARY_OPERATOR(+, UByte);
     IMPLEMENT_BINARY_OPERATOR(+, SByte);
     IMPLEMENT_BINARY_OPERATOR(+, UShort);
@@ -103,7 +203,7 @@ static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2, 
                                   const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_BINARY_OPERATOR(-, UByte);
     IMPLEMENT_BINARY_OPERATOR(-, SByte);
     IMPLEMENT_BINARY_OPERATOR(-, UShort);
@@ -124,7 +224,7 @@ static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2, 
                                   const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_BINARY_OPERATOR(*, UByte);
     IMPLEMENT_BINARY_OPERATOR(*, SByte);
     IMPLEMENT_BINARY_OPERATOR(*, UShort);
@@ -136,7 +236,7 @@ static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2,
     IMPLEMENT_BINARY_OPERATOR(*, Float);
     IMPLEMENT_BINARY_OPERATOR(*, Double);
   default:
-    std::cout << "Unhandled type for Mul instruction: " << Ty << "\n";
+    std::cout << "Unhandled type for Mul instruction: " << *Ty << "\n";
     abort();
   }
   return Dest;
@@ -145,7 +245,7 @@ static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeDivInst(GenericValue Src1, GenericValue Src2, 
                                   const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_BINARY_OPERATOR(/, UByte);
     IMPLEMENT_BINARY_OPERATOR(/, SByte);
     IMPLEMENT_BINARY_OPERATOR(/, UShort);
@@ -166,7 +266,7 @@ static GenericValue executeDivInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeRemInst(GenericValue Src1, GenericValue Src2, 
                                   const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_BINARY_OPERATOR(%, UByte);
     IMPLEMENT_BINARY_OPERATOR(%, SByte);
     IMPLEMENT_BINARY_OPERATOR(%, UShort);
@@ -191,7 +291,7 @@ static GenericValue executeRemInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeAndInst(GenericValue Src1, GenericValue Src2, 
                                   const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_BINARY_OPERATOR(&, Bool);
     IMPLEMENT_BINARY_OPERATOR(&, UByte);
     IMPLEMENT_BINARY_OPERATOR(&, SByte);
@@ -211,7 +311,7 @@ static GenericValue executeAndInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeOrInst(GenericValue Src1, GenericValue Src2, 
                                   const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_BINARY_OPERATOR(|, Bool);
     IMPLEMENT_BINARY_OPERATOR(|, UByte);
     IMPLEMENT_BINARY_OPERATOR(|, SByte);
@@ -231,7 +331,7 @@ static GenericValue executeOrInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeXorInst(GenericValue Src1, GenericValue Src2, 
                                    const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_BINARY_OPERATOR(^, Bool);
     IMPLEMENT_BINARY_OPERATOR(^, UByte);
     IMPLEMENT_BINARY_OPERATOR(^, SByte);
@@ -263,7 +363,7 @@ static GenericValue executeXorInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeSetEQInst(GenericValue Src1, GenericValue Src2, 
                                     const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_SETCC(==, UByte);
     IMPLEMENT_SETCC(==, SByte);
     IMPLEMENT_SETCC(==, UShort);
@@ -285,7 +385,7 @@ static GenericValue executeSetEQInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeSetNEInst(GenericValue Src1, GenericValue Src2, 
                                     const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_SETCC(!=, UByte);
     IMPLEMENT_SETCC(!=, SByte);
     IMPLEMENT_SETCC(!=, UShort);
@@ -308,7 +408,7 @@ static GenericValue executeSetNEInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeSetLEInst(GenericValue Src1, GenericValue Src2, 
                                     const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_SETCC(<=, UByte);
     IMPLEMENT_SETCC(<=, SByte);
     IMPLEMENT_SETCC(<=, UShort);
@@ -321,7 +421,7 @@ static GenericValue executeSetLEInst(GenericValue Src1, GenericValue Src2,
     IMPLEMENT_SETCC(<=, Double);
     IMPLEMENT_POINTERSETCC(<=);
   default:
-    std::cout << "Unhandled type for SetLE instruction: " << Ty << "\n";
+    std::cout << "Unhandled type for SetLE instruction: " << *Ty << "\n";
     abort();
   }
   return Dest;
@@ -330,7 +430,7 @@ static GenericValue executeSetLEInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeSetGEInst(GenericValue Src1, GenericValue Src2, 
                                     const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_SETCC(>=, UByte);
     IMPLEMENT_SETCC(>=, SByte);
     IMPLEMENT_SETCC(>=, UShort);
@@ -352,7 +452,7 @@ static GenericValue executeSetGEInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeSetLTInst(GenericValue Src1, GenericValue Src2, 
                                     const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_SETCC(<, UByte);
     IMPLEMENT_SETCC(<, SByte);
     IMPLEMENT_SETCC(<, UShort);
@@ -374,7 +474,7 @@ static GenericValue executeSetLTInst(GenericValue Src1, GenericValue Src2,
 static GenericValue executeSetGTInst(GenericValue Src1, GenericValue Src2, 
                                     const Type *Ty) {
   GenericValue Dest;
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_SETCC(>, UByte);
     IMPLEMENT_SETCC(>, SByte);
     IMPLEMENT_SETCC(>, UShort);
@@ -423,13 +523,32 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) {
   SetValue(&I, R, SF);
 }
 
+static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2, 
+                                      GenericValue Src3) {
+  return Src1.BoolVal ? Src2 : Src3;
+}
+
+void Interpreter::visitSelectInst(SelectInst &I) {
+  ExecutionContext &SF = ECStack.back();
+  GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
+  GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
+  GenericValue Src3 = getOperandValue(I.getOperand(2), SF);
+  GenericValue R = executeSelectInst(Src1, Src2, Src3);
+  SetValue(&I, R, SF);
+}
+
+
 //===----------------------------------------------------------------------===//
 //                     Terminator Instruction Implementations
 //===----------------------------------------------------------------------===//
 
 void Interpreter::exitCalled(GenericValue GV) {
-  ExitCode = GV.SByteVal;
-  ECStack.clear();
+  // runAtExitHandlers() assumes there are no stack frames, but
+  // if exit() was called, then it had a stack frame. Blow away
+  // the stack before interpreting atexit handlers.
+  ECStack.clear ();
+  runAtExitHandlers ();
+  exit (GV.IntVal);
 }
 
 /// Pop the last stack frame off of ECStack and then copy the result
@@ -494,8 +613,7 @@ void Interpreter::visitUnwindInst(UnwindInst &I) {
   InvokingSF.Caller = CallSite ();
 
   // Go to exceptional destination BB of invoke instruction
-  SwitchToNewBasicBlock (cast<InvokeInst> (Inst)->getExceptionalDest (),
-                         InvokingSF);
+  SwitchToNewBasicBlock(cast<InvokeInst>(Inst)->getUnwindDest(), InvokingSF);
 }
 
 void Interpreter::visitBranchInst(BranchInst &I) {
@@ -599,33 +717,40 @@ void Interpreter::visitFreeInst(FreeInst &I) {
 
 // getElementOffset - The workhorse for getelementptr.
 //
-GenericValue Interpreter::executeGEPOperation(Value *Ptr, User::op_iterator I,
-                                             User::op_iterator E,
+GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I,
+                                             gep_type_iterator E,
                                              ExecutionContext &SF) {
   assert(isa<PointerType>(Ptr->getType()) &&
          "Cannot getElementOffset of a nonpointer type!");
 
   PointerTy Total = 0;
-  const Type *Ty = Ptr->getType();
 
   for (; I != E; ++I) {
-    if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+    if (const StructType *STy = dyn_cast<StructType>(*I)) {
       const StructLayout *SLO = TD.getStructLayout(STy);
       
-      // Indices must be ubyte constants...
-      const ConstantUInt *CPU = cast<ConstantUInt>(*I);
-      assert(CPU->getType() == Type::UByteTy);
+      const ConstantUInt *CPU = cast<ConstantUInt>(I.getOperand());
       unsigned Index = CPU->getValue();
       
       Total += SLO->MemberOffsets[Index];
-      Ty = STy->getElementTypes()[Index];
-    } else if (const SequentialType *ST = cast<SequentialType>(Ty)) {
+    } else {
+      const SequentialType *ST = cast<SequentialType>(*I);
       // Get the index number for the array... which must be long type...
-      assert((*I)->getType() == Type::LongTy);
-      unsigned Idx = getOperandValue(*I, SF).LongVal;
-      Ty = ST->getElementType();
-      unsigned Size = TD.getTypeSize(Ty);
-      Total += Size*Idx;
+      GenericValue IdxGV = getOperandValue(I.getOperand(), SF);
+
+      uint64_t Idx;
+      switch (I.getOperand()->getType()->getTypeID()) {
+      default: assert(0 && "Illegal getelementptr index for sequential type!");
+      case Type::SByteTyID:  Idx = IdxGV.SByteVal; break;
+      case Type::ShortTyID:  Idx = IdxGV.ShortVal; break;
+      case Type::IntTyID:    Idx = IdxGV.IntVal; break;
+      case Type::LongTyID:   Idx = IdxGV.LongVal; break;
+      case Type::UByteTyID:  Idx = IdxGV.UByteVal; break;
+      case Type::UShortTyID: Idx = IdxGV.UShortVal; break;
+      case Type::UIntTyID:   Idx = IdxGV.UIntVal; break;
+      case Type::ULongTyID:  Idx = IdxGV.ULongVal; break;
+      }
+      Total += TD.getTypeSize(ST->getElementType())*Idx;
     }
   }
 
@@ -637,7 +762,7 @@ GenericValue Interpreter::executeGEPOperation(Value *Ptr, User::op_iterator I,
 void Interpreter::visitGetElementPtrInst(GetElementPtrInst &I) {
   ExecutionContext &SF = ECStack.back();
   SetValue(&I, TheEE->executeGEPOperation(I.getPointerOperand(),
-                                   I.idx_begin(), I.idx_end(), SF), SF);
+                                   gep_type_begin(I), gep_type_end(I), SF), SF);
 }
 
 void Interpreter::visitLoadInst(LoadInst &I) {
@@ -662,6 +787,44 @@ void Interpreter::visitStoreInst(StoreInst &I) {
 
 void Interpreter::visitCallSite(CallSite CS) {
   ExecutionContext &SF = ECStack.back();
+
+  // Check to see if this is an intrinsic function call...
+  if (Function *F = CS.getCalledFunction())
+   if (F->isExternal ())
+    switch (F->getIntrinsicID()) {
+    case Intrinsic::not_intrinsic:
+      break;
+    case Intrinsic::vastart: { // va_start
+      GenericValue ArgIndex;
+      ArgIndex.UIntPairVal.first = ECStack.size() - 1;
+      ArgIndex.UIntPairVal.second = 0;
+      SetValue(CS.getInstruction(), ArgIndex, SF);
+      return;
+    }
+    case Intrinsic::vaend:    // va_end is a noop for the interpreter
+      return;
+    case Intrinsic::vacopy:   // va_copy: dest = src
+      SetValue(CS.getInstruction(), getOperandValue(*CS.arg_begin(), SF), SF);
+      return;
+    default:
+      // If it is an unknown intrinsic function, use the intrinsic lowering
+      // class to transform it into hopefully tasty LLVM code.
+      //
+      Instruction *Prev = CS.getInstruction()->getPrev();
+      BasicBlock *Parent = CS.getInstruction()->getParent();
+      IL->LowerIntrinsicCall(cast<CallInst>(CS.getInstruction()));
+
+      // Restore the CurInst pointer to the first instruction newly inserted, if
+      // any.
+      if (!Prev) {
+        SF.CurInst = Parent->begin();
+      } else {
+        SF.CurInst = Prev;
+        ++SF.CurInst;
+      }
+      return;
+    }
+
   SF.Caller = CS;
   std::vector<GenericValue> ArgVals;
   const unsigned NumArgs = SF.Caller.arg_size();
@@ -699,14 +862,10 @@ void Interpreter::visitCallSite(CallSite CS) {
 #define IMPLEMENT_SHIFT(OP, TY) \
    case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.UByteVal; break
 
-void Interpreter::visitShl(ShiftInst &I) {
-  ExecutionContext &SF = ECStack.back();
-  const Type *Ty    = I.getOperand(0)->getType();
-  GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
-  GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
+static GenericValue executeShlInst(GenericValue Src1, GenericValue Src2,
+                                   const Type *Ty) {
   GenericValue Dest;
-
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_SHIFT(<<, UByte);
     IMPLEMENT_SHIFT(<<, SByte);
     IMPLEMENT_SHIFT(<<, UShort);
@@ -718,17 +877,13 @@ void Interpreter::visitShl(ShiftInst &I) {
   default:
     std::cout << "Unhandled type for Shl instruction: " << *Ty << "\n";
   }
-  SetValue(&I, Dest, SF);
+  return Dest;
 }
 
-void Interpreter::visitShr(ShiftInst &I) {
-  ExecutionContext &SF = ECStack.back();
-  const Type *Ty    = I.getOperand(0)->getType();
-  GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
-  GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
+static GenericValue executeShrInst(GenericValue Src1, GenericValue Src2,
+                                   const Type *Ty) {
   GenericValue Dest;
-
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_SHIFT(>>, UByte);
     IMPLEMENT_SHIFT(>>, SByte);
     IMPLEMENT_SHIFT(>>, UShort);
@@ -741,6 +896,26 @@ void Interpreter::visitShr(ShiftInst &I) {
     std::cout << "Unhandled type for Shr instruction: " << *Ty << "\n";
     abort();
   }
+  return Dest;
+}
+
+void Interpreter::visitShl(ShiftInst &I) {
+  ExecutionContext &SF = ECStack.back();
+  const Type *Ty    = I.getOperand(0)->getType();
+  GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
+  GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
+  GenericValue Dest;
+  Dest = executeShlInst (Src1, Src2, Ty);
+  SetValue(&I, Dest, SF);
+}
+
+void Interpreter::visitShr(ShiftInst &I) {
+  ExecutionContext &SF = ECStack.back();
+  const Type *Ty    = I.getOperand(0)->getType();
+  GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
+  GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
+  GenericValue Dest;
+  Dest = executeShrInst (Src1, Src2, Ty);
   SetValue(&I, Dest, SF);
 }
 
@@ -749,7 +924,7 @@ void Interpreter::visitShr(ShiftInst &I) {
 
 #define IMPLEMENT_CAST_CASE_START(DESTTY, DESTCTY)    \
   case Type::DESTTY##TyID:                      \
-    switch (SrcTy->getPrimitiveID()) {          \
+    switch (SrcTy->getTypeID()) {          \
       IMPLEMENT_CAST(DESTTY, DESTCTY, Bool);    \
       IMPLEMENT_CAST(DESTTY, DESTCTY, UByte);   \
       IMPLEMENT_CAST(DESTTY, DESTCTY, SByte);   \
@@ -766,7 +941,7 @@ void Interpreter::visitShr(ShiftInst &I) {
       IMPLEMENT_CAST(DESTTY, DESTCTY, Double)
 
 #define IMPLEMENT_CAST_CASE_END()    \
-    default: std::cout << "Unhandled cast: " << SrcTy << " to " << Ty << "\n"; \
+    default: std::cout << "Unhandled cast: " << *SrcTy << " to " << *Ty << "\n"; \
       abort();                                  \
     }                                           \
     break
@@ -781,7 +956,7 @@ GenericValue Interpreter::executeCastOperation(Value *SrcVal, const Type *Ty,
   const Type *SrcTy = SrcVal->getType();
   GenericValue Dest, Src = getOperandValue(SrcVal, SF);
 
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_CAST_CASE(UByte  , (unsigned char));
     IMPLEMENT_CAST_CASE(SByte  , (  signed char));
     IMPLEMENT_CAST_CASE(UShort , (unsigned short));
@@ -810,13 +985,12 @@ void Interpreter::visitCastInst(CastInst &I) {
 void Interpreter::visitVANextInst(VANextInst &I) {
   ExecutionContext &SF = ECStack.back();
 
-  // Get the incoming valist element.  LLI treats the valist as an integer.
+  // Get the incoming valist parameter.  LLI treats the valist as a
+  // (ec-stack-depth var-arg-index) pair.
   GenericValue VAList = getOperandValue(I.getOperand(0), SF);
   
-  // Move to the next operand.
-  unsigned Argument = VAList.IntVal++;
-  assert(Argument < SF.VarArgs.size() &&
-         "Accessing past the last vararg argument!");
+  // Move the pointer to the next vararg.
+  ++VAList.UIntPairVal.second;
   SetValue(&I, VAList, SF);
 }
 
@@ -826,14 +1000,14 @@ void Interpreter::visitVANextInst(VANextInst &I) {
 void Interpreter::visitVAArgInst(VAArgInst &I) {
   ExecutionContext &SF = ECStack.back();
 
-  // Get the incoming valist element.  LLI treats the valist as an integer.
+  // Get the incoming valist parameter.  LLI treats the valist as a
+  // (ec-stack-depth var-arg-index) pair.
   GenericValue VAList = getOperandValue(I.getOperand(0), SF);
-  unsigned Argument = VAList.IntVal;
-  assert(Argument < SF.VarArgs.size() &&
-         "Accessing past the last vararg argument!");
-  GenericValue Dest, Src = SF.VarArgs[Argument];
+  GenericValue Dest;
+  GenericValue Src = ECStack[VAList.UIntPairVal.first]
+       .VarArgs[VAList.UIntPairVal.second];
   const Type *Ty = I.getType();
-  switch (Ty->getPrimitiveID()) {
+  switch (Ty->getTypeID()) {
     IMPLEMENT_VAARG(UByte);
     IMPLEMENT_VAARG(SByte);
     IMPLEMENT_VAARG(UShort);
@@ -907,6 +1081,7 @@ void Interpreter::run() {
     // Track the number of dynamic instructions executed.
     ++NumDynamicInsts;
 
+    DEBUG(std::cerr << "About to interpret: " << I);
     visit(I);   // Dispatch to one of the visit* methods...
   }
 }