Revise previous patch per review comments.
[oota-llvm.git] / lib / Target / CBackend / CBackend.cpp
index cbf480e8550a177ebe873088b86d03941e80023c..9fc30c45da1405e9d9e0e0e5632fa18c3bbd5e5a 100644 (file)
@@ -57,7 +57,7 @@ namespace {
   ///
   class CBackendNameAllUsedStructsAndMergeFunctions : public ModulePass {
   public:
-    static const int ID;
+    static char ID;
     CBackendNameAllUsedStructsAndMergeFunctions() 
       : ModulePass((intptr_t)&ID) {}
     void getAnalysisUsage(AnalysisUsage &AU) const {
@@ -71,7 +71,7 @@ namespace {
     virtual bool runOnModule(Module &M);
   };
 
-  const int CBackendNameAllUsedStructsAndMergeFunctions::ID = 0;
+  char CBackendNameAllUsedStructsAndMergeFunctions::ID = 0;
 
   /// CWriter - This class is the main chunk of code that converts an LLVM
   /// module to a C translation unit.
@@ -88,7 +88,7 @@ namespace {
     std::set<Function*> intrinsicPrototypesAlreadyGenerated;
 
   public:
-    static const int ID;
+    static char ID;
     CWriter(std::ostream &o) 
       : FunctionPass((intptr_t)&ID), Out(o), IL(0), Mang(0), LI(0), 
         TheModule(0), TAsm(0), TD(0) {}
@@ -264,7 +264,7 @@ namespace {
   };
 }
 
-const int CWriter::ID = 0;
+char CWriter::ID = 0;
 
 /// This method inserts names for any unnamed structure types that are used by
 /// the program, and removes names from structure types that are not used by the
@@ -412,29 +412,6 @@ CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned,
   }
 }
 
-#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.
 //
@@ -489,7 +466,10 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
       printType(Out, *I, false, "field" + utostr(Idx++));
       Out << ";\n";
     }
