[llvm-commits] CVS: llvm/lib/Target/CBackend/CBackend.cpp

Reid Spencer reid at x10sys.com
Tue May 1 19:17:59 PDT 2007



Changes in directory llvm/lib/Target/CBackend:

CBackend.cpp updated: 1.339 -> 1.340
---
Log message:

Make sign extension work correctly for unusual bit widths.


---
Diffs of the changes:  (+100 -28)

 CBackend.cpp |  128 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 100 insertions(+), 28 deletions(-)


Index: llvm/lib/Target/CBackend/CBackend.cpp
diff -u llvm/lib/Target/CBackend/CBackend.cpp:1.339 llvm/lib/Target/CBackend/CBackend.cpp:1.340
--- llvm/lib/Target/CBackend/CBackend.cpp:1.339	Tue May  1 16:15:46 2007
+++ llvm/lib/Target/CBackend/CBackend.cpp	Tue May  1 21:17:41 2007
@@ -412,6 +412,29 @@
   }
 }
 
+#define IMPL_SIGN_EXTENSION(OpTy, Func) { \
+      const IntegerType* IntTy = cast<IntegerType>(OpTy); \
+      unsigned BitWidth = IntTy->getBitWidth(); \
+      if (BitWidth != 8 && BitWidth != 16 && BitWidth != 32 && \
+          BitWidth != 64 && BitWidth != 128) { \
+        const char * Suffix; \
+        if (BitWidth <=32)\
+          Suffix = "U"; \
+        else \
+          Suffix = "ULL"; \
+        Out << "("; \
+        Func; \
+        Out << " & (1" << Suffix << " << " << BitWidth - 1 << " ) ? "; \
+        Func; \
+        Out << " | " << (~IntTy->getBitMask()) << Suffix << " : "; \
+        Func; \
+        Out << " & " << IntTy->getBitMask() << Suffix; \
+        Out << ")";\
+       } \
+      else \
+        Func; \
+      }
+
 // Pass the Type* and the variable name and this prints out the variable
 // declaration.
 //
@@ -711,23 +734,39 @@
     case Instruction::BitCast:
       Out << "(";
       printCast(CE->getOpcode(), CE->getOperand(0)->getType(), CE->getType());
-      if (CE->getOpcode() == Instruction::SExt &&
-          CE->getOperand(0)->getType() == Type::Int1Ty) {
-        // Make sure we really sext from bool here by subtracting from 0
-        Out << "0-";
-      }
-      printConstant(CE->getOperand(0));
-      if (CE->getType() == Type::Int1Ty &&
-          (CE->getOpcode() == Instruction::Trunc ||
+       if (CE->getOpcode() == Instruction::Trunc ||
            CE->getOpcode() == Instruction::FPToUI ||
            CE->getOpcode() == Instruction::FPToSI ||
-           CE->getOpcode() == Instruction::PtrToInt)) {
-        // Make sure we really truncate to bool here by anding with 1
-        Out << "&1u";
+           CE->getOpcode() == Instruction::PtrToInt) {
+        if (const IntegerType* IntTy = dyn_cast<IntegerType>(CE->getType())) {
+          uint64_t BitMask = IntTy->getBitMask();
+          printConstant(CE->getOperand(0));
+          Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
+        }
       }
-      Out << ')';
+      else if (CE->getOpcode() == Instruction::SExt &&
+               CE->getOperand(0)->getType() == Type::Int1Ty) {
+        // Make sure we really sext from bool here by subtracting from 0
+        Out << "0-";
+        printConstant(CE->getOperand(0));
+      }
+      else if (CE->getOpcode() == Instruction::SExt &&
+               CE->getOperand(0)->getType()->getTypeID() == Type::IntegerTyID) {
+         IMPL_SIGN_EXTENSION(CE->getOperand(0)->getType(),
+                             printConstant(CE->getOperand(0)));
+       }
+       else if (CE->getOpcode() == Instruction::ZExt &&
+                CE->getOperand(0)->getType()->getTypeID() == Type::IntegerTyID){
+         const IntegerType* IntTy = 
+           cast<IntegerType>(CE->getOperand(0)->getType());
+         uint64_t BitMask = IntTy->getBitMask();
+         writeOperand(CE->getOperand(0));
+         Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
+       }
+       else
+         printConstant(CE->getOperand(0));
+      Out << ")";
       return;
-
     case Instruction::GetElementPtr:
       Out << "(&(";
       printIndexingExpression(CE->getOperand(0), gep_type_begin(CPV),
@@ -1228,7 +1267,11 @@
     Out << "((";
     printSimpleType(Out, OpTy, castIsSigned);
     Out << ")";
-    writeOperand(Operand);
+    if (castIsSigned && OpTy->getTypeID() == Type::IntegerTyID) {
+      IMPL_SIGN_EXTENSION(OpTy, writeOperand(Operand));
+    }
+    else
+      writeOperand(Operand);
     Out << ")";
   } else 
     writeOperand(Operand);
@@ -1253,7 +1296,9 @@
   switch (predicate) {
     default:
       // for eq and ne, it doesn't matter
-      break; 
+      break;
+    case ICmpInst::ICMP_EQ:
+    case ICmpInst::ICMP_NE:
     case ICmpInst::ICMP_UGT:
     case ICmpInst::ICMP_UGE:
     case ICmpInst::ICMP_ULT:
@@ -1278,10 +1323,25 @@
     else
       printType(Out, OpTy); // not integer, sign doesn't matter
     Out << ")";
-    writeOperand(Operand);
+    if(castIsSigned && OpTy->getTypeID() == Type::IntegerTyID) {
+      IMPL_SIGN_EXTENSION(OpTy, writeOperand(Operand));
+    } else {
+      writeOperand(Operand);
+      if(OpTy->getTypeID() == Type::IntegerTyID){
+        const IntegerType * IntTy = cast<IntegerType>(OpTy);
+        uint64_t BitMask = IntTy->getBitMask();
+        Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
+      }
+    }
     Out << ")";
-  } else 
+  } else {
     writeOperand(Operand);
+    if(OpTy->getTypeID() == Type::IntegerTyID){
+      const IntegerType * IntTy = cast<IntegerType>(OpTy);
+      uint64_t BitMask = IntTy->getBitMask();
+      Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
+    }
+  }
 }
 
 // generateCompilerSpecificCode - This is where we add conditional compilation
