#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cmath>
using namespace llvm;
STATISTIC(NumDynamicInsts, "Number of dynamic instructions executed");
-static Interpreter *TheEE = 0;
static cl::opt<bool> PrintVolatile("interpreter-print-volatile", cl::Hidden,
cl::desc("make the interpreter print every volatile load and store"));
// Various Helper Functions
//===----------------------------------------------------------------------===//
-static inline uint64_t doSignExtension(uint64_t Val, const IntegerType* ITy) {
- // Determine if the value is signed or not
- bool isSigned = (Val & (1 << (ITy->getBitWidth()-1))) != 0;
- // If its signed, extend the sign bits
- if (isSigned)
- Val |= ~ITy->getBitMask();
- return Val;
-}
-
static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) {
SF.Values[V] = Val;
}
-void Interpreter::initializeExecutionEngine() {
- TheEE = this;
-}
-
//===----------------------------------------------------------------------===//
// Binary Instruction Implementations
//===----------------------------------------------------------------------===//
Dest.TY##Val = Src1.TY##Val OP Src2.TY##Val; \
break
-#define IMPLEMENT_INTEGER_BINOP1(OP, TY) \
- case Type::IntegerTyID: { \
- Dest.IntVal = Src1.IntVal OP Src2.IntVal; \
- break; \
- }
-
-
-static void executeAddInst(GenericValue &Dest, GenericValue Src1,
- GenericValue Src2, const Type *Ty) {
+static void executeFAddInst(GenericValue &Dest, GenericValue Src1,
+ GenericValue Src2, const Type *Ty) {
switch (Ty->getTypeID()) {
- IMPLEMENT_INTEGER_BINOP1(+, Ty);
IMPLEMENT_BINARY_OPERATOR(+, Float);
IMPLEMENT_BINARY_OPERATOR(+, Double);
default:
- cerr << "Unhandled type for Add instruction: " << *Ty << "\n";
- abort();
+ cerr << "Unhandled type for FAdd instruction: " << *Ty << "\n";
+ llvm_unreachable();
}
}
-static void executeSubInst(GenericValue &Dest, GenericValue Src1,
- GenericValue Src2, const Type *Ty) {
+static void executeFSubInst(GenericValue &Dest, GenericValue Src1,
+ GenericValue Src2, const Type *Ty) {
switch (Ty->getTypeID()) {
- IMPLEMENT_INTEGER_BINOP1(-, Ty);
IMPLEMENT_BINARY_OPERATOR(-, Float);
IMPLEMENT_BINARY_OPERATOR(-, Double);
default:
- cerr << "Unhandled type for Sub instruction: " << *Ty << "\n";
- abort();
+ cerr << "Unhandled type for FSub instruction: " << *Ty << "\n";
+ llvm_unreachable();
}
}
-static void executeMulInst(GenericValue &Dest, GenericValue Src1,
- GenericValue Src2, const Type *Ty) {
+static void executeFMulInst(GenericValue &Dest, GenericValue Src1,
+ GenericValue Src2, const Type *Ty) {
switch (Ty->getTypeID()) {
- IMPLEMENT_INTEGER_BINOP1(*, Ty);
IMPLEMENT_BINARY_OPERATOR(*, Float);
IMPLEMENT_BINARY_OPERATOR(*, Double);
default:
- cerr << "Unhandled type for Mul instruction: " << *Ty << "\n";
- abort();
+ cerr << "Unhandled type for FMul instruction: " << *Ty << "\n";
+ llvm_unreachable();
}
}
IMPLEMENT_BINARY_OPERATOR(/, Double);
default:
cerr << "Unhandled type for FDiv instruction: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
}
break;
default:
cerr << "Unhandled type for Rem instruction: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
}
IMPLEMENT_POINTER_ICMP(==);
default:
cerr << "Unhandled type for ICMP_EQ predicate: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(!=);
default:
cerr << "Unhandled type for ICMP_NE predicate: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(<);
default:
cerr << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(<);
default:
cerr << "Unhandled type for ICMP_SLT predicate: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(>);
default:
cerr << "Unhandled type for ICMP_UGT predicate: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(>);
default:
cerr << "Unhandled type for ICMP_SGT predicate: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(<=);
default:
cerr << "Unhandled type for ICMP_ULE predicate: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(<=);
default:
cerr << "Unhandled type for ICMP_SLE predicate: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(>=);
default:
cerr << "Unhandled type for ICMP_UGE predicate: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_POINTER_ICMP(>=);
default:
cerr << "Unhandled type for ICMP_SGE predicate: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
case ICmpInst::ICMP_SGE: R = executeICMP_SGE(Src1, Src2, Ty); break;
default:
cerr << "Don't know how to handle this ICmp predicate!\n-->" << I;
- abort();
+ llvm_unreachable();
}
SetValue(&I, R, SF);
IMPLEMENT_FCMP(==, Double);
default:
cerr << "Unhandled type for FCmp EQ instruction: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
default:
cerr << "Unhandled type for FCmp NE instruction: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_FCMP(<=, Double);
default:
cerr << "Unhandled type for FCmp LE instruction: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_FCMP(>=, Double);
default:
cerr << "Unhandled type for FCmp GE instruction: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_FCMP(<, Double);
default:
cerr << "Unhandled type for FCmp LT instruction: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
IMPLEMENT_FCMP(>, Double);
default:
cerr << "Unhandled type for FCmp GT instruction: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
return Dest;
}
case FCmpInst::FCMP_OGE: R = executeFCMP_OGE(Src1, Src2, Ty); break;
default:
cerr << "Don't know how to handle this FCmp predicate!\n-->" << I;
- abort();
+ llvm_unreachable();
}
SetValue(&I, R, SF);
}
default:
cerr << "Unhandled Cmp predicate\n";
- abort();
+ llvm_unreachable();
}
}
GenericValue R; // Result
switch (I.getOpcode()) {
- case Instruction::Add: executeAddInst (R, Src1, Src2, Ty); break;
- case Instruction::Sub: executeSubInst (R, Src1, Src2, Ty); break;
- case Instruction::Mul: executeMulInst (R, Src1, Src2, Ty); break;
- case Instruction::FDiv: executeFDivInst (R, Src1, Src2, Ty); break;
- case Instruction::FRem: executeFRemInst (R, Src1, Src2, Ty); break;
+ case Instruction::Add: R.IntVal = Src1.IntVal + Src2.IntVal; break;
+ case Instruction::Sub: R.IntVal = Src1.IntVal - Src2.IntVal; break;
+ case Instruction::Mul: R.IntVal = Src1.IntVal * Src2.IntVal; break;
+ case Instruction::FAdd: executeFAddInst(R, Src1, Src2, Ty); break;
+ case Instruction::FSub: executeFSubInst(R, Src1, Src2, Ty); break;
+ case Instruction::FMul: executeFMulInst(R, Src1, Src2, Ty); break;
+ case Instruction::FDiv: executeFDivInst(R, Src1, Src2, Ty); break;
+ case Instruction::FRem: executeFRemInst(R, Src1, Src2, Ty); break;
case Instruction::UDiv: R.IntVal = Src1.IntVal.udiv(Src2.IntVal); break;
case Instruction::SDiv: R.IntVal = Src1.IntVal.sdiv(Src2.IntVal); break;
case Instruction::URem: R.IntVal = Src1.IntVal.urem(Src2.IntVal); break;
case Instruction::Xor: R.IntVal = Src1.IntVal ^ Src2.IntVal; break;
default:
cerr << "Don't know how to handle this binary operator!\n-->" << I;
- abort();
+ llvm_unreachable();
}
SetValue(&I, R, SF);
do {
ECStack.pop_back ();
if (ECStack.empty ())
- abort ();
+ llvm_report_error("Empty stack during unwind!");
Inst = ECStack.back ().Caller.getInstruction ();
} while (!(Inst && isa<InvokeInst> (Inst)));
}
void Interpreter::visitUnreachableInst(UnreachableInst &I) {
- cerr << "ERROR: Program executed an 'unreachable' instruction!\n";
- abort();
+ llvm_report_error("ERROR: Program executed an 'unreachable' instruction!");
}
void Interpreter::visitBranchInst(BranchInst &I) {
unsigned NumElements =
getOperandValue(I.getOperand(0), SF).IntVal.getZExtValue();
- unsigned TypeSize = (size_t)TD.getTypePaddedSize(Ty);
+ unsigned TypeSize = (size_t)TD.getTypeAllocSize(Ty);
// Avoid malloc-ing zero bytes, use max()...
unsigned MemToAlloc = std::max(1U, NumElements * TypeSize);
assert(BitWidth == 64 && "Invalid index type for getelementptr");
Idx = (int64_t)IdxGV.IntVal.getZExtValue();
}
- Total += TD.getTypePaddedSize(ST->getElementType())*Idx;
+ Total += TD.getTypeAllocSize(ST->getElementType())*Idx;
}
}
void Interpreter::visitGetElementPtrInst(GetElementPtrInst &I) {
ExecutionContext &SF = ECStack.back();
- SetValue(&I, TheEE->executeGEPOperation(I.getPointerOperand(),
+ SetValue(&I, executeGEPOperation(I.getPointerOperand(),
gep_type_begin(I), gep_type_end(I), SF), SF);
}
} else if (SrcTy->isInteger()) {
Dest.IntVal = Src.IntVal;
} else
- assert(0 && "Invalid BitCast");
+ LLVM_UNREACHABLE("Invalid BitCast");
} else if (DstTy == Type::FloatTy) {
if (SrcTy->isInteger())
Dest.FloatVal = Src.IntVal.bitsToFloat();
else
Dest.DoubleVal = Src.DoubleVal;
} else
- assert(0 && "Invalid Bitcast");
+ LLVM_UNREACHABLE("Invalid Bitcast");
return Dest;
}
IMPLEMENT_VAARG(Double);
default:
cerr << "Unhandled dest type for vaarg instruction: " << *Ty << "\n";
- abort();
+ llvm_unreachable();
}
// Set the Value of this Instruction.
GenericValue Dest;
const Type * Ty = CE->getOperand(0)->getType();
switch (CE->getOpcode()) {
- case Instruction::Add: executeAddInst (Dest, Op0, Op1, Ty); break;
- case Instruction::Sub: executeSubInst (Dest, Op0, Op1, Ty); break;
- case Instruction::Mul: executeMulInst (Dest, Op0, Op1, Ty); break;
+ case Instruction::Add: Dest.IntVal = Op0.IntVal + Op1.IntVal; break;
+ case Instruction::Sub: Dest.IntVal = Op0.IntVal - Op1.IntVal; break;
+ case Instruction::Mul: Dest.IntVal = Op0.IntVal * Op1.IntVal; break;
+ case Instruction::FAdd: executeFAddInst(Dest, Op0, Op1, Ty); break;
+ case Instruction::FSub: executeFSubInst(Dest, Op0, Op1, Ty); break;
+ case Instruction::FMul: executeFMulInst(Dest, Op0, Op1, Ty); break;
case Instruction::FDiv: executeFDivInst(Dest, Op0, Op1, Ty); break;
case Instruction::FRem: executeFRemInst(Dest, Op0, Op1, Ty); break;
case Instruction::SDiv: Dest.IntVal = Op0.IntVal.sdiv(Op1.IntVal); break;
case Instruction::UDiv: Dest.IntVal = Op0.IntVal.udiv(Op1.IntVal); break;
case Instruction::URem: Dest.IntVal = Op0.IntVal.urem(Op1.IntVal); break;
case Instruction::SRem: Dest.IntVal = Op0.IntVal.srem(Op1.IntVal); break;
- case Instruction::And: Dest.IntVal = Op0.IntVal.And(Op1.IntVal); break;
- case Instruction::Or: Dest.IntVal = Op0.IntVal.Or(Op1.IntVal); break;
- case Instruction::Xor: Dest.IntVal = Op0.IntVal.Xor(Op1.IntVal); break;
+ case Instruction::And: Dest.IntVal = Op0.IntVal & Op1.IntVal; break;
+ case Instruction::Or: Dest.IntVal = Op0.IntVal | Op1.IntVal; break;
+ case Instruction::Xor: Dest.IntVal = Op0.IntVal ^ Op1.IntVal; break;
case Instruction::Shl:
Dest.IntVal = Op0.IntVal.shl(Op1.IntVal.getZExtValue());
break;
break;
default:
cerr << "Unhandled ConstantExpr: " << *CE << "\n";
- abort();
+ llvm_unreachable();
return GenericValue();
}
return Dest;
DOUT << " --> ";
const GenericValue &Val = SF.Values[&I];
switch (I.getType()->getTypeID()) {
- default: assert(0 && "Invalid GenericValue Type");
+ default: LLVM_UNREACHABLE("Invalid GenericValue Type");
case Type::VoidTyID: DOUT << "void"; break;
case Type::FloatTyID: DOUT << "float " << Val.FloatVal; break;
case Type::DoubleTyID: DOUT << "double " << Val.DoubleVal; break;