diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2007-01-20 20:12:29 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2007-01-20 20:12:29 +0000 |
commit | a42c7fd0ca5f2d6f653e3a9bac13ae176861a823 (patch) | |
tree | 714c7089076895a722ebece9e3d3fce722f6e38f /lib/ExecutionEngine/Interpreter | |
parent | 515674c7b66a411db4ea2fa1f5c30cd1461d3e51 (diff) | |
download | external_llvm-a42c7fd0ca5f2d6f653e3a9bac13ae176861a823.zip external_llvm-a42c7fd0ca5f2d6f653e3a9bac13ae176861a823.tar.gz external_llvm-a42c7fd0ca5f2d6f653e3a9bac13ae176861a823.tar.bz2 |
Implement the signed icmp instructions properly. To do this we introduce
a small inline function to sign extend a uint64_t value based on its
type's bitwidth. This function is then used in both executeSExtInst and
the various executeICMP_S** functions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33403 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine/Interpreter')
-rw-r--r-- | lib/ExecutionEngine/Interpreter/Execution.cpp | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 91c7c57..41d7aad 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -67,6 +67,15 @@ static GenericValue executeAShrInst(GenericValue Src1, GenericValue Src2, static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2, GenericValue Src3); +inline uint64_t doSignExtension(uint64_t Val, const IntegerType* ITy) { + // Determine if the value is signed or not + bool isSigned = (Val & (1 << (ITy->getBitWidth()-1))) != 0; + // If its signed, extend the sign bits + if (isSigned) + Val |= ~ITy->getBitMask(); + return Val; +} + GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE, ExecutionContext &SF) { switch (CE->getOpcode()) { @@ -385,22 +394,26 @@ static GenericValue executeXorInst(GenericValue Src1, GenericValue Src2, #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 { \ + const IntegerType* ITy = cast<IntegerType>(TY); \ + unsigned BitWidth = ITy->getBitWidth(); \ + int64_t LHS = 0, RHS = 0; \ + if (BitWidth <= 8) { \ + LHS = int64_t(doSignExtension(uint64_t(Src1.Int8Val), ITy)); \ + RHS = int64_t(doSignExtension(uint64_t(Src2.Int8Val), ITy)); \ + } else if (BitWidth <= 16) { \ + LHS = int64_t(doSignExtension(uint64_t(Src1.Int16Val), ITy)); \ + RHS = int64_t(doSignExtension(uint64_t(Src2.Int16Val), ITy)); \ + } else if (BitWidth <= 32) { \ + LHS = int64_t(doSignExtension(uint64_t(Src1.Int32Val), ITy)); \ + RHS = int64_t(doSignExtension(uint64_t(Src2.Int32Val), ITy)); \ + } else if (BitWidth <= 64) { \ + LHS = int64_t(doSignExtension(uint64_t(Src1.Int64Val), ITy)); \ + RHS = int64_t(doSignExtension(uint64_t(Src2.Int64Val), ITy)); \ + } else { \ cerr << "Integer types > 64 bits not supported: " << *Ty << "\n"; \ abort(); \ } \ - maskToBitWidth(Dest, BitWidth); \ + Dest.Int1Val = LHS OP RHS; \ break; \ } @@ -1359,10 +1372,7 @@ GenericValue Interpreter::executeSExtInst(Value *SrcVal, const Type *DstTy, else Normalized = Src.Int64Val; - // Now do the bit-accurate sign extension manually. - bool isSigned = (Normalized & (1 << (SBitWidth-1))) != 0; - if (isSigned) - Normalized |= ~SITy->getBitMask(); + Normalized = doSignExtension(Normalized, SITy); // Now that we have a sign extended value, assign it to the destination INTEGER_ASSIGN(Dest, DBitWidth, Normalized); |