-    return Out << '}';
+    Out << '}';
+    if (STy->isPacked())
+      Out << " __attribute__ ((packed))";
+    return Out;
   }
 
   case Type::PointerTyID: {
@@ -624,17 +604,19 @@ void CWriter::printConstantVector(ConstantVector *CP) {
 // only deal in IEEE FP).
 //
 static bool isFPCSafeToPrint(const ConstantFP *CFP) {
+  APFloat APF = APFloat(CFP->getValueAPF());  // copy
+  if (CFP->getType()==Type::FloatTy)
+    APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven);
 #if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A
   char Buffer[100];
-  sprintf(Buffer, "%a", CFP->getValue());
-
+  sprintf(Buffer, "%a", APF.convertToDouble());
   if (!strncmp(Buffer, "0x", 2) ||
       !strncmp(Buffer, "-0x", 3) ||
       !strncmp(Buffer, "+0x", 3))
-    return atof(Buffer) == CFP->getValue();
+    return APF.bitwiseIsEqual(APFloat(atof(Buffer)));
   return false;
 #else
-  std::string StrVal = ftostr(CFP->getValue());
+  std::string StrVal = ftostr(APF);
 
   while (StrVal[0] == ' ')
     StrVal.erase(StrVal.begin());
@@ -645,7 +627,7 @@ static bool isFPCSafeToPrint(const ConstantFP *CFP) {
       ((StrVal[0] == '-' || StrVal[0] == '+') &&
        (StrVal[1] >= '0' && StrVal[1] <= '9')))
     // Reparse stringized version!
-    return atof(StrVal.c_str()) == CFP->getValue();
+    return APF.bitwiseIsEqual(APFloat(atof(StrVal.c_str())));
   return false;
 #endif
 }
@@ -734,39 +716,23 @@ void CWriter::printConstant(Constant *CPV) {
     case Instruction::BitCast:
       Out << "(";
       printCast(CE->getOpcode(), CE->getOperand(0)->getType(), CE->getType());
-       if (CE->getOpcode() == Instruction::Trunc ||
-           CE->getOpcode() == Instruction::FPToUI ||
-           CE->getOpcode() == Instruction::FPToSI ||
-           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");
-        }
-      }
-      else if (CE->getOpcode() == Instruction::SExt &&
-               CE->getOperand(0)->getType() == Type::Int1Ty) {
+      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 << ")";
+      printConstant(CE->getOperand(0));
+      if (CE->getType() == Type::Int1Ty &&
+          (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";
+      }
+      Out << ')';
       return;
+
     case Instruction::GetElementPtr:
       Out << "(&(";
       printIndexingExpression(CE->getOperand(0), gep_type_begin(CPV),
@@ -918,9 +884,13 @@ void CWriter::printConstant(Constant *CPV) {
       Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double")
           << "*)&FPConstant" << I->second << ')';
     } else {
-      if (IsNAN(FPC->getValue())) {
+      double V = FPC->getType() == Type::FloatTy ? 
+                 FPC->getValueAPF().convertToFloat() : 
+                 FPC->getValueAPF().convertToDouble();
+      if (IsNAN(V)) {
         // The value is NaN
 
+        // FIXME the actual NaN bits should be emitted.
         // The prefix for a quiet NaN is 0x7FF8. For a signalling NaN,
         // it's 0x7ff4.
         const unsigned long QuietNaN = 0x7ff8UL;
@@ -929,7 +899,7 @@ void CWriter::printConstant(Constant *CPV) {
         // We need to grab the first part of the FP #
         char Buffer[100];
 
-        uint64_t ll = DoubleToBits(FPC->getValue());
+        uint64_t ll = DoubleToBits(V);
         sprintf(Buffer, "0x%llx", static_cast<long long>(ll));
 
         std::string Num(&Buffer[0], &Buffer[6]);
@@ -941,9 +911,9 @@ void CWriter::printConstant(Constant *CPV) {
         else
           Out << "LLVM_NAN" << (Val == QuietNaN ? "" : "S") << "(\""
               << Buffer << "\") /*nan*/ ";
-      } else if (IsInf(FPC->getValue())) {
+      } else if (IsInf(V)) {
         // The value is Inf
-        if (FPC->getValue() < 0) Out << '-';
+        if (V < 0) Out << '-';
         Out << "LLVM_INF" << (FPC->getType() == Type::FloatTy ? "F" : "")
             << " /*inf*/ ";
       } else {
@@ -951,12 +921,12 @@ void CWriter::printConstant(Constant *CPV) {
 #if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A
         // Print out the constant as a floating point number.
         char Buffer[100];
-        sprintf(Buffer, "%a", FPC->getValue());
+        sprintf(Buffer, "%a", V);
         Num = Buffer;
 #else
-        Num = ftostr(FPC->getValue());
+        Num = ftostr(FPC->getValueAPF());
 #endif
-        Out << Num;
+       Out << Num;
       }
     }
     break;
@@ -1267,11 +1237,7 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
     Out << "((";
     printSimpleType(Out, OpTy, castIsSigned);
     Out << ")";
-    if (castIsSigned && OpTy->getTypeID() == Type::IntegerTyID) {
-      IMPL_SIGN_EXTENSION(OpTy, writeOperand(Operand));
-    }
-    else
-      writeOperand(Operand);
+    writeOperand(Operand);
     Out << ")";
   } else 
     writeOperand(Operand);
@@ -1296,9 +1262,7 @@ void CWriter::writeOperandWithCast(Value* Operand, ICmpInst::Predicate predicate
   switch (predicate) {
     default:
       // for eq and ne, it doesn't matter
-      break;
-    case ICmpInst::ICMP_EQ:
-    case ICmpInst::ICMP_NE:
+      break; 
     case ICmpInst::ICMP_UGT:
     case ICmpInst::ICMP_UGE:
     case ICmpInst::ICMP_ULT:
@@ -1323,25 +1287,10 @@ void CWriter::writeOperandWithCast(Value* Operand, ICmpInst::Predicate predicate
     else
       printType(Out, OpTy); // not integer, sign doesn't matter
     Out << ")";
-    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");
-      }
-    }
+    writeOperand(Operand);
     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
@@ -1458,19 +1407,14 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
       << "#define __ATTRIBUTE_DTOR__\n"
       << "#define LLVM_ASM(X)\n"
       << "#endif\n\n";
+  
+  Out << "#if __GNUC__ < 4 /* Old GCC's, or compilers not GCC */ \n"
+      << "#define __builtin_stack_save() 0   /* not implemented */\n"
+      << "#define __builtin_stack_restore(X) /* noop */\n"
+      << "#endif\n\n";
 
   // Output target-specific code that should be inserted into main.
   Out << "#define CODE_FOR_MAIN() /* Any target-specific code for main()*/\n";
-  // On X86, set the FP control word to 64-bits of precision instead of 80 bits.
-  Out << "#if defined(__GNUC__) && !defined(__llvm__)\n"
-      << "#if defined(i386) || defined(__i386__) || defined(__i386) || "
-      << "defined(__x86_64__)\n"
-      << "#undef CODE_FOR_MAIN\n"
-      << "#define CODE_FOR_MAIN() \\\n"
-      << "  {short F;__asm__ (\"fnstcw %0\" : \"=m\" (*&F)); \\\n"
-      << "  F=(F&~0x300)|0x200;__asm__(\"fldcw %0\"::\"m\"(*&F));}\n"
-      << "#endif\n#endif\n";
-
 }
 
 /// FindStaticTors - Given a static ctor/dtor list, unpack its contents into
@@ -1767,17 +1711,20 @@ void CWriter::printFloatingPointConstants(Function &F) {
     if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I))
       if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe.
           !FPConstantMap.count(FPC)) {
-        double Val = FPC->getValue();
-
         FPConstantMap[FPC] = FPCounter;  // Number the FP constants
 
         if (FPC->getType() == Type::DoubleTy) {
+          double Val = FPC->getValueAPF().convertToDouble();
+          uint64_t i = FPC->getValueAPF().convertToAPInt().getZExtValue();
           Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
-              << " = 0x" << std::hex << DoubleToBits(Val) << std::dec
+              << " = 0x" << std::hex << i << std::dec
               << "ULL;    /* " << Val << " */\n";
         } else if (FPC->getType() == Type::FloatTy) {
+          float Val = FPC->getValueAPF().convertToFloat();
+          uint32_t i = (uint32_t)FPC->getValueAPF().convertToAPInt().
+                                    getZExtValue();
           Out << "static const ConstantFloatTy FPConstant" << FPCounter++
-              << " = 0x" << std::hex << FloatToBits(Val) << std::dec
+              << " = 0x" << std::hex << i << std::dec
               << "U;    /* " << Val << " */\n";
         } else
           assert(0 && "Unknown float type!");
@@ -2406,33 +2353,21 @@ void CWriter::visitCastInst(CastInst &I) {
         << getFloatBitCastField(I.getType());
   } else {
     printCast(I.getOpcode(), SrcTy, DstTy);
-    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) {
+    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");
     }
-    else
-      writeOperand(I.getOperand(0));
+    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";
+    }
   }
-  Out << ")";
+  Out << ')';
 }
 
 void CWriter::visitSelectInst(SelectInst &I) {