@@ -2346,21 +2406,33 @@
         << getFloatBitCastField(I.getType());
   } else {
     printCast(I.getOpcode(), SrcTy, DstTy);
-    if (I.getOpcode() == Instruction::SExt && SrcTy == Type::Int1Ty) {
+    if (I.getOpcode() == Instruction::Trunc ||
+        I.getOpcode() == Instruction::FPToUI ||
+        I.getOpcode() == Instruction::FPToSI ||
+        I.getOpcode() == Instruction::PtrToInt) {
+      if (const IntegerType* IntTy = dyn_cast<IntegerType>(DstTy)){
+        uint64_t BitMask = IntTy->getBitMask();
+        writeOperand(I.getOperand(0));
+        Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
+      }
+    } else if (I.getOpcode() == Instruction::SExt && SrcTy == Type::Int1Ty) {
       // Make sure we really get a sext from bool by subtracing the bool from 0
       Out << "0-";
+      writeOperand(I.getOperand(0));
+    } else if (I.getOpcode() == Instruction::SExt &&
+               SrcTy->getTypeID() == Type::IntegerTyID) {
+      IMPL_SIGN_EXTENSION(SrcTy, writeOperand(I.getOperand(0)) );
+    } else if (I.getOpcode() == Instruction::ZExt &&
+               SrcTy->getTypeID() == Type::IntegerTyID) {
+      const IntegerType* IntTy = cast<IntegerType>(SrcTy);
+      uint64_t BitMask = IntTy->getBitMask();
+      writeOperand(I.getOperand(0));
+      Out << "&" << BitMask << (IntTy->getBitWidth() <=32 ? "U": "ULL");
     }
-    writeOperand(I.getOperand(0));
-    if (DstTy == Type::Int1Ty && 
-        (I.getOpcode() == Instruction::Trunc ||
-         I.getOpcode() == Instruction::FPToUI ||
-         I.getOpcode() == Instruction::FPToSI ||
-         I.getOpcode() == Instruction::PtrToInt)) {
-      // Make sure we really get a trunc to bool by anding the operand with 1 
-      Out << "&1u";
-    }
+    else
+      writeOperand(I.getOperand(0));
   }
-  Out << ')';
+  Out << ")";
 }
 
 void CWriter::visitSelectInst(SelectInst &I) {






More information about the llvm-commits mailing list