aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ExecutionEngine
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp303
-rw-r--r--lib/ExecutionEngine/Interpreter/Execution.cpp1065
-rw-r--r--lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp14
-rw-r--r--lib/ExecutionEngine/Interpreter/Interpreter.h37
-rw-r--r--lib/ExecutionEngine/JIT/JIT.cpp48
5 files changed, 967 insertions, 500 deletions
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index e5f9ea1..26f51d0 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -296,6 +296,28 @@ void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) {
return state.getGlobalAddressMap(locked)[GV];
}
+/// This macro is used to handle a variety of situations involing integer
+/// values where the action should be done to one of the GenericValue members.
+/// THEINTTY is a const Type * for the integer type. ACTION1 comes before
+/// the GenericValue, ACTION2 comes after.
+#define DO_FOR_INTEGER(THEINTTY, ACTION) \
+ { \
+ unsigned BitWidth = cast<IntegerType>(THEINTTY)->getBitWidth(); \
+ if (BitWidth == 1) {\
+ ACTION(Int1Val); \
+ } else if (BitWidth <= 8) {\
+ ACTION(Int8Val); \
+ } else if (BitWidth <= 16) {\
+ ACTION(Int16Val); \
+ } else if (BitWidth <= 32) { \
+ ACTION(Int32Val); \
+ } else if (BitWidth <= 64) { \
+ ACTION(Int64Val); \
+ } else {\
+ assert(0 && "Not implemented: integer types > 64 bits"); \
+ } \
+ }
+
/// This function converts a Constant* into a GenericValue. The interesting
/// part is if C is a ConstantExpr.
/// @brief Get a GenericValue for a Constnat*
@@ -350,34 +372,21 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
// IntToPtr casts are just so special. Cast to intptr_t first.
Constant *Op = CE->getOperand(0);
GenericValue GV = getConstantValue(Op);
- switch (Op->getType()->getTypeID()) {
- case Type::Int1TyID: return PTOGV((void*)(uintptr_t)GV.Int1Val);
- case Type::Int8TyID: return PTOGV((void*)(uintptr_t)GV.Int8Val);
- case Type::Int16TyID: return PTOGV((void*)(uintptr_t)GV.Int16Val);
- case Type::Int32TyID: return PTOGV((void*)(uintptr_t)GV.Int32Val);
- case Type::Int64TyID: return PTOGV((void*)(uintptr_t)GV.Int64Val);
- default: assert(0 && "Unknown integral type!");
- }
+#define INT_TO_PTR_ACTION(FIELD) \
+ return PTOGV((void*)(uintptr_t)GV.FIELD)
+ DO_FOR_INTEGER(Op->getType(), INT_TO_PTR_ACTION)
+#undef INT_TO_PTR_ACTION
break;
}
case Instruction::Add:
switch (CE->getOperand(0)->getType()->getTypeID()) {
default: assert(0 && "Bad add type!"); abort();
- case Type::Int64TyID:
- Result.Int64Val = getConstantValue(CE->getOperand(0)).Int64Val +
- getConstantValue(CE->getOperand(1)).Int64Val;
- break;
- case Type::Int32TyID:
- Result.Int32Val = getConstantValue(CE->getOperand(0)).Int32Val +
- getConstantValue(CE->getOperand(1)).Int32Val;
- break;
- case Type::Int16TyID:
- Result.Int16Val = getConstantValue(CE->getOperand(0)).Int16Val +
- getConstantValue(CE->getOperand(1)).Int16Val;
- break;
- case Type::Int8TyID:
- Result.Int8Val = getConstantValue(CE->getOperand(0)).Int8Val +
- getConstantValue(CE->getOperand(1)).Int8Val;
+ case Type::IntegerTyID:
+#define ADD_ACTION(FIELD) \
+ Result.FIELD = getConstantValue(CE->getOperand(0)).FIELD + \
+ getConstantValue(CE->getOperand(1)).FIELD;
+ DO_FOR_INTEGER(CE->getOperand(0)->getType(),ADD_ACTION);
+#undef ADD_ACTION
break;
case Type::FloatTyID:
Result.FloatVal = getConstantValue(CE->getOperand(0)).FloatVal +
@@ -399,14 +408,26 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
switch (C->getType()->getTypeID()) {
#define GET_CONST_VAL(TY, CTY, CLASS, GETMETH) \
case Type::TY##TyID: Result.TY##Val = (CTY)cast<CLASS>(C)->GETMETH(); break
- GET_CONST_VAL(Int1 , bool , ConstantInt, getZExtValue);
- GET_CONST_VAL(Int8 , unsigned char , ConstantInt, getZExtValue);
- GET_CONST_VAL(Int16 , unsigned short, ConstantInt, getZExtValue);
- GET_CONST_VAL(Int32 , unsigned int , ConstantInt, getZExtValue);
- GET_CONST_VAL(Int64 , uint64_t , ConstantInt, getZExtValue);
GET_CONST_VAL(Float , float , ConstantFP, getValue);
GET_CONST_VAL(Double, double , ConstantFP, getValue);
#undef GET_CONST_VAL
+ case Type::IntegerTyID: {
+ unsigned BitWidth = cast<IntegerType>(C->getType())->getBitWidth();
+ if (BitWidth == 1)
+ Result.Int1Val = (bool)cast<ConstantInt>(C)->getZExtValue();
+ else if (BitWidth <= 8)
+ Result.Int8Val = (uint8_t )cast<ConstantInt>(C)->getZExtValue();
+ else if (BitWidth <= 16)
+ Result.Int16Val = (uint16_t )cast<ConstantInt>(C)->getZExtValue();
+ else if (BitWidth <= 32)
+ Result.Int32Val = (uint32_t )cast<ConstantInt>(C)->getZExtValue();
+ else if (BitWidth <= 64)
+ Result.Int64Val = (uint64_t )cast<ConstantInt>(C)->getZExtValue();
+ else
+ assert("Integers with > 64-bits not implemented");
+ break;
+ }
+
case Type::PointerTyID:
if (isa<ConstantPointerNull>(C))
Result.PointerVal = 0;
@@ -433,22 +454,43 @@ void ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr,
const Type *Ty) {
if (getTargetData()->isLittleEndian()) {
switch (Ty->getTypeID()) {
- case Type::Int1TyID:
- case Type::Int8TyID: Ptr->Untyped[0] = Val.Int8Val; break;
- case Type::Int16TyID: Ptr->Untyped[0] = Val.Int16Val & 255;
- Ptr->Untyped[1] = (Val.Int16Val >> 8) & 255;
- break;
- Store4BytesLittleEndian:
+ case Type::IntegerTyID: {
+ unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
+ if (BitWidth <= 8)
+ Ptr->Untyped[0] = Val.Int8Val;
+ else if (BitWidth <= 16) {
+ Ptr->Untyped[0] = Val.Int16Val & 255;
+ Ptr->Untyped[1] = (Val.Int16Val >> 8) & 255;
+ } else if (BitWidth <= 32) {
+ Ptr->Untyped[0] = Val.Int32Val & 255;
+ Ptr->Untyped[1] = (Val.Int32Val >> 8) & 255;
+ Ptr->Untyped[2] = (Val.Int32Val >> 16) & 255;
+ Ptr->Untyped[3] = (Val.Int32Val >> 24) & 255;
+ } else if (BitWidth <= 64) {
+ Ptr->Untyped[0] = (unsigned char)(Val.Int64Val );
+ Ptr->Untyped[1] = (unsigned char)(Val.Int64Val >> 8);
+ Ptr->Untyped[2] = (unsigned char)(Val.Int64Val >> 16);
+ Ptr->Untyped[3] = (unsigned char)(Val.Int64Val >> 24);
+ Ptr->Untyped[4] = (unsigned char)(Val.Int64Val >> 32);
+ Ptr->Untyped[5] = (unsigned char)(Val.Int64Val >> 40);
+ Ptr->Untyped[6] = (unsigned char)(Val.Int64Val >> 48);
+ Ptr->Untyped[7] = (unsigned char)(Val.Int64Val >> 56);
+ } else
+ assert(0 && "Integer types > 64 bits not supported");
+ break;
+ }
+Store4BytesLittleEndian:
case Type::FloatTyID:
- case Type::Int32TyID: Ptr->Untyped[0] = Val.Int32Val & 255;
- Ptr->Untyped[1] = (Val.Int32Val >> 8) & 255;
- Ptr->Untyped[2] = (Val.Int32Val >> 16) & 255;
- Ptr->Untyped[3] = (Val.Int32Val >> 24) & 255;
- break;
- case Type::PointerTyID: if (getTargetData()->getPointerSize() == 4)
- goto Store4BytesLittleEndian;
+ Ptr->Untyped[0] = Val.Int32Val & 255;
+ Ptr->Untyped[1] = (Val.Int32Val >> 8) & 255;
+ Ptr->Untyped[2] = (Val.Int32Val >> 16) & 255;
+ Ptr->Untyped[3] = (Val.Int32Val >> 24) & 255;
+ break;
+ case Type::PointerTyID:
+ if (getTargetData()->getPointerSize() == 4)
+ goto Store4BytesLittleEndian;
+ /* FALL THROUGH */
case Type::DoubleTyID:
- case Type::Int64TyID:
Ptr->Untyped[0] = (unsigned char)(Val.Int64Val );
Ptr->Untyped[1] = (unsigned char)(Val.Int64Val >> 8);
Ptr->Untyped[2] = (unsigned char)(Val.Int64Val >> 16);
@@ -463,22 +505,43 @@ void ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr,
}
} else {
switch (Ty->getTypeID()) {
- case Type::Int1TyID:
- case Type::Int8TyID: Ptr->Untyped[0] = Val.Int8Val; break;
- case Type::Int16TyID: Ptr->Untyped[1] = Val.Int16Val & 255;
- Ptr->Untyped[0] = (Val.Int16Val >> 8) & 255;
- break;
+ case Type::IntegerTyID: {
+ unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
+ if (BitWidth <= 8)
+ Ptr->Untyped[0] = Val.Int8Val;
+ else if (BitWidth <= 16) {
+ Ptr->Untyped[1] = Val.Int16Val & 255;
+ Ptr->Untyped[0] = (Val.Int16Val >> 8) & 255;
+ } else if (BitWidth <= 32) {
+ Ptr->Untyped[3] = Val.Int32Val & 255;
+ Ptr->Untyped[2] = (Val.Int32Val >> 8) & 255;
+ Ptr->Untyped[1] = (Val.Int32Val >> 16) & 255;
+ Ptr->Untyped[0] = (Val.Int32Val >> 24) & 255;
+ } else if (BitWidth <= 64) {
+ Ptr->Untyped[7] = (unsigned char)(Val.Int64Val );
+ Ptr->Untyped[6] = (unsigned char)(Val.Int64Val >> 8);
+ Ptr->Untyped[5] = (unsigned char)(Val.Int64Val >> 16);
+ Ptr->Untyped[4] = (unsigned char)(Val.Int64Val >> 24);
+ Ptr->Untyped[3] = (unsigned char)(Val.Int64Val >> 32);
+ Ptr->Untyped[2] = (unsigned char)(Val.Int64Val >> 40);
+ Ptr->Untyped[1] = (unsigned char)(Val.Int64Val >> 48);
+ Ptr->Untyped[0] = (unsigned char)(Val.Int64Val >> 56);
+ } else
+ assert(0 && "Integer types > 64 bits not supported");
+ break;
+ }
Store4BytesBigEndian:
case Type::FloatTyID:
- case Type::Int32TyID: Ptr->Untyped[3] = Val.Int32Val & 255;
- Ptr->Untyped[2] = (Val.Int32Val >> 8) & 255;
- Ptr->Untyped[1] = (Val.Int32Val >> 16) & 255;
- Ptr->Untyped[0] = (Val.Int32Val >> 24) & 255;
- break;
- case Type::PointerTyID: if (getTargetData()->getPointerSize() == 4)
- goto Store4BytesBigEndian;
+ Ptr->Untyped[3] = Val.Int32Val & 255;
+ Ptr->Untyped[2] = (Val.Int32Val >> 8) & 255;
+ Ptr->Untyped[1] = (Val.Int32Val >> 16) & 255;
+ Ptr->Untyped[0] = (Val.Int32Val >> 24) & 255;
+ break;
+ case Type::PointerTyID:
+ if (getTargetData()->getPointerSize() == 4)
+ goto Store4BytesBigEndian;
+ /* FALL THROUGH */
case Type::DoubleTyID:
- case Type::Int64TyID:
Ptr->Untyped[7] = (unsigned char)(Val.Int64Val );
Ptr->Untyped[6] = (unsigned char)(Val.Int64Val >> 8);
Ptr->Untyped[5] = (unsigned char)(Val.Int64Val >> 16);
@@ -501,60 +564,104 @@ GenericValue ExecutionEngine::LoadValueFromMemory(GenericValue *Ptr,
GenericValue Result;
if (getTargetData()->isLittleEndian()) {
switch (Ty->getTypeID()) {
- case Type::Int1TyID:
- case Type::Int8TyID: Result.Int8Val = Ptr->Untyped[0]; break;
- case Type::Int16TyID: Result.Int16Val = (unsigned)Ptr->Untyped[0] |
- ((unsigned)Ptr->Untyped[1] << 8);
- break;
+ case Type::IntegerTyID: {
+ unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
+ if (BitWidth <= 8)
+ Result.Int8Val = Ptr->Untyped[0];
+ else if (BitWidth <= 16) {
+ Result.Int16Val = (unsigned)Ptr->Untyped[0] |
+ ((unsigned)Ptr->Untyped[1] << 8);
+ } else if (BitWidth <= 32) {
+ Result.Int32Val = (unsigned)Ptr->Untyped[0] |
+ ((unsigned)Ptr->Untyped[1] << 8) |
+ ((unsigned)Ptr->Untyped[2] << 16) |
+ ((unsigned)Ptr->Untyped[3] << 24);
+ } else if (BitWidth <= 64) {
+ Result.Int64Val = (uint64_t)Ptr->Untyped[0] |
+ ((uint64_t)Ptr->Untyped[1] << 8) |
+ ((uint64_t)Ptr->Untyped[2] << 16) |
+ ((uint64_t)Ptr->Untyped[3] << 24) |
+ ((uint64_t)Ptr->Untyped[4] << 32) |
+ ((uint64_t)Ptr->Untyped[5] << 40) |
+ ((uint64_t)Ptr->Untyped[6] << 48) |
+ ((uint64_t)Ptr->Untyped[7] << 56);
+ } else
+ assert(0 && "Integer types > 64 bits not supported");
+ break;
+ }
Load4BytesLittleEndian:
case Type::FloatTyID:
- case Type::Int32TyID: Result.Int32Val = (unsigned)Ptr->Untyped[0] |
- ((unsigned)Ptr->Untyped[1] << 8) |
- ((unsigned)Ptr->Untyped[2] << 16) |
- ((unsigned)Ptr->Untyped[3] << 24);
- break;
- case Type::PointerTyID: if (getTargetData()->getPointerSize() == 4)
- goto Load4BytesLittleEndian;
+ Result.Int32Val = (unsigned)Ptr->Untyped[0] |
+ ((unsigned)Ptr->Untyped[1] << 8) |
+ ((unsigned)Ptr->Untyped[2] << 16) |
+ ((unsigned)Ptr->Untyped[3] << 24);
+ break;
+ case Type::PointerTyID:
+ if (getTargetData()->getPointerSize() == 4)
+ goto Load4BytesLittleEndian;
+ /* FALL THROUGH */
case Type::DoubleTyID:
- case Type::Int64TyID: Result.Int64Val = (uint64_t)Ptr->Untyped[0] |
- ((uint64_t)Ptr->Untyped[1] << 8) |
- ((uint64_t)Ptr->Untyped[2] << 16) |
- ((uint64_t)Ptr->Untyped[3] << 24) |
- ((uint64_t)Ptr->Untyped[4] << 32) |
- ((uint64_t)Ptr->Untyped[5] << 40) |
- ((uint64_t)Ptr->Untyped[6] << 48) |
- ((uint64_t)Ptr->Untyped[7] << 56);
- break;
+ Result.Int64Val = (uint64_t)Ptr->Untyped[0] |
+ ((uint64_t)Ptr->Untyped[1] << 8) |
+ ((uint64_t)Ptr->Untyped[2] << 16) |
+ ((uint64_t)Ptr->Untyped[3] << 24) |
+ ((uint64_t)Ptr->Untyped[4] << 32) |
+ ((uint64_t)Ptr->Untyped[5] << 40) |
+ ((uint64_t)Ptr->Untyped[6] << 48) |
+ ((uint64_t)Ptr->Untyped[7] << 56);
+ break;
default:
cerr << "Cannot load value of type " << *Ty << "!\n";
abort();
}
} else {
switch (Ty->getTypeID()) {
- case Type::Int1TyID:
- case Type::Int8TyID: Result.Int8Val = Ptr->Untyped[0]; break;
- case Type::Int16TyID: Result.Int16Val = (unsigned)Ptr->Untyped[1] |
- ((unsigned)Ptr->Untyped[0] << 8);
- break;
+ case Type::IntegerTyID: {
+ unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
+ if (BitWidth <= 8)
+ Result.Int8Val = Ptr->Untyped[0];
+ else if (BitWidth <= 16) {
+ Result.Int16Val = (unsigned)Ptr->Untyped[1] |
+ ((unsigned)Ptr->Untyped[0] << 8);
+ } else if (BitWidth <= 32) {
+ Result.Int32Val = (unsigned)Ptr->Untyped[3] |
+ ((unsigned)Ptr->Untyped[2] << 8) |
+ ((unsigned)Ptr->Untyped[1] << 16) |
+ ((unsigned)Ptr->Untyped[0] << 24);
+ } else if (BitWidth <= 64) {
+ Result.Int64Val = (uint64_t)Ptr->Untyped[7] |
+ ((uint64_t)Ptr->Untyped[6] << 8) |
+ ((uint64_t)Ptr->Untyped[5] << 16) |
+ ((uint64_t)Ptr->Untyped[4] << 24) |
+ ((uint64_t)Ptr->Untyped[3] << 32) |
+ ((uint64_t)Ptr->Untyped[2] << 40) |
+ ((uint64_t)Ptr->Untyped[1] << 48) |
+ ((uint64_t)Ptr->Untyped[0] << 56);
+ } else
+ assert(0 && "Integer types > 64 bits not supported");
+ break;
+ }
Load4BytesBigEndian:
case Type::FloatTyID:
- case Type::Int32TyID: Result.Int32Val =(unsigned)Ptr->Untyped[3] |
- ((unsigned)Ptr->Untyped[2] << 8) |
- ((unsigned)Ptr->Untyped[1] << 16) |
- ((unsigned)Ptr->Untyped[0] << 24);
+ Result.Int32Val = (unsigned)Ptr->Untyped[3] |
+ ((unsigned)Ptr->Untyped[2] << 8) |
+ ((unsigned)Ptr->Untyped[1] << 16) |
+ ((unsigned)Ptr->Untyped[0] << 24);
break;
- case Type::PointerTyID: if (getTargetData()->getPointerSize() == 4)
- goto Load4BytesBigEndian;
+ case Type::PointerTyID:
+ if (getTargetData()->getPointerSize() == 4)
+ goto Load4BytesBigEndian;
+ /* FALL THROUGH */
case Type::DoubleTyID:
- case Type::Int64TyID: Result.Int64Val = (uint64_t)Ptr->Untyped[7] |
- ((uint64_t)Ptr->Untyped[6] << 8) |
- ((uint64_t)Ptr->Untyped[5] << 16) |
- ((uint64_t)Ptr->Untyped[4] << 24) |
- ((uint64_t)Ptr->Untyped[3] << 32) |
- ((uint64_t)Ptr->Untyped[2] << 40) |
- ((uint64_t)Ptr->Untyped[1] << 48) |
- ((uint64_t)Ptr->Untyped[0] << 56);
- break;
+ Result.Int64Val = (uint64_t)Ptr->Untyped[7] |
+ ((uint64_t)Ptr->Untyped[6] << 8) |
+ ((uint64_t)Ptr->Untyped[5] << 16) |
+ ((uint64_t)Ptr->Untyped[4] << 24) |
+ ((uint64_t)Ptr->Untyped[3] << 32) |
+ ((uint64_t)Ptr->Untyped[2] << 40) |
+ ((uint64_t)Ptr->Untyped[1] << 48) |
+ ((uint64_t)Ptr->Untyped[0] << 56);
+ break;
default:
cerr << "Cannot load value of type " << *Ty << "!\n";
abort();
@@ -708,8 +815,8 @@ void ExecutionEngine::emitGlobals() {
}
}
- // Now that all of the globals are set up in memory, loop through them all and
- // initialize their contents.
+ // Now that all of the globals are set up in memory, loop through them all
+ // and initialize their contents.
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
if (!I->isExternal()) {
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp
index 0a0fbce..681fb67 100644
--- a/lib/ExecutionEngine/Interpreter/Execution.cpp
+++ b/lib/ExecutionEngine/Interpreter/Execution.cpp
@@ -20,6 +20,7 @@
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
#include <cmath>
using namespace llvm;
@@ -69,20 +70,30 @@ static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2,
GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
ExecutionContext &SF) {
switch (CE->getOpcode()) {
- case Instruction::Trunc:
+ case Instruction::Trunc:
+ return executeTruncInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::ZExt:
+ return executeZExtInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::SExt:
+ return executeSExtInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::FPTrunc:
+ return executeFPTruncInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::FPExt:
+ return executeFPExtInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::UIToFP:
+ return executeUIToFPInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::SIToFP:
+ return executeSIToFPInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::FPToUI:
+ return executeFPToUIInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::FPToSI:
+ return executeFPToSIInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::PtrToInt:
+ return executePtrToIntInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::IntToPtr:
+ return executeIntToPtrInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::BitCast:
- return executeCastOperation(Instruction::CastOps(CE->getOpcode()),
- CE->getOperand(0), CE->getType(), SF);
+ return executeBitCastInst(CE->getOperand(0), CE->getType(), SF);
case Instruction::GetElementPtr:
return executeGEPOperation(CE->getOperand(0), gep_type_begin(CE),
gep_type_end(CE), SF);
@@ -190,14 +201,69 @@ void Interpreter::initializeExecutionEngine() {
#define IMPLEMENT_BINARY_OPERATOR(OP, TY) \
case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.TY##Val; break
+#define IMPLEMENT_INTEGER_BINOP(OP, TY) \
+ case Type::IntegerTyID: { \
+ unsigned BitWidth = cast<IntegerType>(TY)->getBitWidth(); \
+ if (BitWidth == 1) \
+ Dest.Int1Val = Src1.Int1Val OP Src2.Int1Val; \
+ else if (BitWidth <= 8) \
+ Dest.Int8Val = Src1.Int8Val OP Src2.Int8Val; \
+ else if (BitWidth <= 16) \
+ Dest.Int16Val = Src1.Int16Val OP Src2.Int16Val; \
+ else if (BitWidth <= 32) \
+ Dest.Int32Val = Src1.Int32Val OP Src2.Int32Val; \
+ else if (BitWidth <= 64) \
+ Dest.Int64Val = Src1.Int64Val OP Src2.Int64Val; \
+ else \
+ cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \
+ break; \
+ }
+
+#define IMPLEMENT_SIGNED_BINOP(OP, TY) \
+ if (const IntegerType *ITy = dyn_cast<IntegerType>(TY)) { \
+ unsigned BitWidth = ITy->getBitWidth(); \
+ if (BitWidth <= 8) \
+ Dest.Int8Val = ((int8_t)Src1.Int8Val) OP ((int8_t)Src2.Int8Val); \
+ else if (BitWidth <= 16) \
+ Dest.Int16Val = ((int16_t)Src1.Int16Val) OP ((int16_t)Src2.Int16Val); \
+ else if (BitWidth <= 32) \
+ Dest.Int32Val = ((int32_t)Src1.Int32Val) OP ((int32_t)Src2.Int32Val); \
+ else if (BitWidth <= 64) \
+ Dest.Int64Val = ((int64_t)Src1.Int64Val) OP ((int64_t)Src2.Int64Val); \
+ else { \
+ cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \
+ abort(); \
+ } \
+ } else { \
+ cerr << "Unhandled type for " #OP " operator: " << *Ty << "\n"; \
+ abort(); \
+ }
+
+#define IMPLEMENT_UNSIGNED_BINOP(OP, TY) \
+ if (const IntegerType *ITy = dyn_cast<IntegerType>(TY)) { \
+ unsigned BitWidth = ITy->getBitWidth(); \
+ if (BitWidth <= 8) \
+ Dest.Int8Val = ((uint8_t)Src1.Int8Val) OP ((uint8_t)Src2.Int8Val); \
+ else if (BitWidth <= 16) \
+ Dest.Int16Val = ((uint16_t)Src1.Int16Val) OP ((uint16_t)Src2.Int16Val); \
+ else if (BitWidth <= 32) \
+ Dest.Int32Val = ((uint32_t)Src1.Int32Val) OP ((uint32_t)Src2.Int32Val); \
+ else if (BitWidth <= 64) \
+ Dest.Int64Val = ((uint64_t)Src1.Int64Val) OP ((uint64_t)Src2.Int64Val); \
+ else { \
+ cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \
+ abort(); \
+ } \
+ } else { \
+ cerr << "Unhandled type for " #OP " operator: " << *Ty << "\n"; \
+ abort(); \
+ }
+
static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_BINARY_OPERATOR(+, Int8);
- IMPLEMENT_BINARY_OPERATOR(+, Int16);
- IMPLEMENT_BINARY_OPERATOR(+, Int32);
- IMPLEMENT_BINARY_OPERATOR(+, Int64);
+ IMPLEMENT_INTEGER_BINOP(+, Ty);
IMPLEMENT_BINARY_OPERATOR(+, Float);
IMPLEMENT_BINARY_OPERATOR(+, Double);
default:
@@ -211,10 +277,7 @@ static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_BINARY_OPERATOR(-, Int8);
- IMPLEMENT_BINARY_OPERATOR(-, Int16);
- IMPLEMENT_BINARY_OPERATOR(-, Int32);
- IMPLEMENT_BINARY_OPERATOR(-, Int64);
+ IMPLEMENT_INTEGER_BINOP(-, Ty);
IMPLEMENT_BINARY_OPERATOR(-, Float);
IMPLEMENT_BINARY_OPERATOR(-, Double);
default:
@@ -228,10 +291,7 @@ static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_BINARY_OPERATOR(*, Int8);
- IMPLEMENT_BINARY_OPERATOR(*, Int16);
- IMPLEMENT_BINARY_OPERATOR(*, Int32);
- IMPLEMENT_BINARY_OPERATOR(*, Int64);
+ IMPLEMENT_INTEGER_BINOP(*, Ty);
IMPLEMENT_BINARY_OPERATOR(*, Float);
IMPLEMENT_BINARY_OPERATOR(*, Double);
default:
@@ -241,37 +301,17 @@ static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2,
return Dest;
}
-#define IMPLEMENT_SIGNLESS_BINOP(OP, TY, CAST) \
- case Type::TY##TyID: Dest.TY##Val = \
- ((CAST)Src1.TY##Val) OP ((CAST)Src2.TY##Val); break
-
static GenericValue executeUDivInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
- switch (Ty->getTypeID()) {
- IMPLEMENT_SIGNLESS_BINOP(/, Int8, uint8_t);
- IMPLEMENT_SIGNLESS_BINOP(/, Int16, uint16_t);
- IMPLEMENT_SIGNLESS_BINOP(/, Int32, uint32_t);
- IMPLEMENT_SIGNLESS_BINOP(/, Int64, uint64_t);
- default:
- cerr << "Unhandled type for UDiv instruction: " << *Ty << "\n";
- abort();
- }
+ IMPLEMENT_UNSIGNED_BINOP(/,Ty)
return Dest;
}
static GenericValue executeSDivInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
- switch (Ty->getTypeID()) {
- IMPLEMENT_SIGNLESS_BINOP(/, Int8, int8_t);
- IMPLEMENT_SIGNLESS_BINOP(/, Int16, int16_t);
- IMPLEMENT_SIGNLESS_BINOP(/, Int32, int32_t);
- IMPLEMENT_SIGNLESS_BINOP(/, Int64, int64_t);
- default:
- cerr << "Unhandled type for SDiv instruction: " << *Ty << "\n";
- abort();
- }
+ IMPLEMENT_SIGNED_BINOP(/,Ty)
return Dest;
}
@@ -282,7 +322,7 @@ static GenericValue executeFDivInst(GenericValue Src1, GenericValue Src2,
IMPLEMENT_BINARY_OPERATOR(/, Float);
IMPLEMENT_BINARY_OPERATOR(/, Double);
default:
- cerr << "Unhandled type for Div instruction: " << *Ty << "\n";
+ cerr << "Unhandled type for FDiv instruction: " << *Ty << "\n";
abort();
}
return Dest;
@@ -291,30 +331,14 @@ static GenericValue executeFDivInst(GenericValue Src1, GenericValue Src2,
static GenericValue executeURemInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
- switch (Ty->getTypeID()) {
- IMPLEMENT_SIGNLESS_BINOP(%, Int8, uint8_t);
- IMPLEMENT_SIGNLESS_BINOP(%, Int16, uint16_t);
- IMPLEMENT_SIGNLESS_BINOP(%, Int32, uint32_t);
- IMPLEMENT_SIGNLESS_BINOP(%, Int64, uint64_t );
- default:
- cerr << "Unhandled type for URem instruction: " << *Ty << "\n";
- abort();
- }
+ IMPLEMENT_UNSIGNED_BINOP(%, Ty)
return Dest;
}
static GenericValue executeSRemInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
- switch (Ty->getTypeID()) {
- IMPLEMENT_SIGNLESS_BINOP(%, Int8, int8_t);
- IMPLEMENT_SIGNLESS_BINOP(%, Int16, int16_t);
- IMPLEMENT_SIGNLESS_BINOP(%, Int32, int32_t);
- IMPLEMENT_SIGNLESS_BINOP(%, Int64, int64_t);
- default:
- cerr << "Unhandled type for Rem instruction: " << *Ty << "\n";
- abort();
- }
+ IMPLEMENT_SIGNED_BINOP(%, Ty)
return Dest;
}
@@ -338,60 +362,69 @@ static GenericValue executeFRemInst(GenericValue Src1, GenericValue Src2,
static GenericValue executeAndInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
- switch (Ty->getTypeID()) {
- IMPLEMENT_BINARY_OPERATOR(&, Int1);
- IMPLEMENT_BINARY_OPERATOR(&, Int8);
- IMPLEMENT_BINARY_OPERATOR(&, Int16);
- IMPLEMENT_BINARY_OPERATOR(&, Int32);
- IMPLEMENT_BINARY_OPERATOR(&, Int64);
- default:
- cerr << "Unhandled type for And instruction: " << *Ty << "\n";
- abort();
- }
+ IMPLEMENT_UNSIGNED_BINOP(&, Ty)
return Dest;
}
static GenericValue executeOrInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
- switch (Ty->getTypeID()) {
- IMPLEMENT_BINARY_OPERATOR(|, Int1);
- IMPLEMENT_BINARY_OPERATOR(|, Int8);
- IMPLEMENT_BINARY_OPERATOR(|, Int16);
- IMPLEMENT_BINARY_OPERATOR(|, Int32);
- IMPLEMENT_BINARY_OPERATOR(|, Int64);
- default:
- cerr << "Unhandled type for Or instruction: " << *Ty << "\n";
- abort();
- }
+ IMPLEMENT_UNSIGNED_BINOP(|, Ty)
return Dest;
}
static GenericValue executeXorInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
- switch (Ty->getTypeID()) {
- IMPLEMENT_BINARY_OPERATOR(^, Int1);
- IMPLEMENT_BINARY_OPERATOR(^, Int8);
- IMPLEMENT_BINARY_OPERATOR(^, Int16);
- IMPLEMENT_BINARY_OPERATOR(^, Int32);
- IMPLEMENT_BINARY_OPERATOR(^, Int64);
- default:
- cerr << "Unhandled type for Xor instruction: " << *Ty << "\n";
- abort();
- }
+ IMPLEMENT_UNSIGNED_BINOP(^, Ty)
return Dest;
}
-#define IMPLEMENT_ICMP(OP, TY, CAST) \
- case Type::TY##TyID: Dest.Int1Val = \
- ((CAST)Src1.TY##Val) OP ((CAST)Src2.TY##Val); break
+#define IMPLEMENT_SIGNED_ICMP(OP, TY) \
+ case Type::IntegerTyID: { \
+ unsigned BitWidth = cast<IntegerType>(TY)->getBitWidth(); \
+ if (BitWidth == 1) \
+ Dest.Int1Val = ((int8_t)Src1.Int1Val) OP ((int8_t)Src2.Int1Val); \
+ else if (BitWidth <= 8) \
+ Dest.Int1Val = ((int8_t)Src1.Int8Val) OP ((int8_t)Src2.Int8Val); \
+ else if (BitWidth <= 16) \
+ Dest.Int1Val = ((int16_t)Src1.Int16Val) OP ((int16_t)Src2.Int16Val); \
+ else if (BitWidth <= 32) \
+ Dest.Int1Val = ((int32_t)Src1.Int32Val) OP ((int32_t)Src2.Int32Val); \
+ else if (BitWidth <= 64) \
+ Dest.Int1Val = ((int64_t)Src1.Int64Val) OP ((int64_t)Src2.Int64Val); \
+ else { \
+ cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \
+ abort(); \
+ } \
+ break; \
+ }
+
+#define IMPLEMENT_UNSIGNED_ICMP(OP, TY) \
+ case Type::IntegerTyID: { \
+ unsigned BitWidth = cast<IntegerType>(TY)->getBitWidth(); \
+ if (BitWidth == 1) \
+ Dest.Int1Val = ((uint8_t)Src1.Int1Val) OP ((uint8_t)Src2.Int1Val); \
+ else if (BitWidth <= 8) \
+ Dest.Int1Val = ((uint8_t)Src1.Int8Val) OP ((uint8_t)Src2.Int8Val); \
+ else if (BitWidth <= 16) \
+ Dest.Int1Val = ((uint16_t)Src1.Int16Val) OP ((uint16_t)Src2.Int16Val); \
+ else if (BitWidth <= 32) \
+ Dest.Int1Val = ((uint32_t)Src1.Int32Val) OP ((uint32_t)Src2.Int32Val); \
+ else if (BitWidth <= 64) \
+ Dest.Int1Val = ((uint64_t)Src1.Int64Val) OP ((uint64_t)Src2.Int64Val); \
+ else { \
+ cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \
+ abort(); \
+ } \
+ break; \
+ }
// Handle pointers specially because they must be compared with only as much
// width as the host has. We _do not_ want to be comparing 64 bit values when
// running on a 32-bit target, otherwise the upper 32 bits might mess up
// comparisons if they contain garbage.
-#define IMPLEMENT_POINTERCMP(OP) \
+#define IMPLEMENT_POINTER_ICMP(OP) \
case Type::PointerTyID: \
Dest.Int1Val = (void*)(intptr_t)Src1.PointerVal OP \
(void*)(intptr_t)Src2.PointerVal; break
@@ -400,11 +433,8 @@ static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_ICMP(==, Int8, uint8_t);
- IMPLEMENT_ICMP(==, Int16, uint16_t);
- IMPLEMENT_ICMP(==, Int32, uint32_t);
- IMPLEMENT_ICMP(==, Int64, uint64_t);
- IMPLEMENT_POINTERCMP(==);
+ IMPLEMENT_UNSIGNED_ICMP(==, Ty);
+ IMPLEMENT_POINTER_ICMP(==);
default:
cerr << "Unhandled type for ICMP_EQ predicate: " << *Ty << "\n";
abort();
@@ -416,11 +446,8 @@ static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_ICMP(!=, Int8, uint8_t);
- IMPLEMENT_ICMP(!=, Int16, uint16_t);
- IMPLEMENT_ICMP(!=, Int32, uint32_t);
- IMPLEMENT_ICMP(!=, Int64, uint64_t);
- IMPLEMENT_POINTERCMP(!=);
+ IMPLEMENT_UNSIGNED_ICMP(!=, Ty);
+ IMPLEMENT_POINTER_ICMP(!=);
default:
cerr << "Unhandled type for ICMP_NE predicate: " << *Ty << "\n";
abort();
@@ -432,11 +459,8 @@ static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_ICMP(<, Int8, uint8_t);
- IMPLEMENT_ICMP(<, Int16, uint16_t);
- IMPLEMENT_ICMP(<, Int32, uint32_t);
- IMPLEMENT_ICMP(<, Int64, uint64_t);
- IMPLEMENT_POINTERCMP(<);
+ IMPLEMENT_UNSIGNED_ICMP(<, Ty);
+ IMPLEMENT_POINTER_ICMP(<);
default:
cerr << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n";
abort();
@@ -448,11 +472,8 @@ static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_ICMP(<, Int8, int8_t);
- IMPLEMENT_ICMP(<, Int16, int16_t);
- IMPLEMENT_ICMP(<, Int32, int32_t);
- IMPLEMENT_ICMP(<, Int64, int64_t);
- IMPLEMENT_POINTERCMP(<);
+ IMPLEMENT_SIGNED_ICMP(<, Ty);
+ IMPLEMENT_POINTER_ICMP(<);
default:
cerr << "Unhandled type for ICMP_SLT predicate: " << *Ty << "\n";
abort();
@@ -464,11 +485,8 @@ static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_ICMP(>, Int8, uint8_t);
- IMPLEMENT_ICMP(>, Int16, uint16_t);
- IMPLEMENT_ICMP(>, Int32, uint32_t);
- IMPLEMENT_ICMP(>, Int64, uint64_t);
- IMPLEMENT_POINTERCMP(>);
+ IMPLEMENT_UNSIGNED_ICMP(>, Ty);
+ IMPLEMENT_POINTER_ICMP(>);
default:
cerr << "Unhandled type for ICMP_UGT predicate: " << *Ty << "\n";
abort();
@@ -480,11 +498,8 @@ static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_ICMP(>, Int8, int8_t);
- IMPLEMENT_ICMP(>, Int16, int16_t);
- IMPLEMENT_ICMP(>, Int32, int32_t);
- IMPLEMENT_ICMP(>, Int64, int64_t);
- IMPLEMENT_POINTERCMP(>);
+ IMPLEMENT_SIGNED_ICMP(>, Ty);
+ IMPLEMENT_POINTER_ICMP(>);
default:
cerr << "Unhandled type for ICMP_SGT predicate: " << *Ty << "\n";
abort();
@@ -496,11 +511,8 @@ static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_ICMP(<=, Int8, uint8_t);
- IMPLEMENT_ICMP(<=, Int16, uint16_t);
- IMPLEMENT_ICMP(<=, Int32, uint32_t);
- IMPLEMENT_ICMP(<=, Int64, uint64_t);
- IMPLEMENT_POINTERCMP(<=);
+ IMPLEMENT_UNSIGNED_ICMP(<=, Ty);
+ IMPLEMENT_POINTER_ICMP(<=);
default:
cerr << "Unhandled type for ICMP_ULE predicate: " << *Ty << "\n";
abort();
@@ -512,11 +524,8 @@ static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_ICMP(<=, Int8, int8_t);
- IMPLEMENT_ICMP(<=, Int16, int16_t);
- IMPLEMENT_ICMP(<=, Int32, int32_t);
- IMPLEMENT_ICMP(<=, Int64, int64_t);
- IMPLEMENT_POINTERCMP(<=);
+ IMPLEMENT_SIGNED_ICMP(<=, Ty);
+ IMPLEMENT_POINTER_ICMP(<=);
default:
cerr << "Unhandled type for ICMP_SLE predicate: " << *Ty << "\n";
abort();
@@ -528,11 +537,8 @@ static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_ICMP(>=, Int8, uint8_t);
- IMPLEMENT_ICMP(>=, Int16, uint16_t);
- IMPLEMENT_ICMP(>=, Int32, uint32_t);
- IMPLEMENT_ICMP(>=, Int64, uint64_t);
- IMPLEMENT_POINTERCMP(>=);
+ IMPLEMENT_UNSIGNED_ICMP(>=,Ty);
+ IMPLEMENT_POINTER_ICMP(>=);
default:
cerr << "Unhandled type for ICMP_UGE predicate: " << *Ty << "\n";
abort();
@@ -544,11 +550,8 @@ static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
- IMPLEMENT_ICMP(>=, Int8, int8_t);
- IMPLEMENT_ICMP(>=, Int16, int16_t);
- IMPLEMENT_ICMP(>=, Int32, int32_t);
- IMPLEMENT_ICMP(>=, Int64, int64_t);
- IMPLEMENT_POINTERCMP(>=);
+ IMPLEMENT_SIGNED_ICMP(>=, Ty);
+ IMPLEMENT_POINTER_ICMP(>=);
default:
cerr << "Unhandled type for ICMP_SGE predicate: " << *Ty << "\n";
abort();
@@ -564,8 +567,8 @@ void Interpreter::visitICmpInst(ICmpInst &I) {
GenericValue R; // Result
switch (I.getPredicate()) {
- case ICmpInst::ICMP_EQ: R = executeICMP_EQ(Src1, Src2, Ty); break;
- case ICmpInst::ICMP_NE: R = executeICMP_NE(Src1, Src2, Ty); break;
+ case ICmpInst::ICMP_EQ: R = executeICMP_EQ(Src1, Src2, Ty); break;
+ case ICmpInst::ICMP_NE: R = executeICMP_NE(Src1, Src2, Ty); break;
case ICmpInst::ICMP_ULT: R = executeICMP_ULT(Src1, Src2, Ty); break;
case ICmpInst::ICMP_SLT: R = executeICMP_SLT(Src1, Src2, Ty); break;
case ICmpInst::ICMP_UGT: R = executeICMP_UGT(Src1, Src2, Ty); break;
@@ -585,20 +588,20 @@ void Interpreter::visitICmpInst(ICmpInst &I) {
#define IMPLEMENT_FCMP(OP, TY) \
case Type::TY##TyID: Dest.Int1Val = Src1.TY##Val OP Src2.TY##Val; break
-static GenericValue executeFCMP_EQ(GenericValue Src1, GenericValue Src2,
+static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_FCMP(==, Float);
IMPLEMENT_FCMP(==, Double);
default:
- cerr << "Unhandled type for SetEQ instruction: " << *Ty << "\n";
+ cerr << "Unhandled type for FCmp EQ instruction: " << *Ty << "\n";
abort();
}
return Dest;
}
-static GenericValue executeFCMP_NE(GenericValue Src1, GenericValue Src2,
+static GenericValue executeFCMP_ONE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
@@ -606,64 +609,142 @@ static GenericValue executeFCMP_NE(GenericValue Src1, GenericValue Src2,
IMPLEMENT_FCMP(!=, Double);
default:
- cerr << "Unhandled type for SetNE instruction: " << *Ty << "\n";
+ cerr << "Unhandled type for FCmp NE instruction: " << *Ty << "\n";
abort();
}
return Dest;
}
-static GenericValue executeFCMP_LE(GenericValue Src1, GenericValue Src2,
+static GenericValue executeFCMP_OLE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_FCMP(<=, Float);
IMPLEMENT_FCMP(<=, Double);
default:
- cerr << "Unhandled type for SetLE instruction: " << *Ty << "\n";
+ cerr << "Unhandled type for FCmp LE instruction: " << *Ty << "\n";
abort();
}
return Dest;
}
-static GenericValue executeFCMP_GE(GenericValue Src1, GenericValue Src2,
+static GenericValue executeFCMP_OGE(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_FCMP(>=, Float);
IMPLEMENT_FCMP(>=, Double);
default:
- cerr << "Unhandled type for SetGE instruction: " << *Ty << "\n";
+ cerr << "Unhandled type for FCmp GE instruction: " << *Ty << "\n";
abort();
}
return Dest;
}
-static GenericValue executeFCMP_LT(GenericValue Src1, GenericValue Src2,
+static GenericValue executeFCMP_OLT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_FCMP(<, Float);
IMPLEMENT_FCMP(<, Double);
default:
- cerr << "Unhandled type for SetLT instruction: " << *Ty << "\n";
+ cerr << "Unhandled type for FCmp LT instruction: " << *Ty << "\n";
abort();
}
return Dest;
}
-static GenericValue executeFCMP_GT(GenericValue Src1, GenericValue Src2,
+static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
switch (Ty->getTypeID()) {
IMPLEMENT_FCMP(>, Float);
IMPLEMENT_FCMP(>, Double);
default:
- cerr << "Unhandled type for SetGT instruction: " << *Ty << "\n";
+ cerr << "Unhandled type for FCmp GT instruction: " << *Ty << "\n";
abort();
}
return Dest;
}
+#define IMPLEMENT_UNORDERED(TY, X,Y) \
+ if (TY == Type::FloatTy) \
+ if (X.FloatVal != X.FloatVal || Y.FloatVal != Y.FloatVal) { \
+ Dest.Int1Val = true; \
+ return Dest; \
+ } \
+ else if (X.DoubleVal != X.DoubleVal || Y.DoubleVal != Y.DoubleVal) { \
+ Dest.Int1Val = true; \
+ return Dest; \
+ }
+
+
+static GenericValue executeFCMP_UEQ(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ IMPLEMENT_UNORDERED(Ty, Src1, Src2)
+ return executeFCMP_OEQ(Src1, Src2, Ty);
+}
+
+static GenericValue executeFCMP_UNE(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ IMPLEMENT_UNORDERED(Ty, Src1, Src2)
+ return executeFCMP_ONE(Src1, Src2, Ty);
+}
+
+static GenericValue executeFCMP_ULE(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ IMPLEMENT_UNORDERED(Ty, Src1, Src2)
+ return executeFCMP_OLE(Src1, Src2, Ty);
+}
+
+static GenericValue executeFCMP_UGE(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ IMPLEMENT_UNORDERED(Ty, Src1, Src2)
+ return executeFCMP_OGE(Src1, Src2, Ty);
+}
+
+static GenericValue executeFCMP_ULT(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ IMPLEMENT_UNORDERED(Ty, Src1, Src2)
+ return executeFCMP_OLT(Src1, Src2, Ty);
+}
+
+static GenericValue executeFCMP_UGT(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ IMPLEMENT_UNORDERED(Ty, Src1, Src2)
+ return executeFCMP_OGT(Src1, Src2, Ty);
+}
+
+static GenericValue executeFCMP_ORD(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ if (Ty == Type::FloatTy)
+ Dest.Int1Val = (Src1.FloatVal == Src1.FloatVal &&
+ Src2.FloatVal == Src2.FloatVal);
+ else
+ Dest.Int1Val = (Src1.DoubleVal == Src1.DoubleVal &&
+ Src2.DoubleVal == Src2.DoubleVal);
+ return Dest;
+}
+
+static GenericValue executeFCMP_UNO(GenericValue Src1, GenericValue Src2,
+ const Type *Ty) {
+ GenericValue Dest;
+ if (Ty == Type::FloatTy)
+ Dest.Int1Val = (Src1.FloatVal != Src1.FloatVal ||
+ Src2.FloatVal != Src2.FloatVal);
+ else
+ Dest.Int1Val = (Src1.DoubleVal != Src1.DoubleVal ||
+ Src2.DoubleVal != Src2.DoubleVal);
+ return Dest;
+}
+
void Interpreter::visitFCmpInst(FCmpInst &I) {
ExecutionContext &SF = ECStack.back();
const Type *Ty = I.getOperand(0)->getType();
@@ -672,22 +753,22 @@ void Interpreter::visitFCmpInst(FCmpInst &I) {
GenericValue R; // Result
switch (I.getPredicate()) {
- case FCmpInst::FCMP_FALSE: R.Int1Val = false;
- case FCmpInst::FCMP_ORD: R = executeFCMP_EQ(Src1, Src2, Ty); break; ///???
- case FCmpInst::FCMP_UNO: R = executeFCMP_NE(Src1, Src2, Ty); break; ///???
- case FCmpInst::FCMP_OEQ:
- case FCmpInst::FCMP_UEQ: R = executeFCMP_EQ(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_ONE:
- case FCmpInst::FCMP_UNE: R = executeFCMP_NE(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_OLT:
- case FCmpInst::FCMP_ULT: R = executeFCMP_LT(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_OGT:
- case FCmpInst::FCMP_UGT: R = executeFCMP_GT(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_OLE:
- case FCmpInst::FCMP_ULE: R = executeFCMP_LE(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_OGE:
- case FCmpInst::FCMP_UGE: R = executeFCMP_GE(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_TRUE: R.Int1Val = true;
+ case FCmpInst::FCMP_FALSE: R.Int1Val = false; break;
+ case FCmpInst::FCMP_TRUE: R.Int1Val = true; break;
+ case FCmpInst::FCMP_ORD: R = executeFCMP_ORD(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_UNO: R = executeFCMP_UNO(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_UEQ: R = executeFCMP_UEQ(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OEQ: R = executeFCMP_OEQ(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_UNE: R = executeFCMP_UNE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_ONE: R = executeFCMP_ONE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_ULT: R = executeFCMP_ULT(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OLT: R = executeFCMP_OLT(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_UGT: R = executeFCMP_UGT(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OGT: R = executeFCMP_OGT(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_ULE: R = executeFCMP_ULE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_OLE: R = executeFCMP_OLE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_UGE: R = executeFCMP_UGE(Src1, Src2, Ty); break;
+ 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();
@@ -710,20 +791,20 @@ static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1,
case ICmpInst::ICMP_SGE: return executeICMP_SGE(Src1, Src2, Ty);
case ICmpInst::ICMP_ULE: return executeICMP_ULE(Src1, Src2, Ty);
case ICmpInst::ICMP_SLE: return executeICMP_SLE(Src1, Src2, Ty);
- case FCmpInst::FCMP_ORD: return executeFCMP_EQ(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_UNO: return executeFCMP_NE(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_OEQ:
- case FCmpInst::FCMP_UEQ: return executeFCMP_EQ(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_ONE:
- case FCmpInst::FCMP_UNE: return executeFCMP_NE(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_OLT:
- case FCmpInst::FCMP_ULT: return executeFCMP_LT(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_OGT:
- case FCmpInst::FCMP_UGT: return executeFCMP_GT(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_OLE:
- case FCmpInst::FCMP_ULE: return executeFCMP_LE(Src1, Src2, Ty); break;
- case FCmpInst::FCMP_OGE:
- case FCmpInst::FCMP_UGE: return executeFCMP_GE(Src1, Src2, Ty); break;
+ case FCmpInst::FCMP_ORD: return executeFCMP_ORD(Src1, Src2, Ty);
+ case FCmpInst::FCMP_UNO: return executeFCMP_UNO(Src1, Src2, Ty);
+ case FCmpInst::FCMP_OEQ: return executeFCMP_OEQ(Src1, Src2, Ty);
+ case FCmpInst::FCMP_UEQ: return executeFCMP_UEQ(Src1, Src2, Ty);
+ case FCmpInst::FCMP_ONE: return executeFCMP_ONE(Src1, Src2, Ty);
+ case FCmpInst::FCMP_UNE: return executeFCMP_UNE(Src1, Src2, Ty);
+ case FCmpInst::FCMP_OLT: return executeFCMP_OLT(Src1, Src2, Ty);
+ case FCmpInst::FCMP_ULT: return executeFCMP_ULT(Src1, Src2, Ty);
+ case FCmpInst::FCMP_OGT: return executeFCMP_OGT(Src1, Src2, Ty);
+ case FCmpInst::FCMP_UGT: return executeFCMP_UGT(Src1, Src2, Ty);
+ case FCmpInst::FCMP_OLE: return executeFCMP_OLE(Src1, Src2, Ty);
+ case FCmpInst::FCMP_ULE: return executeFCMP_ULE(Src1, Src2, Ty);
+ case FCmpInst::FCMP_OGE: return executeFCMP_OGE(Src1, Src2, Ty);
+ case FCmpInst::FCMP_UGE: return executeFCMP_UGE(Src1, Src2, Ty);
case FCmpInst::FCMP_FALSE: {
GenericValue Result;
Result.Int1Val = false;
@@ -989,14 +1070,19 @@ GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I,
// Get the index number for the array... which must be long type...
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::Int8TyID: Idx = IdxGV.Int8Val; break;
- case Type::Int16TyID: Idx = IdxGV.Int16Val; break;
- case Type::Int32TyID: Idx = IdxGV.Int32Val; break;
- case Type::Int64TyID: Idx = IdxGV.Int64Val; break;
- }
+ int64_t Idx;
+ unsigned BitWidth =
+ cast<IntegerType>(I.getOperand()->getType())->getBitWidth();
+ if (BitWidth <= 8)
+ Idx = (int64_t)(int8_t)IdxGV.Int8Val;
+ else if (BitWidth <= 16)
+ Idx = (int64_t)(int16_t)IdxGV.Int16Val;
+ else if (BitWidth <= 32)
+ Idx = (int64_t)(int32_t)IdxGV.Int32Val;
+ else if (BitWidth <= 64)
+ Idx = (int64_t)IdxGV.Int64Val;
+ else
+ assert(0 && "Integer types >64 bits not supported");
Total += PointerTy(TD.getTypeSize(ST->getElementType())*Idx);
}
}
@@ -1084,15 +1170,13 @@ void Interpreter::visitCallSite(CallSite CS) {
// this by zero or sign extending the value as appropriate according to the
// source type.
const Type *Ty = V->getType();
- if (Ty->isIntegral() && Ty->getPrimitiveSize() < 4) {
- if (Ty == Type::Int16Ty)
- ArgVals.back().Int32Val = ArgVals.back().Int16Val;
- else if (Ty == Type::Int8Ty)
- ArgVals.back().Int32Val = ArgVals.back().Int8Val;
- else if (Ty == Type::Int1Ty)
+ if (Ty->isIntegral()) {
+ if (Ty->getPrimitiveSizeInBits() == 1)
ArgVals.back().Int32Val = ArgVals.back().Int1Val;
- else
- assert(0 && "Unknown type!");
+ else if (Ty->getPrimitiveSizeInBits() <= 8)
+ ArgVals.back().Int32Val = ArgVals.back().Int8Val;
+ else if (Ty->getPrimitiveSizeInBits() <= 16)
+ ArgVals.back().Int32Val = ArgVals.back().Int16Val;
}
}
@@ -1102,23 +1186,26 @@ void Interpreter::visitCallSite(CallSite CS) {
callFunction((Function*)GVTOP(SRC), ArgVals);
}
-#define IMPLEMENT_SHIFT(OP, TY) \
- case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.Int8Val; break
-
-#define IMPLEMENT_SIGNLESS_SHIFT(OP, TY, CAST) \
- case Type::TY##TyID: Dest.TY##Val = ((CAST)Src1.TY##Val) OP Src2.Int8Val; \
- break
-
static GenericValue executeShlInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
- switch (Ty->getTypeID()) {
- IMPLEMENT_SHIFT(<<, Int8);
- IMPLEMENT_SHIFT(<<, Int16);
- IMPLEMENT_SHIFT(<<, Int32);
- IMPLEMENT_SHIFT(<<, Int64);
- default:
+ if (const IntegerType *ITy = cast<IntegerType>(Ty)) {
+ unsigned BitWidth = ITy->getBitWidth();
+ if (BitWidth <= 8)
+ Dest.Int8Val = ((uint8_t)Src1.Int8Val) << ((uint32_t)Src2.Int8Val);
+ else if (BitWidth <= 16)
+ Dest.Int16Val = ((uint16_t)Src1.Int16Val) << ((uint32_t)Src2.Int8Val);
+ else if (BitWidth <= 32)
+ Dest.Int32Val = ((uint32_t)Src1.Int32Val) << ((uint32_t)Src2.Int8Val);
+ else if (BitWidth <= 64)
+ Dest.Int64Val = ((uint64_t)Src1.Int64Val) << ((uint32_t)Src2.Int8Val);
+ else {
+ cerr << "Integer types > 64 bits not supported: " << *Ty << "\n";
+ abort();
+ }
+ } else {
cerr << "Unhandled type for Shl instruction: " << *Ty << "\n";
+ abort();
}
return Dest;
}
@@ -1126,12 +1213,21 @@ static GenericValue executeShlInst(GenericValue Src1, GenericValue Src2,
static GenericValue executeLShrInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
- switch (Ty->getTypeID()) {
- IMPLEMENT_SIGNLESS_SHIFT(>>, Int8, uint8_t);
- IMPLEMENT_SIGNLESS_SHIFT(>>, Int16, uint16_t);
- IMPLEMENT_SIGNLESS_SHIFT(>>, Int32, uint32_t);
- IMPLEMENT_SIGNLESS_SHIFT(>>, Int64, uint64_t);
- default:
+ if (const IntegerType *ITy = cast<IntegerType>(Ty)) {
+ unsigned BitWidth = ITy->getBitWidth();
+ if (BitWidth <= 8)
+ Dest.Int8Val = ((uint8_t)Src1.Int8Val) >> ((uint32_t)Src2.Int8Val);
+ else if (BitWidth <= 16)
+ Dest.Int16Val = ((uint16_t)Src1.Int16Val) >> ((uint32_t)Src2.Int8Val);
+ else if (BitWidth <= 32)
+ Dest.Int32Val = ((uint32_t)Src1.Int32Val) >> ((uint32_t)Src2.Int8Val);
+ else if (BitWidth <= 64)
+ Dest.Int64Val = ((uint64_t)Src1.Int64Val) >> ((uint32_t)Src2.Int8Val);
+ else {
+ cerr << "Integer types > 64 bits not supported: " << *Ty << "\n";
+ abort();
+ }
+ } else {
cerr << "Unhandled type for LShr instruction: " << *Ty << "\n";
abort();
}
@@ -1141,12 +1237,21 @@ static GenericValue executeLShrInst(GenericValue Src1, GenericValue Src2,
static GenericValue executeAShrInst(GenericValue Src1, GenericValue Src2,
const Type *Ty) {
GenericValue Dest;
- switch (Ty->getTypeID()) {
- IMPLEMENT_SIGNLESS_SHIFT(>>, Int8, int8_t);
- IMPLEMENT_SIGNLESS_SHIFT(>>, Int16, int16_t);
- IMPLEMENT_SIGNLESS_SHIFT(>>, Int32, int32_t);
- IMPLEMENT_SIGNLESS_SHIFT(>>, Int64, int64_t);
- default:
+ if (const IntegerType *ITy = cast<IntegerType>(Ty)) {
+ unsigned BitWidth = ITy->getBitWidth();
+ if (BitWidth <= 8)
+ Dest.Int8Val = ((int8_t)Src1.Int8Val) >> ((int32_t)Src2.Int8Val);
+ else if (BitWidth <= 16)
+ Dest.Int16Val = ((int16_t)Src1.Int16Val) >> ((int32_t)Src2.Int8Val);
+ else if (BitWidth <= 32)
+ Dest.Int32Val = ((int32_t)Src1.Int32Val) >> ((int32_t)Src2.Int8Val);
+ else if (BitWidth <= 64)
+ Dest.Int64Val = ((int64_t)Src1.Int64Val) >> ((int32_t)Src2.Int8Val);
+ else {
+ cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \
+ abort();
+ }
+ } else {
cerr << "Unhandled type for AShr instruction: " << *Ty << "\n";
abort();
}
@@ -1183,165 +1288,357 @@ void Interpreter::visitAShr(ShiftInst &I) {
SetValue(&I, Dest, SF);
}
-#define IMPLEMENT_CAST_START \
- switch (DstTy->getTypeID()) {
-
-#define IMPLEMENT_CAST(STY, DTY, CAST) \
- case Type::STY##TyID: Dest.DTY##Val = (CAST(Src.STY##Val)); break;
-
-#define IMPLEMENT_CAST_CASE(DTY, CAST) \
- case Type::DTY##TyID: \
- switch (SrcTy->getTypeID()) { \
- IMPLEMENT_CAST(Int1, DTY, CAST); \
- IMPLEMENT_CAST(Int8, DTY, CAST); \
- IMPLEMENT_CAST(Int16, DTY, CAST); \
- IMPLEMENT_CAST(Int32, DTY, CAST); \
- IMPLEMENT_CAST(Int64, DTY, CAST); \
- IMPLEMENT_CAST(Pointer,DTY, CAST); \
- IMPLEMENT_CAST(Float, DTY, CAST); \
- IMPLEMENT_CAST(Double, DTY, CAST); \
- default: \
- cerr << "Unhandled cast: " \
- << *SrcTy << " to " << *DstTy << "\n"; \
- abort(); \
- } \
- break
-
-#define IMPLEMENT_CAST_END \
- default: cerr \
- << "Unhandled dest type for cast instruction: " \
- << *DstTy << "\n"; \
- abort(); \
- }
+#define INTEGER_ASSIGN(DEST, BITWIDTH, VAL) \
+ if (BITWIDTH == 1) { \
+ Dest.Int1Val = (bool) VAL; \
+ } else if (BITWIDTH <= 8) { \
+ Dest.Int8Val = (uint8_t) VAL; \
+ } else if (BITWIDTH <= 16) { \
+ Dest.Int16Val = (uint16_t) VAL; \
+ } else if (BITWIDTH <= 32) { \
+ Dest.Int32Val = (uint32_t) VAL; \
+ } else \
+ Dest.Int64Val = (uint64_t) VAL;
+
+GenericValue Interpreter::executeTruncInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
+ const Type *SrcTy = SrcVal->getType();
+ GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ const IntegerType *DITy = cast<IntegerType>(DstTy);
+ const IntegerType *SITy = cast<IntegerType>(SrcTy);
+ unsigned DBitWidth = DITy->getBitWidth();
+ unsigned SBitWidth = SITy->getBitWidth();
+ assert(SBitWidth <= 64 && DBitWidth <= 64 &&
+ "Integer types > 64 bits not supported");
+ assert(SBitWidth > DBitWidth && "Invalid truncate");
+
+ // Mask the source value to its actual bit width. This ensures that any
+ // high order bits are cleared.
+ uint64_t Mask = (1ULL << DBitWidth) - 1;
+ uint64_t MaskedVal = 0;
+ if (SBitWidth <= 8)
+ MaskedVal = Src.Int8Val & Mask;
+ else if (SBitWidth <= 16)
+ MaskedVal = Src.Int16Val & Mask;
+ else if (SBitWidth <= 32)
+ MaskedVal = Src.Int32Val & Mask;
+ else
+ MaskedVal = Src.Int64Val & Mask;
+
+ INTEGER_ASSIGN(Dest, DBitWidth, MaskedVal);
+ return Dest;
+}
-GenericValue Interpreter::executeCastOperation(Instruction::CastOps opcode,
- Value *SrcVal, const Type *DstTy,
- ExecutionContext &SF) {
+GenericValue Interpreter::executeSExtInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
const Type *SrcTy = SrcVal->getType();
GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ const IntegerType *DITy = cast<IntegerType>(DstTy);
+ const IntegerType *SITy = cast<IntegerType>(SrcTy);
+ unsigned DBitWidth = DITy->getBitWidth();
+ unsigned SBitWidth = SITy->getBitWidth();
+ assert(SBitWidth <= 64 && DBitWidth <= 64 &&
+ "Integer types > 64 bits not supported");
+ assert(SBitWidth < DBitWidth && "Invalid sign extend");
+ int64_t Extended = 0;
+ if (SBitWidth == 1)
+ // For sign extension from bool, we must extend the source bits.
+ Extended = 0 - (Src.Int1Val & 1);
+ else if (SBitWidth <= 8)
+ Extended = (int64_t) (int8_t)Src.Int8Val;
+ else if (SBitWidth <= 16)
+ Extended = (int64_t) (int16_t)Src.Int16Val;
+ else if (SBitWidth <= 32)
+ Extended = (int64_t) (int32_t)Src.Int32Val;
+ else
+ Extended = (int64_t) Src.Int64Val;
+
+ // Now that we have a sign extended value, assign it to the destination
+ INTEGER_ASSIGN(Dest, DBitWidth, Extended);
+ return Dest;
+}
- if (opcode == Instruction::Trunc && DstTy->getTypeID() == Type::Int1TyID) {
- // For truncations to bool, we must clear the high order bits of the source
- switch (SrcTy->getTypeID()) {
- case Type::Int1TyID: Src.Int1Val &= 1; break;
- case Type::Int8TyID: Src.Int8Val &= 1; break;
- case Type::Int16TyID: Src.Int16Val &= 1; break;
- case Type::Int32TyID: Src.Int32Val &= 1; break;
- case Type::Int64TyID: Src.Int64Val &= 1; break;
- default:
- assert(0 && "Can't trunc a non-integer!");
- break;
- }
- } else if (opcode == Instruction::SExt &&
- SrcTy->getTypeID() == Type::Int1TyID) {
+GenericValue Interpreter::executeZExtInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
+ const Type *SrcTy = SrcVal->getType();
+ GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ const IntegerType *DITy = cast<IntegerType>(DstTy);
+ const IntegerType *SITy = cast<IntegerType>(SrcTy);
+ unsigned DBitWidth = DITy->getBitWidth();
+ unsigned SBitWidth = SITy->getBitWidth();
+ assert(SBitWidth <= 64 && DBitWidth <= 64 &&
+ "Integer types > 64 bits not supported");
+ assert(SBitWidth < DBitWidth && "Invalid sign extend");
+ uint64_t Extended = 0;
+ if (SBitWidth == 1)
// For sign extension from bool, we must extend the source bits.
- SrcTy = Type::Int64Ty;
- Src.Int64Val = 0 - Src.Int1Val;
- }
+ Extended = (uint64_t) (Src.Int1Val & 1);
+ else if (SBitWidth <= 8)
+ Extended = (uint64_t) (uint8_t)Src.Int8Val;
+ else if (SBitWidth <= 16)
+ Extended = (uint64_t) (uint16_t)Src.Int16Val;
+ else if (SBitWidth <= 32)
+ Extended = (uint64_t) (uint32_t)Src.Int32Val;
+ else
+ Extended = (uint64_t) Src.Int64Val;
+
+ // Now that we have a sign extended value, assign it to the destination
+ INTEGER_ASSIGN(Dest, DBitWidth, Extended);
+ return Dest;
+}
- switch (opcode) {
- case Instruction::Trunc: // src integer, dest integral (can't be long)
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Int1 , (bool));
- IMPLEMENT_CAST_CASE(Int8 , (uint8_t));
- IMPLEMENT_CAST_CASE(Int16, (uint16_t));
- IMPLEMENT_CAST_CASE(Int32, (uint32_t));
- IMPLEMENT_CAST_CASE(Int64, (uint64_t));
- IMPLEMENT_CAST_END
- break;
- case Instruction::ZExt: // src integral (can't be long), dest integer
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Int8 , (uint8_t));
- IMPLEMENT_CAST_CASE(Int16, (uint16_t));
- IMPLEMENT_CAST_CASE(Int32, (uint32_t));
- IMPLEMENT_CAST_CASE(Int64, (uint64_t));
- IMPLEMENT_CAST_END
- break;
- case Instruction::SExt: // src integral (can't be long), dest integer
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Int8 , (uint8_t)(int8_t));
- IMPLEMENT_CAST_CASE(Int16, (uint16_t)(int16_t));
- IMPLEMENT_CAST_CASE(Int32, (uint32_t)(int32_t));
- IMPLEMENT_CAST_CASE(Int64, (uint64_t)(int64_t));
- IMPLEMENT_CAST_END
- break;
- case Instruction::FPTrunc: // src double, dest float
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Float , (float));
- IMPLEMENT_CAST_END
- break;
- case Instruction::FPExt: // src float, dest double
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Double , (double));
- IMPLEMENT_CAST_END
- break;
- case Instruction::UIToFP: // src integral, dest floating
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Float , (float)(uint64_t));
- IMPLEMENT_CAST_CASE(Double , (double)(uint64_t));
- IMPLEMENT_CAST_END
- break;
- case Instruction::SIToFP: // src integeral, dest floating
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Float , (float)(int64_t));
- IMPLEMENT_CAST_CASE(Double , (double)(int64_t));
- IMPLEMENT_CAST_END
- break;
- case Instruction::FPToUI: // src floating, dest integral
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Int1 , (bool));
- IMPLEMENT_CAST_CASE(Int8 , (uint8_t));
- IMPLEMENT_CAST_CASE(Int16, (uint16_t));
- IMPLEMENT_CAST_CASE(Int32, (uint32_t ));
- IMPLEMENT_CAST_CASE(Int64, (uint64_t));
- IMPLEMENT_CAST_END
- break;
- case Instruction::FPToSI: // src floating, dest integral
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Int1 , (bool));
- IMPLEMENT_CAST_CASE(Int8 , (uint8_t) (int8_t));
- IMPLEMENT_CAST_CASE(Int16, (uint16_t)(int16_t));
- IMPLEMENT_CAST_CASE(Int32, (uint32_t)(int32_t));
- IMPLEMENT_CAST_CASE(Int64, (uint64_t)(int64_t));
- IMPLEMENT_CAST_END
- break;
- case Instruction::PtrToInt: // src pointer, dest integral
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Int1 , (bool));
- IMPLEMENT_CAST_CASE(Int8 , (uint8_t));
- IMPLEMENT_CAST_CASE(Int16, (uint16_t));
- IMPLEMENT_CAST_CASE(Int32, (uint32_t));
- IMPLEMENT_CAST_CASE(Int64, (uint64_t));
- IMPLEMENT_CAST_END
- break;
- case Instruction::IntToPtr: // src integral, dest pointer
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Pointer, (PointerTy));
- IMPLEMENT_CAST_END
- break;
- case Instruction::BitCast: // src any, dest any (same size)
- IMPLEMENT_CAST_START
- IMPLEMENT_CAST_CASE(Int1 , (bool));
- IMPLEMENT_CAST_CASE(Int8 , (uint8_t));
- IMPLEMENT_CAST_CASE(Int16 , (uint16_t));
- IMPLEMENT_CAST_CASE(Int32 , (uint32_t));
- IMPLEMENT_CAST_CASE(Int64 , (uint64_t));
- IMPLEMENT_CAST_CASE(Pointer, (PointerTy));
- IMPLEMENT_CAST_CASE(Float , (float));
- IMPLEMENT_CAST_CASE(Double , (double));
- IMPLEMENT_CAST_END
- break;
- default:
- cerr << "Invalid cast opcode for cast instruction: " << opcode << "\n";
- abort();
- }
+GenericValue Interpreter::executeFPTruncInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
+ const Type *SrcTy = SrcVal->getType();
+ GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ assert(SrcTy == Type::DoubleTy && DstTy == Type::FloatTy &&
+ "Invalid FPTrunc instruction");
+ Dest.FloatVal = (float) Src.DoubleVal;
+ return Dest;
+}
+
+GenericValue Interpreter::executeFPExtInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
+ const Type *SrcTy = SrcVal->getType();
+ GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ assert(SrcTy == Type::FloatTy && DstTy == Type::DoubleTy &&
+ "Invalid FPTrunc instruction");
+ Dest.DoubleVal = (double) Src.FloatVal;
+ return Dest;
+}
+
+GenericValue Interpreter::executeFPToUIInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
+ const Type *SrcTy = SrcVal->getType();
+ GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ const IntegerType *DITy = cast<IntegerType>(DstTy);
+ unsigned DBitWidth = DITy->getBitWidth();
+ assert(DBitWidth <= 64 && "Integer types > 64 bits not supported");
+ assert(SrcTy->isFloatingPoint() && "Invalid FPToUI instruction");
+ uint64_t Converted = 0;
+ if (SrcTy->getTypeID() == Type::FloatTyID)
+ Converted = (uint64_t) Src.FloatVal;
+ else
+ Converted = (uint64_t) Src.DoubleVal;
+
+ INTEGER_ASSIGN(Dest, DBitWidth, Converted);
+ return Dest;
+}
+
+GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
+ const Type *SrcTy = SrcVal->getType();
+ GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ const IntegerType *DITy = cast<IntegerType>(DstTy);
+ unsigned DBitWidth = DITy->getBitWidth();
+ assert(DBitWidth <= 64 && "Integer types > 64 bits not supported");
+ assert(SrcTy->isFloatingPoint() && "Invalid FPToSI instruction");
+ int64_t Converted = 0;
+ if (SrcTy->getTypeID() == Type::FloatTyID)
+ Converted = (int64_t) Src.FloatVal;
+ else
+ Converted = (int64_t) Src.DoubleVal;
+
+ INTEGER_ASSIGN(Dest, DBitWidth, Converted);
+ return Dest;
+}
+
+GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
+ const Type *SrcTy = SrcVal->getType();
+ GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ const IntegerType *SITy = cast<IntegerType>(SrcTy);
+ unsigned SBitWidth = SITy->getBitWidth();
+ assert(SBitWidth <= 64 && "Integer types > 64 bits not supported");
+ assert(DstTy->isFloatingPoint() && "Invalid UIToFP instruction");
+ uint64_t Converted = 0;
+ if (SBitWidth == 1)
+ Converted = (uint64_t) Src.Int1Val;
+ else if (SBitWidth <= 8)
+ Converted = (uint64_t) Src.Int8Val;
+ else if (SBitWidth <= 16)
+ Converted = (uint64_t) Src.Int16Val;
+ else if (SBitWidth <= 32)
+ Converted = (uint64_t) Src.Int32Val;
+ else
+ Converted = (uint64_t) Src.Int64Val;
+
+ if (DstTy->getTypeID() == Type::FloatTyID)
+ Dest.FloatVal = (float) Converted;
+ else
+ Dest.DoubleVal = (double) Converted;
+ return Dest;
+}
+
+GenericValue Interpreter::executeSIToFPInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
+ const Type *SrcTy = SrcVal->getType();
+ GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ const IntegerType *SITy = cast<IntegerType>(SrcTy);
+ unsigned SBitWidth = SITy->getBitWidth();
+ assert(SBitWidth <= 64 && "Integer types > 64 bits not supported");
+ assert(DstTy->isFloatingPoint() && "Invalid UIToFP instruction");
+ int64_t Converted = 0;
+ if (SBitWidth == 1)
+ Converted = 0LL - Src.Int1Val;
+ else if (SBitWidth <= 8)
+ Converted = (int64_t) (int8_t)Src.Int8Val;
+ else if (SBitWidth <= 16)
+ Converted = (int64_t) (int16_t)Src.Int16Val;
+ else if (SBitWidth <= 32)
+ Converted = (int64_t) (int32_t)Src.Int32Val;
+ else
+ Converted = (int64_t) Src.Int64Val;
+
+ if (DstTy->getTypeID() == Type::FloatTyID)
+ Dest.FloatVal = (float) Converted;
+ else
+ Dest.DoubleVal = (double) Converted;
+ return Dest;
+}
+
+GenericValue Interpreter::executePtrToIntInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
+ const Type *SrcTy = SrcVal->getType();
+ GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ const IntegerType *DITy = cast<IntegerType>(DstTy);
+ unsigned DBitWidth = DITy->getBitWidth();
+ assert(DBitWidth <= 64 && "Integer types > 64 bits not supported");
+ assert(isa<PointerType>(SrcTy) && "Invalid PtrToInt instruction");
+ INTEGER_ASSIGN(Dest, DBitWidth, (intptr_t) Src.PointerVal);
return Dest;
}
-void Interpreter::visitCastInst(CastInst &I) {
+GenericValue Interpreter::executeIntToPtrInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
+ const Type *SrcTy = SrcVal->getType();
+ GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ const IntegerType *SITy = cast<IntegerType>(SrcTy);
+ unsigned SBitWidth = SITy->getBitWidth();
+ assert(SBitWidth <= 64 && "Integer types > 64 bits not supported");
+ assert(isa<PointerType>(DstTy) && "Invalid PtrToInt instruction");
+ uint64_t Converted = 0;
+ if (SBitWidth == 1)
+ Converted = (uint64_t) Src.Int1Val;
+ else if (SBitWidth <= 8)
+ Converted = (uint64_t) Src.Int8Val;
+ else if (SBitWidth <= 16)
+ Converted = (uint64_t) Src.Int16Val;
+ else if (SBitWidth <= 32)
+ Converted = (uint64_t) Src.Int32Val;
+ else
+ Converted = (uint64_t) Src.Int64Val;
+
+ Dest.PointerVal = (PointerTy) Converted;
+ return Dest;
+}
+
+GenericValue Interpreter::executeBitCastInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF) {
+
+ const Type *SrcTy = SrcVal->getType();
+ GenericValue Dest, Src = getOperandValue(SrcVal, SF);
+ if (isa<PointerType>(DstTy)) {
+ assert(isa<PointerType>(SrcTy) && "Invalid BitCast");
+ Dest.PointerVal = Src.PointerVal;
+ } else if (DstTy->isInteger()) {
+ const IntegerType *DITy = cast<IntegerType>(DstTy);
+ unsigned DBitWidth = DITy->getBitWidth();
+ if (SrcTy == Type::FloatTy) {
+ Dest.Int32Val = FloatToBits(Src.FloatVal);
+ } else if (SrcTy == Type::DoubleTy) {
+ Dest.Int64Val = DoubleToBits(Src.DoubleVal);
+ } else if (SrcTy->isInteger()) {
+ const IntegerType *SITy = cast<IntegerType>(SrcTy);
+ unsigned SBitWidth = SITy->getBitWidth();
+ assert(SBitWidth <= 64 && "Integer types > 64 bits not supported");
+ assert(SBitWidth == DBitWidth && "Invalid BitCast");
+ if (SBitWidth == 1)
+ Dest.Int1Val = Src.Int1Val;
+ else if (SBitWidth <= 8)
+ Dest.Int8Val = Src.Int8Val;
+ else if (SBitWidth <= 16)
+ Dest.Int16Val = Src.Int16Val;
+ else if (SBitWidth <= 32)
+ Dest.Int32Val = Src.Int32Val;
+ else
+ Dest.Int64Val = Src.Int64Val;
+ } else
+ assert(0 && "Invalid BitCast");
+ } else if (DstTy == Type::FloatTy) {
+ if (SrcTy->isInteger())
+ Dest.FloatVal = BitsToFloat(Src.Int32Val);
+ else
+ Dest.FloatVal = Src.FloatVal;
+ } else if (DstTy == Type::DoubleTy) {
+ if (SrcTy->isInteger())
+ Dest.DoubleVal = BitsToDouble(Src.Int64Val);
+ else
+ Dest.DoubleVal = Src.DoubleVal;
+ } else
+ assert(0 && "Invalid Bitcast");
+
+ return Dest;
+}
+
+void Interpreter::visitTruncInst(TruncInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ SetValue(&I, executeTruncInst(I.getOperand(0), I.getType(), SF), SF);
+}
+
+void Interpreter::visitSExtInst(SExtInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ SetValue(&I, executeSExtInst(I.getOperand(0), I.getType(), SF), SF);
+}
+
+void Interpreter::visitZExtInst(ZExtInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ SetValue(&I, executeZExtInst(I.getOperand(0), I.getType(), SF), SF);
+}
+
+void Interpreter::visitFPTruncInst(FPTruncInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ SetValue(&I, executeFPTruncInst(I.getOperand(0), I.getType(), SF), SF);
+}
+
+void Interpreter::visitFPExtInst(FPExtInst &I) {
ExecutionContext &SF = ECStack.back();
- SetValue(&I, executeCastOperation(I.getOpcode(), I.getOperand(0),
- I.getType(), SF), SF);
+ SetValue(&I, executeFPExtInst(I.getOperand(0), I.getType(), SF), SF);
+}
+
+void Interpreter::visitUIToFPInst(UIToFPInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ SetValue(&I, executeUIToFPInst(I.getOperand(0), I.getType(), SF), SF);
+}
+
+void Interpreter::visitSIToFPInst(SIToFPInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ SetValue(&I, executeSIToFPInst(I.getOperand(0), I.getType(), SF), SF);
+}
+
+void Interpreter::visitFPToUIInst(FPToUIInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ SetValue(&I, executeFPToUIInst(I.getOperand(0), I.getType(), SF), SF);
+}
+
+void Interpreter::visitFPToSIInst(FPToSIInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ SetValue(&I, executeFPToSIInst(I.getOperand(0), I.getType(), SF), SF);
+}
+
+void Interpreter::visitPtrToIntInst(PtrToIntInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ SetValue(&I, executePtrToIntInst(I.getOperand(0), I.getType(), SF), SF);
+}
+
+void Interpreter::visitIntToPtrInst(IntToPtrInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ SetValue(&I, executeIntToPtrInst(I.getOperand(0), I.getType(), SF), SF);
+}
+
+void Interpreter::visitBitCastInst(BitCastInst &I) {
+ ExecutionContext &SF = ECStack.back();
+ SetValue(&I, executeBitCastInst(I.getOperand(0), I.getType(), SF), SF);
}
#define IMPLEMENT_VAARG(TY) \
@@ -1358,14 +1655,24 @@ void Interpreter::visitVAArgInst(VAArgInst &I) {
.VarArgs[VAList.UIntPairVal.second];
const Type *Ty = I.getType();
switch (Ty->getTypeID()) {
- IMPLEMENT_VAARG(Int8);
- IMPLEMENT_VAARG(Int16);
- IMPLEMENT_VAARG(Int32);
- IMPLEMENT_VAARG(Int64);
+ case Type::IntegerTyID: {
+ unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
+ if (BitWidth == 1)
+ Dest.Int1Val = Src.Int1Val;
+ else if (BitWidth <= 8)
+ Dest.Int8Val = Src.Int8Val;
+ else if (BitWidth <= 16)
+ Dest.Int16Val = Src.Int16Val;
+ else if (BitWidth <= 32)
+ Dest.Int32Val = Src.Int32Val;
+ else if (BitWidth <= 64)
+ Dest.Int64Val = Src.Int64Val;
+ else
+ assert("Integer types > 64 bits not supported");
+ }
IMPLEMENT_VAARG(Pointer);
IMPLEMENT_VAARG(Float);
IMPLEMENT_VAARG(Double);
- IMPLEMENT_VAARG(Int1);
default:
cerr << "Unhandled dest type for vaarg instruction: " << *Ty << "\n";
abort();
diff --git a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
index 52d3cfa..b1c2ee4 100644
--- a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
+++ b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
@@ -41,11 +41,15 @@ static Interpreter *TheInterpreter;
static char getTypeID(const Type *Ty) {
switch (Ty->getTypeID()) {
case Type::VoidTyID: return 'V';
- case Type::Int1TyID: return 'o';
- case Type::Int8TyID: return 'B';
- case Type::Int16TyID: return 'S';
- case Type::Int32TyID: return 'I';
- case Type::Int64TyID: return 'L';
+ case Type::IntegerTyID:
+ switch (cast<IntegerType>(Ty)->getBitWidth()) {
+ case 1: return 'o';
+ case 8: return 'B';
+ case 16: return 'S';
+ case 32: return 'I';
+ case 64: return 'L';
+ default: return 'N';
+ }
case Type::FloatTyID: return 'F';
case Type::DoubleTyID: return 'D';
case Type::PointerTyID: return 'P';
diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h
index 559c7dc..c62249b 100644
--- a/lib/ExecutionEngine/Interpreter/Interpreter.h
+++ b/lib/ExecutionEngine/Interpreter/Interpreter.h
@@ -144,7 +144,18 @@ public:
void visitStoreInst(StoreInst &I);
void visitGetElementPtrInst(GetElementPtrInst &I);
void visitPHINode(PHINode &PN) { assert(0 && "PHI nodes already handled!"); }
- void visitCastInst(CastInst &I);
+ void visitTruncInst(TruncInst &I);
+ void visitZExtInst(ZExtInst &I);
+ void visitSExtInst(SExtInst &I);
+ void visitFPTruncInst(FPTruncInst &I);
+ void visitFPExtInst(FPExtInst &I);
+ void visitUIToFPInst(UIToFPInst &I);
+ void visitSIToFPInst(SIToFPInst &I);
+ void visitFPToUIInst(FPToUIInst &I);
+ void visitFPToSIInst(FPToSIInst &I);
+ void visitPtrToIntInst(PtrToIntInst &I);
+ void visitIntToPtrInst(IntToPtrInst &I);
+ void visitBitCastInst(BitCastInst &I);
void visitSelectInst(SelectInst &I);
@@ -193,6 +204,30 @@ private: // Helper functions
void initializeExternalFunctions();
GenericValue getConstantExprValue(ConstantExpr *CE, ExecutionContext &SF);
GenericValue getOperandValue(Value *V, ExecutionContext &SF);
+ GenericValue executeTruncInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
+ GenericValue executeSExtInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
+ GenericValue executeZExtInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
+ GenericValue executeFPTruncInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
+ GenericValue executeFPExtInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
+ GenericValue executeFPToUIInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
+ GenericValue executeFPToSIInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
+ GenericValue executeUIToFPInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
+ GenericValue executeSIToFPInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
+ GenericValue executePtrToIntInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
+ GenericValue executeIntToPtrInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
+ GenericValue executeBitCastInst(Value *SrcVal, const Type *DstTy,
+ ExecutionContext &SF);
GenericValue executeCastOperation(Instruction::CastOps opcode, Value *SrcVal,
const Type *Ty, ExecutionContext &SF);
void popStackAndReturnValueToCaller(const Type *RetTy, GenericValue Result);
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp
index 13ee719..7fd62cc 100644
--- a/lib/ExecutionEngine/JIT/JIT.cpp
+++ b/lib/ExecutionEngine/JIT/JIT.cpp
@@ -142,22 +142,25 @@ GenericValue JIT::runFunction(Function *F,
GenericValue rv;
switch (RetTy->getTypeID()) {
default: assert(0 && "Unknown return type for function call!");
- case Type::Int1TyID:
- rv.Int1Val = ((bool(*)())(intptr_t)FPtr)();
- return rv;
- case Type::Int8TyID:
- rv.Int8Val = ((char(*)())(intptr_t)FPtr)();
- return rv;
- case Type::Int16TyID:
- rv.Int16Val = ((short(*)())(intptr_t)FPtr)();
+ case Type::IntegerTyID: {
+ unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
+ if (BitWidth == 1)
+ rv.Int1Val = ((bool(*)())(intptr_t)FPtr)();
+ else if (BitWidth <= 8)
+ rv.Int8Val = ((char(*)())(intptr_t)FPtr)();
+ else if (BitWidth <= 16)
+ rv.Int16Val = ((short(*)())(intptr_t)FPtr)();
+ else if (BitWidth <= 32)
+ rv.Int32Val = ((int(*)())(intptr_t)FPtr)();
+ else if (BitWidth <= 64)
+ rv.Int64Val = ((int64_t(*)())(intptr_t)FPtr)();
+ else
+ assert(0 && "Integer types > 64 bits not supported");
return rv;
+ }
case Type::VoidTyID:
- case Type::Int32TyID:
rv.Int32Val = ((int(*)())(intptr_t)FPtr)();
return rv;
- case Type::Int64TyID:
- rv.Int64Val = ((int64_t(*)())(intptr_t)FPtr)();
- return rv;
case Type::FloatTyID:
rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
return rv;
@@ -191,11 +194,22 @@ GenericValue JIT::runFunction(Function *F,
const GenericValue &AV = ArgValues[i];
switch (ArgTy->getTypeID()) {
default: assert(0 && "Unknown argument type for function call!");
- case Type::Int1TyID: C = ConstantInt::get(ArgTy, AV.Int1Val); break;
- case Type::Int8TyID: C = ConstantInt::get(ArgTy, AV.Int8Val); break;
- case Type::Int16TyID: C = ConstantInt::get(ArgTy, AV.Int16Val); break;
- case Type::Int32TyID: C = ConstantInt::get(ArgTy, AV.Int32Val); break;
- case Type::Int64TyID: C = ConstantInt::get(ArgTy, AV.Int64Val); break;
+ case Type::IntegerTyID: {
+ unsigned BitWidth = cast<IntegerType>(ArgTy)->getBitWidth();
+ if (BitWidth == 1)
+ C = ConstantInt::get(ArgTy, AV.Int1Val);
+ else if (BitWidth <= 8)
+ C = ConstantInt::get(ArgTy, AV.Int8Val);
+ else if (BitWidth <= 16)
+ C = ConstantInt::get(ArgTy, AV.Int16Val);
+ else if (BitWidth <= 32)
+ C = ConstantInt::get(ArgTy, AV.Int32Val);
+ else if (BitWidth <= 64)
+ C = ConstantInt::get(ArgTy, AV.Int64Val);
+ else
+ assert(0 && "Integer types > 64 bits not supported");
+ break;
+ }
case Type::FloatTyID: C = ConstantFP ::get(ArgTy, AV.FloatVal); break;
case Type::DoubleTyID: C = ConstantFP ::get(ArgTy, AV.DoubleVal); break;
case Type::PointerTyID: