summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2007-01-20 20:12:29 +0000
committerReid Spencer <rspencer@reidspencer.com>2007-01-20 20:12:29 +0000
commita42c7fd0ca5f2d6f653e3a9bac13ae176861a823 (patch)
tree714c7089076895a722ebece9e3d3fce722f6e38f
parent515674c7b66a411db4ea2fa1f5c30cd1461d3e51 (diff)
downloadllvm-a42c7fd0ca5f2d6f653e3a9bac13ae176861a823.tar.gz
llvm-a42c7fd0ca5f2d6f653e3a9bac13ae176861a823.tar.bz2
llvm-a42c7fd0ca5f2d6f653e3a9bac13ae176861a823.tar.xz
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
-rw-r--r--lib/ExecutionEngine/Interpreter/Execution.cpp44
1 files changed, 27 insertions, 17 deletions
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp
index 91c7c57f95..41d7aad826 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);