OSDN Git Service

Implement the signed icmp instructions properly. To do this we introduce
authorReid Spencer <rspencer@reidspencer.com>
Sat, 20 Jan 2007 20:12:29 +0000 (20:12 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Sat, 20 Jan 2007 20:12:29 +0000 (20:12 +0000)
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

lib/ExecutionEngine/Interpreter/Execution.cpp

index 91c7c57..41d7aad 100644 (file)
@@ -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);