diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2007-03-03 06:22:22 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2007-03-03 06:22:22 +0000 |
commit | e1aa0662162a891b5eb7c4e847e5332adf5e2b86 (patch) | |
tree | 364d0675a77c1adf6308a84501fed56b3a6119d0 /lib/ExecutionEngine | |
parent | dea7ef1f17add8dd7050b80dff339e55503ce9d3 (diff) | |
download | external_llvm-e1aa0662162a891b5eb7c4e847e5332adf5e2b86.zip external_llvm-e1aa0662162a891b5eb7c4e847e5332adf5e2b86.tar.gz external_llvm-e1aa0662162a891b5eb7c4e847e5332adf5e2b86.tar.bz2 |
Implement APInt support for the binary operators.
Move the getConstantExpr function towards the end of the file so we don't
need a dozen forward declarations.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34877 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r-- | lib/ExecutionEngine/Interpreter/Execution.cpp | 494 |
1 files changed, 240 insertions, 254 deletions
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index c6dcc5c..68f118d 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -18,6 +18,7 @@ #include "llvm/Instructions.h" #include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/ADT/APInt.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" @@ -27,47 +28,17 @@ using namespace llvm; STATISTIC(NumDynamicInsts, "Number of dynamic instructions executed"); static Interpreter *TheEE = 0; - //===----------------------------------------------------------------------===// -// Value Manipulation code +// Various Helper Functions //===----------------------------------------------------------------------===// -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 executeUDivInst(GenericValue Src1, GenericValue Src2, - const Type *Ty); -static GenericValue executeSDivInst(GenericValue Src1, GenericValue Src2, - const Type *Ty); -static GenericValue executeFDivInst(GenericValue Src1, GenericValue Src2, - const Type *Ty); -static GenericValue executeURemInst(GenericValue Src1, GenericValue Src2, - const Type *Ty); -static GenericValue executeSRemInst(GenericValue Src1, GenericValue Src2, - const Type *Ty); -static GenericValue executeFRemInst(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 executeCmpInst(unsigned predicate, GenericValue Src1, - GenericValue Src2, const Type *Ty); -static GenericValue executeShlInst(GenericValue Src1, GenericValue Src2, - const Type *Ty); -static GenericValue executeLShrInst(GenericValue Src1, GenericValue Src2, - const Type *Ty); -static GenericValue executeAShrInst(GenericValue Src1, GenericValue Src2, - const Type *Ty); -static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2, - GenericValue Src3); +inline void initializeAPInt(GenericValue &GV, const Type* Ty, + ExecutionContext &SF) { + if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty)) + GV.APIntVal = SF.getAPInt(ITy->getBitWidth()); +} -inline uint64_t doSignExtension(uint64_t Val, const IntegerType* ITy) { +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 @@ -76,122 +47,19 @@ inline uint64_t doSignExtension(uint64_t Val, const IntegerType* ITy) { return Val; } -GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE, - ExecutionContext &SF) { - switch (CE->getOpcode()) { - 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 executeBitCastInst(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::SDiv: - return executeSDivInst(getOperandValue(CE->getOperand(0), SF), - getOperandValue(CE->getOperand(1), SF), - CE->getOperand(0)->getType()); - case Instruction::UDiv: - return executeUDivInst(getOperandValue(CE->getOperand(0), SF), - getOperandValue(CE->getOperand(1), SF), - CE->getOperand(0)->getType()); - case Instruction::FDiv: - return executeFDivInst(getOperandValue(CE->getOperand(0), SF), - getOperandValue(CE->getOperand(1), SF), - CE->getOperand(0)->getType()); - case Instruction::URem: - return executeURemInst(getOperandValue(CE->getOperand(0), SF), - getOperandValue(CE->getOperand(1), SF), - CE->getOperand(0)->getType()); - case Instruction::SRem: - return executeSRemInst(getOperandValue(CE->getOperand(0), SF), - getOperandValue(CE->getOperand(1), SF), - CE->getOperand(0)->getType()); - case Instruction::FRem: - return executeFRemInst(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::FCmp: - case Instruction::ICmp: - return executeCmpInst(CE->getPredicate(), - 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::LShr: - return executeLShrInst(getOperandValue(CE->getOperand(0), SF), - getOperandValue(CE->getOperand(1), SF), - CE->getOperand(0)->getType()); - case Instruction::AShr: - return executeAShrInst(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: - cerr << "Unhandled ConstantExpr: " << *CE << "\n"; - abort(); - return GenericValue(); - } -} - -GenericValue Interpreter::getOperandValue(Value *V, ExecutionContext &SF) { - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - return getConstantExprValue(CE, SF); - } else if (Constant *CPV = dyn_cast<Constant>(V)) { - return getConstantValue(CPV); - } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) { - return PTOGV(getPointerToGlobal(GV)); - } else { - return SF.Values[V]; +static inline void maskToBitWidth(GenericValue& GV, unsigned BitWidth) { + uint64_t BitMask = ~(uint64_t)(0ull) >> (64-BitWidth); + if (BitWidth <= 8) + GV.Int8Val &= BitMask; + else if (BitWidth <= 16) + GV.Int16Val &= BitMask; + else if (BitWidth <= 32) + GV.Int32Val &= BitMask; + else if (BitWidth <= 64) + GV.Int64Val &= BitMask; + else { + assert(GV.APIntVal && "Unallocated GV.APIntVal"); + *(GV.APIntVal) &= APInt::getAllOnesValue(BitWidth); } } @@ -213,67 +81,72 @@ void Interpreter::initializeExecutionEngine() { #define IMPLEMENT_INTEGER_BINOP(OP, TY) \ case Type::IntegerTyID: { \ unsigned BitWidth = cast<IntegerType>(TY)->getBitWidth(); \ - if (BitWidth == 1) \ + if (BitWidth == 1) {\ Dest.Int1Val = Src1.Int1Val OP Src2.Int1Val; \ - else if (BitWidth <= 8) \ + maskToBitWidth(Dest, BitWidth); \ + } else if (BitWidth <= 8) {\ Dest.Int8Val = Src1.Int8Val OP Src2.Int8Val; \ - else if (BitWidth <= 16) \ + maskToBitWidth(Dest, BitWidth); \ + } else if (BitWidth <= 16) {\ Dest.Int16Val = Src1.Int16Val OP Src2.Int16Val; \ - else if (BitWidth <= 32) \ + maskToBitWidth(Dest, BitWidth); \ + } else if (BitWidth <= 32) {\ Dest.Int32Val = Src1.Int32Val OP Src2.Int32Val; \ - else if (BitWidth <= 64) \ + maskToBitWidth(Dest, BitWidth); \ + } else if (BitWidth <= 64) {\ Dest.Int64Val = Src1.Int64Val OP Src2.Int64Val; \ - else \ - cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \ - maskToBitWidth(Dest, BitWidth); \ + maskToBitWidth(Dest, BitWidth); \ + } else \ + *(Dest.APIntVal) = *(Src1.APIntVal) OP *(Src2.APIntVal); \ break; \ } -#define IMPLEMENT_SIGNED_BINOP(OP, TY) \ +#define IMPLEMENT_SIGNED_BINOP(OP, TY, APOP) \ if (const IntegerType *ITy = dyn_cast<IntegerType>(TY)) { \ unsigned BitWidth = ITy->getBitWidth(); \ - if (BitWidth <= 8) \ + if (BitWidth <= 8) { \ Dest.Int8Val = ((int8_t)Src1.Int8Val) OP ((int8_t)Src2.Int8Val); \ - else if (BitWidth <= 16) \ + maskToBitWidth(Dest, BitWidth); \ + } else if (BitWidth <= 16) { \ Dest.Int16Val = ((int16_t)Src1.Int16Val) OP ((int16_t)Src2.Int16Val); \ - else if (BitWidth <= 32) \ + maskToBitWidth(Dest, BitWidth); \ + } else if (BitWidth <= 32) { \ Dest.Int32Val = ((int32_t)Src1.Int32Val) OP ((int32_t)Src2.Int32Val); \ - else if (BitWidth <= 64) \ + maskToBitWidth(Dest, BitWidth); \ + } 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(); \ - } \ - maskToBitWidth(Dest, BitWidth); \ + maskToBitWidth(Dest, BitWidth); \ + } else \ + *(Dest.APIntVal) = Src1.APIntVal->APOP(*(Src2.APIntVal)); \ } else { \ cerr << "Unhandled type for " #OP " operator: " << *Ty << "\n"; \ abort(); \ } -#define IMPLEMENT_UNSIGNED_BINOP(OP, TY) \ +#define IMPLEMENT_UNSIGNED_BINOP(OP, TY, APOP) \ if (const IntegerType *ITy = dyn_cast<IntegerType>(TY)) { \ unsigned BitWidth = ITy->getBitWidth(); \ - if (BitWidth <= 8) \ + if (BitWidth <= 8) {\ Dest.Int8Val = ((uint8_t)Src1.Int8Val) OP ((uint8_t)Src2.Int8Val); \ - else if (BitWidth <= 16) \ + maskToBitWidth(Dest, BitWidth); \ + } else if (BitWidth <= 16) {\ Dest.Int16Val = ((uint16_t)Src1.Int16Val) OP ((uint16_t)Src2.Int16Val); \ - else if (BitWidth <= 32) \ + maskToBitWidth(Dest, BitWidth); \ + } else if (BitWidth <= 32) {\ Dest.Int32Val = ((uint32_t)Src1.Int32Val) OP ((uint32_t)Src2.Int32Val); \ - else if (BitWidth <= 64) \ + maskToBitWidth(Dest, BitWidth); \ + } 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(); \ - } \ - maskToBitWidth(Dest, BitWidth); \ + maskToBitWidth(Dest, BitWidth); \ + } else \ + *(Dest.APIntVal) = Src1.APIntVal->APOP(*(Src2.APIntVal)); \ } else { \ cerr << "Unhandled type for " #OP " operator: " << *Ty << "\n"; \ abort(); \ } -static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; +static void executeAddInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_BINOP(+, Ty); IMPLEMENT_BINARY_OPERATOR(+, Float); @@ -282,12 +155,10 @@ static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2, cerr << "Unhandled type for Add instruction: " << *Ty << "\n"; abort(); } - return Dest; } -static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; +static void executeSubInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_BINOP(-, Ty); IMPLEMENT_BINARY_OPERATOR(-, Float); @@ -296,12 +167,10 @@ static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2, cerr << "Unhandled type for Sub instruction: " << *Ty << "\n"; abort(); } - return Dest; } -static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; +static void executeMulInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_BINOP(*, Ty); IMPLEMENT_BINARY_OPERATOR(*, Float); @@ -310,26 +179,20 @@ static GenericValue executeMulInst(GenericValue Src1, GenericValue Src2, cerr << "Unhandled type for Mul instruction: " << *Ty << "\n"; abort(); } - return Dest; } -static GenericValue executeUDivInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; - IMPLEMENT_UNSIGNED_BINOP(/,Ty) - return Dest; +static void executeUDivInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { + IMPLEMENT_UNSIGNED_BINOP(/,Ty,udiv) } -static GenericValue executeSDivInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; - IMPLEMENT_SIGNED_BINOP(/,Ty) - return Dest; +static void executeSDivInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { + IMPLEMENT_SIGNED_BINOP(/,Ty,sdiv) } -static GenericValue executeFDivInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; +static void executeFDivInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { switch (Ty->getTypeID()) { IMPLEMENT_BINARY_OPERATOR(/, Float); IMPLEMENT_BINARY_OPERATOR(/, Double); @@ -337,26 +200,20 @@ static GenericValue executeFDivInst(GenericValue Src1, GenericValue Src2, cerr << "Unhandled type for FDiv instruction: " << *Ty << "\n"; abort(); } - return Dest; } -static GenericValue executeURemInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; - IMPLEMENT_UNSIGNED_BINOP(%, Ty) - return Dest; +static void executeURemInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { + IMPLEMENT_UNSIGNED_BINOP(%,Ty,urem) } -static GenericValue executeSRemInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; - IMPLEMENT_SIGNED_BINOP(%, Ty) - return Dest; +static void executeSRemInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { + IMPLEMENT_SIGNED_BINOP(%,Ty,srem) } -static GenericValue executeFRemInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; +static void executeFRemInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { switch (Ty->getTypeID()) { case Type::FloatTyID: Dest.FloatVal = fmod(Src1.FloatVal, Src2.FloatVal); @@ -368,28 +225,21 @@ static GenericValue executeFRemInst(GenericValue Src1, GenericValue Src2, cerr << "Unhandled type for Rem instruction: " << *Ty << "\n"; abort(); } - return Dest; } -static GenericValue executeAndInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; - IMPLEMENT_UNSIGNED_BINOP(&, Ty) - return Dest; +static void executeAndInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { + IMPLEMENT_UNSIGNED_BINOP(&,Ty,And) } -static GenericValue executeOrInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; - IMPLEMENT_UNSIGNED_BINOP(|, Ty) - return Dest; +static void executeOrInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { + IMPLEMENT_UNSIGNED_BINOP(|,Ty,Or) } -static GenericValue executeXorInst(GenericValue Src1, GenericValue Src2, - const Type *Ty) { - GenericValue Dest; - IMPLEMENT_UNSIGNED_BINOP(^, Ty) - return Dest; +static void executeXorInst(GenericValue &Dest, GenericValue Src1, + GenericValue Src2, const Type *Ty) { + IMPLEMENT_UNSIGNED_BINOP(^,Ty,Xor) } #define IMPLEMENT_SIGNED_ICMP(OP, TY) \ @@ -845,20 +695,21 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) { GenericValue Src1 = getOperandValue(I.getOperand(0), SF); GenericValue Src2 = getOperandValue(I.getOperand(1), SF); GenericValue R; // Result + initializeAPInt(R, Ty, SF); switch (I.getOpcode()) { - case Instruction::Add: R = executeAddInst (Src1, Src2, Ty); break; - case Instruction::Sub: R = executeSubInst (Src1, Src2, Ty); break; - case Instruction::Mul: R = executeMulInst (Src1, Src2, Ty); break; - case Instruction::UDiv: R = executeUDivInst (Src1, Src2, Ty); break; - case Instruction::SDiv: R = executeSDivInst (Src1, Src2, Ty); break; - case Instruction::FDiv: R = executeFDivInst (Src1, Src2, Ty); break; - case Instruction::URem: R = executeURemInst (Src1, Src2, Ty); break; - case Instruction::SRem: R = executeSRemInst (Src1, Src2, Ty); break; - case Instruction::FRem: R = executeFRemInst (Src1, Src2, Ty); break; - case Instruction::And: R = executeAndInst (Src1, Src2, Ty); break; - case Instruction::Or: R = executeOrInst (Src1, Src2, Ty); break; - case Instruction::Xor: R = executeXorInst (Src1, Src2, Ty); break; + 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::UDiv: executeUDivInst (R, Src1, Src2, Ty); break; + case Instruction::SDiv: executeSDivInst (R, Src1, Src2, Ty); break; + case Instruction::FDiv: executeFDivInst (R, Src1, Src2, Ty); break; + case Instruction::URem: executeURemInst (R, Src1, Src2, Ty); break; + case Instruction::SRem: executeSRemInst (R, Src1, Src2, Ty); break; + case Instruction::FRem: executeFRemInst (R, Src1, Src2, Ty); break; + case Instruction::And: executeAndInst (R, Src1, Src2, Ty); break; + case Instruction::Or: executeOrInst (R, Src1, Src2, Ty); break; + case Instruction::Xor: executeXorInst (R, Src1, Src2, Ty); break; default: cerr << "Don't know how to handle this binary operator!\n-->" << I; abort(); @@ -877,7 +728,9 @@ void Interpreter::visitSelectInst(SelectInst &I) { 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); + GenericValue R; + initializeAPInt(R, I.getOperand(1)->getType(), SF); + R = executeSelectInst(Src1, Src2, Src3); SetValue(&I, R, SF); } @@ -1328,22 +1181,30 @@ GenericValue Interpreter::executeTruncInst(Value *SrcVal, const Type *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"); + if (DBitWidth > 64) { + // Both values are APInt, just use the APInt trunc + initializeAPInt(Dest, DstTy, SF); + *(Dest.APIntVal) = Src.APIntVal->trunc(DBitWidth); + return Dest; + } + + uint64_t MaskedVal = 0; + uint64_t Mask = (1ULL << DBitWidth) - 1; + // 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 + else if (SBitWidth <= 64) MaskedVal = Src.Int64Val & Mask; + else + MaskedVal = Src.APIntVal->trunc(DBitWidth).getZExtValue(); INTEGER_ASSIGN(Dest, DBitWidth, MaskedVal); return Dest; @@ -1708,6 +1569,131 @@ void Interpreter::visitVAArgInst(VAArgInst &I) { ++VAList.UIntPairVal.second; } +GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE, + ExecutionContext &SF) { + switch (CE->getOpcode()) { + 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 executeBitCastInst(CE->getOperand(0), CE->getType(), SF); + case Instruction::GetElementPtr: + return executeGEPOperation(CE->getOperand(0), gep_type_begin(CE), + gep_type_end(CE), SF); + default : + break; + } + GenericValue Dest; + initializeAPInt(Dest, CE->getType(), SF); + switch (CE->getOpcode()) { + case Instruction::Add: + executeAddInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::Sub: + executeSubInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::Mul: + executeMulInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::SDiv: + executeSDivInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::UDiv: + executeUDivInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::FDiv: + executeFDivInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::URem: + executeURemInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::SRem: + executeSRemInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::FRem: + executeFRemInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::And: + executeAndInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::Or: + executeOrInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::Xor: + executeXorInst(Dest, getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::FCmp: + case Instruction::ICmp: + return executeCmpInst(CE->getPredicate(), + 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::LShr: + return executeLShrInst(getOperandValue(CE->getOperand(0), SF), + getOperandValue(CE->getOperand(1), SF), + CE->getOperand(0)->getType()); + case Instruction::AShr: + return executeAShrInst(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: + cerr << "Unhandled ConstantExpr: " << *CE << "\n"; + abort(); + return GenericValue(); + } +} + +GenericValue Interpreter::getOperandValue(Value *V, ExecutionContext &SF) { + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { + return getConstantExprValue(CE, SF); + } else if (Constant *CPV = dyn_cast<Constant>(V)) { + return getConstantValue(CPV); + } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) { + return PTOGV(getPointerToGlobal(GV)); + } else { + return SF.Values[V]; + } +} + //===----------------------------------------------------------------------===// // Dispatch and Execution Code //===----------------------------------------------------------------------===// |