diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2007-01-20 08:32:52 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2007-01-20 08:32:52 +0000 |
commit | c00a43092ed960cdb28f4f3f00606f572869848d (patch) | |
tree | 2443e23dc4a9b2c05d7c3ba2e8e10666d004a6f2 /lib/ExecutionEngine/Interpreter/Execution.cpp | |
parent | 6df4c4576f3bc47a547d400effd4c59653ffe592 (diff) |
Implement bit-accurate sext instruction.
This patch fixes test/Integer/2007-01-17-TruncSext.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33394 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine/Interpreter/Execution.cpp')
-rw-r--r-- | lib/ExecutionEngine/Interpreter/Execution.cpp | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 61624f3dc9..91c7c57f95 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -1347,21 +1347,25 @@ GenericValue Interpreter::executeSExtInst(Value *SrcVal, const Type *DstTy, 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; + + // Normalize to a 64-bit value. + uint64_t Normalized = 0; + if (SBitWidth <= 8) + Normalized = Src.Int8Val; else if (SBitWidth <= 16) - Extended = (int64_t) (int16_t)Src.Int16Val; + Normalized = Src.Int16Val; else if (SBitWidth <= 32) - Extended = (int64_t) (int32_t)Src.Int32Val; + Normalized = Src.Int32Val; else - Extended = (int64_t) Src.Int64Val; + Normalized = Src.Int64Val; + + // Now do the bit-accurate sign extension manually. + bool isSigned = (Normalized & (1 << (SBitWidth-1))) != 0; + if (isSigned) + Normalized |= ~SITy->getBitMask(); // Now that we have a sign extended value, assign it to the destination - INTEGER_ASSIGN(Dest, DBitWidth, Extended); + INTEGER_ASSIGN(Dest, DBitWidth, Normalized); return Dest; } |