+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;
+}
+
+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;
+ maskToBitWidth(Dest, DBitWidth);
+ } 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) {