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

Reid Spencer reid at x10sys.com
Mon Dec 11 12:39:30 PST 2006



Changes in directory llvm/lib/Target/CBackend:

Writer.cpp updated: 1.295 -> 1.296
---
Log message:

Implement correct bitcast of int<->float and long<->double by using a
union to perform the bitcast. 


---
Diffs of the changes:  (+58 -14)

 Writer.cpp |   72 +++++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 58 insertions(+), 14 deletions(-)


Index: llvm/lib/Target/CBackend/Writer.cpp
diff -u llvm/lib/Target/CBackend/Writer.cpp:1.295 llvm/lib/Target/CBackend/Writer.cpp:1.296
--- llvm/lib/Target/CBackend/Writer.cpp:1.295	Sun Dec 10 17:12:42 2006
+++ llvm/lib/Target/CBackend/Writer.cpp	Mon Dec 11 14:39:15 2006
@@ -169,7 +169,7 @@
       // Must not be used in inline asm
       if (I.hasOneUse() && isInlineAsm(*I.use_back())) return false;
 
-      // Only inline instruction it it's use is in the same BB as the inst.
+      // Only inline instruction it if it's use is in the same BB as the inst.
       return I.getParent() == cast<Instruction>(I.use_back())->getParent();
     }
 
@@ -1508,6 +1508,16 @@
 /// type name is found, emit its declaration...
 ///
 void CWriter::printModuleTypes(const SymbolTable &ST) {
+  Out << "/* Helper union for bitcasts */\n";
+  Out << "typedef union {\n";
+  Out << "  unsigned int  UInt;\n";
+  Out << "    signed int  SInt;\n";
+  Out << "  unsigned long ULong;\n";
+  Out << "    signed long SLong;\n";
+  Out << "          float Float;\n";
+  Out << "         double Double;\n";
+  Out << "} llvmBitCastUnion;\n";
+
   // We are only interested in the type plane of the symbol table.
   SymbolTable::type_const_iterator I   = ST.type_begin();
   SymbolTable::type_const_iterator End = ST.type_end();
@@ -1704,6 +1714,15 @@
         Out << ";\n";
       }
       PrintedVar = true;
+    } else if (isa<BitCastInst>(*I) && 
+               ((I->getType()->isFloatingPoint() && 
+                 I->getOperand(0)->getType()->isInteger()) ||
+                (I->getType()->isInteger() && 
+                 I->getOperand(0)->getType()->isFloatingPoint()))) {
+      // We need a temporary for the BitCast to use so it can pluck a 
+      // value out of a union to do the BitCast.
+      Out << "  llvmBitCastUnion " << Mang->getValueName(&*I)
+          << "__BITCAST_TEMPORARY;\n";
     }
 
   if (PrintedVar)
@@ -1986,23 +2005,48 @@
   }
 }
 
+static const char * getFloatBitCastField(const Type *Ty) {
+  switch (Ty->getTypeID()) {
+    default: assert(0 && "Invalid Type");
+    case Type::FloatTyID: return "Float";
+    case Type::UIntTyID:  return "UInt";
+    case Type::IntTyID:   return "SInt";
+    case Type::DoubleTyID:return "Double";
+    case Type::ULongTyID: return "ULong";
+    case Type::LongTyID:  return "SLong";
+  }
+}
+
 void CWriter::visitCastInst(CastInst &I) {
   const Type *DstTy = I.getType();
   const Type *SrcTy = I.getOperand(0)->getType();
   Out << '(';
-  printCast(I.getOpcode(), SrcTy, DstTy);
-  if (I.getOpcode() == Instruction::SExt && SrcTy == Type::BoolTy) {
-    // Make sure we really get a sext from bool by subtracing the bool from 0
-    Out << "0-";
-  }
-  writeOperand(I.getOperand(0));
-  if (DstTy == Type::BoolTy && 
-      (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";
+  if (isa<BitCastInst>(I) &&
+      ((I.getType()->isFloatingPoint() && 
+        I.getOperand(0)->getType()->isInteger()) ||
+       (I.getType()->isInteger() && 
+        I.getOperand(0)->getType()->isFloatingPoint()))) {
+    // These int<->float and long<->double casts need to be handled specially
+    Out << Mang->getValueName(&I) << "__BITCAST_TEMPORARY." 
+        << getFloatBitCastField(I.getOperand(0)->getType()) << " = ";
+    writeOperand(I.getOperand(0));
+    Out << ", " << Mang->getValueName(&I) << "__BITCAST_TEMPORARY."
+        << getFloatBitCastField(I.getType());
+  } else {
+    printCast(I.getOpcode(), SrcTy, DstTy);
+    if (I.getOpcode() == Instruction::SExt && SrcTy == Type::BoolTy) {
+      // Make sure we really get a sext from bool by subtracing the bool from 0
+      Out << "0-";
+    }
+    writeOperand(I.getOperand(0));
+    if (DstTy == Type::BoolTy && 
+        (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";
+    }
   }
   Out << ')';
 }






More information about the llvm-commits mailing list