For PR411:
[oota-llvm.git] / lib / Target / CBackend / CBackend.cpp
index 13fd574e0cd624fab3fe5877f279887df12702c0..ffa3b1ec3f7c459776471a7c084510ad7325087e 100644 (file)
@@ -1,4 +1,4 @@
-//===-- Writer.cpp - Library for converting LLVM code to C ----------------===//
+//===-- CBackend.cpp - Library for converting LLVM code to C --------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -20,7 +20,7 @@
 #include "llvm/Instructions.h"
 #include "llvm/Pass.h"
 #include "llvm/PassManager.h"
-#include "llvm/SymbolTable.h"
+#include "llvm/TypeSymbolTable.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/IntrinsicInst.h"
 #include "llvm/InlineAsm.h"
@@ -31,6 +31,7 @@
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Target/TargetMachineRegistry.h"
 #include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetData.h"
 #include "llvm/Support/CallSite.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
@@ -69,16 +70,18 @@ namespace {
   /// module to a C translation unit.
   class CWriter : public FunctionPass, public InstVisitor<CWriter> {
     std::ostream &Out;
-    IntrinsicLowering IL;
+    IntrinsicLowering *IL;
     Mangler *Mang;
     LoopInfo *LI;
     const Module *TheModule;
     const TargetAsmInfo* TAsm;
+    const TargetData* TD;
     std::map<const Type *, std::string> TypeNames;
 
     std::map<const ConstantFP *, unsigned> FPConstantMap;
   public:
-    CWriter(std::ostream &o) : Out(o), TAsm(0) {}
+    CWriter(std::ostream &o) : Out(o), IL(0), Mang(0), LI(0), TheModule(0), 
+                               TAsm(0), TD(0) {}
 
     virtual const char *getPassName() const { return "C backend"; }
 
@@ -98,9 +101,6 @@ namespace {
       // Output all floating point constants that cannot be printed accurately.
       printFloatingPointConstants(F);
 
-      // Ensure that no local symbols conflict with global symbols.
-      F.renameLocalSymbols();
-
       printFunction(F);
       FPConstantMap.clear();
       return false;
@@ -113,9 +113,13 @@ namespace {
       return false;
     }
 
-    std::ostream &printType(std::ostream &Out, const Type *Ty,
+    std::ostream &printType(std::ostream &Out, const Type *Ty, 
+                            bool isSigned = false,
                             const std::string &VariableName = "",
                             bool IgnoreName = false);
+    std::ostream &printSimpleType(std::ostream &Out, const Type *Ty, 
+                                     bool isSigned, 
+                                     const std::string &NameSoFar = "");
 
     void printStructReturnPointerFunctionType(std::ostream &Out,
                                               const PointerType *Ty);
@@ -124,6 +128,7 @@ namespace {
     void writeOperandRaw(Value *Operand);
     void writeOperandInternal(Value *Operand);
     void writeOperandWithCast(Value* Operand, unsigned Opcode);
+    void writeOperandWithCast(Value* Operand, ICmpInst::Predicate predicate);
     bool writeInstructionCast(const Instruction &I);
 
   private :
@@ -132,7 +137,7 @@ namespace {
     void lowerIntrinsics(Function &F);
 
     void printModule(Module *M);
-    void printModuleTypes(const SymbolTable &ST);
+    void printModuleTypes(const TypeSymbolTable &ST);
     void printContainedStructs(const Type *Ty, std::set<const StructType *> &);
     void printFloatingPointConstants(Function &F);
     void printFunctionSignature(const Function *F, bool Prototype);
@@ -154,9 +159,10 @@ namespace {
     // printed and an extra copy of the expr is not emitted.
     //
     static bool isInlinableInst(const Instruction &I) {
-      // Always inline setcc instructions, even if they are shared by multiple
+      // Always inline cmp instructions, even if they are shared by multiple
       // expressions.  GCC generates horrible code if we don't.
-      if (isa<SetCondInst>(I)) return true;
+      if (isa<CmpInst>(I)) 
+        return true;
 
       // Must be an expression, must be used exactly once.  If it is dead, we
       // emit it inline where it would go.
@@ -211,12 +217,13 @@ namespace {
 
     void visitPHINode(PHINode &I);
     void visitBinaryOperator(Instruction &I);
+    void visitICmpInst(ICmpInst &I);
+    void visitFCmpInst(FCmpInst &I);
 
     void visitCastInst (CastInst &I);
     void visitSelectInst(SelectInst &I);
     void visitCallInst (CallInst &I);
     void visitInlineAsm(CallInst &I);
-    void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); }
 
     void visitMallocInst(MallocInst &I);
     void visitAllocaInst(AllocaInst &I);
@@ -256,17 +263,23 @@ bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) {
   // Loop over the module symbol table, removing types from UT that are
   // already named, and removing names for types that are not used.
   //
-  SymbolTable &MST = M.getSymbolTable();
-  for (SymbolTable::type_iterator TI = MST.type_begin(), TE = MST.type_end();
+  TypeSymbolTable &TST = M.getTypeSymbolTable();
+  for (TypeSymbolTable::iterator TI = TST.begin(), TE = TST.end();
        TI != TE; ) {
-    SymbolTable::type_iterator I = TI++;
-
-    // If this is not used, remove it from the symbol table.
-    std::set<const Type *>::iterator UTI = UT.find(I->second);
-    if (UTI == UT.end())
-      MST.remove(I);
-    else
-      UT.erase(UTI);    // Only keep one name for this type.
+    TypeSymbolTable::iterator I = TI++;
+    
+    // If this isn't a struct type, remove it from our set of types to name.
+    // This simplifies emission later.
+    if (!isa<StructType>(I->second) && !isa<OpaqueType>(I->second)) {
+      TST.remove(I);
+    } else {
+      // If this is not used, remove it from the symbol table.
+      std::set<const Type *>::iterator UTI = UT.find(I->second);
+      if (UTI == UT.end())
+        TST.remove(I);
+      else
+        UT.erase(UTI);    // Only keep one name for this type.
+    }
   }
 
   // UT now contains types that are not named.  Loop over it, naming
@@ -290,7 +303,7 @@ bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) {
   std::map<std::string, GlobalValue*> ExtSymbols;
   for (Module::iterator I = M.begin(), E = M.end(); I != E;) {
     Function *GV = I++;
-    if (GV->isExternal() && GV->hasName()) {
+    if (GV->isDeclaration() && GV->hasName()) {
       std::pair<std::map<std::string, GlobalValue*>::iterator, bool> X
         = ExtSymbols.insert(std::make_pair(GV->getName(), GV));
       if (!X.second) {
@@ -306,7 +319,7 @@ bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) {
   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
        I != E;) {
     GlobalVariable *GV = I++;
-    if (GV->isExternal() && GV->hasName()) {
+    if (GV->isDeclaration() && GV->hasName()) {
       std::pair<std::map<std::string, GlobalValue*>::iterator, bool> X
         = ExtSymbols.insert(std::make_pair(GV->getName(), GV));
       if (!X.second) {
@@ -334,10 +347,12 @@ void CWriter::printStructReturnPointerFunctionType(std::ostream &Out,
 
   FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end();
   const Type *RetTy = cast<PointerType>(I->get())->getElementType();
+  unsigned Idx = 1;
   for (++I; I != E; ++I) {
     if (PrintedType)
       FunctionInnards << ", ";
-    printType(FunctionInnards, *I, "");
+    printType(FunctionInnards, *I, 
+        /*isSigned=*/FTy->paramHasAttr(Idx, FunctionType::SExtAttribute), "");
     PrintedType = true;
   }
   if (FTy->isVarArg()) {
@@ -348,34 +363,50 @@ void CWriter::printStructReturnPointerFunctionType(std::ostream &Out,
   }
   FunctionInnards << ')';
   std::string tstr = FunctionInnards.str();
-  printType(Out, RetTy, tstr);
+  printType(Out, RetTy, 
+      /*isSigned=*/FTy->paramHasAttr(0, FunctionType::SExtAttribute), tstr);
 }
 
+std::ostream &
+CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned,
+                            const std::string &NameSoFar) {
+  assert((Ty->isPrimitiveType() || Ty->isInteger()) && 
+         "Invalid type for printSimpleType");
+  switch (Ty->getTypeID()) {
+  case Type::VoidTyID:   return Out << "void " << NameSoFar;
+  case Type::IntegerTyID: {
+    unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth();
+    if (NumBits == 1) 
+      return Out << "bool " << NameSoFar;
+    else if (NumBits <= 8)
+      return Out << (isSigned?"signed":"unsigned") << " char " << NameSoFar;
+    else if (NumBits <= 16)
+      return Out << (isSigned?"signed":"unsigned") << " short " << NameSoFar;
+    else if (NumBits <= 32)
+      return Out << (isSigned?"signed":"unsigned") << " int " << NameSoFar;
+    else { 
+      assert(NumBits <= 64 && "Bit widths > 64 not implemented yet");
+      return Out << (isSigned?"signed":"unsigned") << " long long "<< NameSoFar;
+    }
+  }
+  case Type::FloatTyID:  return Out << "float "   << NameSoFar;
+  case Type::DoubleTyID: return Out << "double "  << NameSoFar;
+  default :
+    cerr << "Unknown primitive type: " << *Ty << "\n";
+    abort();
+  }
+}
 
 // Pass the Type* and the variable name and this prints out the variable
 // declaration.
 //
 std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
-                                 const std::string &NameSoFar,
+                                 bool isSigned, const std::string &NameSoFar,
                                  bool IgnoreName) {
-  if (Ty->isPrimitiveType())
-    switch (Ty->getTypeID()) {
-    case Type::VoidTyID:   return Out << "void "               << NameSoFar;
-    case Type::BoolTyID:   return Out << "bool "               << NameSoFar;
-    case Type::UByteTyID:  return Out << "unsigned char "      << NameSoFar;
-    case Type::SByteTyID:  return Out << "signed char "        << NameSoFar;
-    case Type::UShortTyID: return Out << "unsigned short "     << NameSoFar;
-    case Type::ShortTyID:  return Out << "short "              << NameSoFar;
-    case Type::UIntTyID:   return Out << "unsigned "           << NameSoFar;
-    case Type::IntTyID:    return Out << "int "                << NameSoFar;
-    case Type::ULongTyID:  return Out << "unsigned long long " << NameSoFar;
-    case Type::LongTyID:   return Out << "signed long long "   << NameSoFar;
-    case Type::FloatTyID:  return Out << "float "              << NameSoFar;
-    case Type::DoubleTyID: return Out << "double "             << NameSoFar;
-    default :
-      cerr << "Unknown primitive type: " << *Ty << "\n";
-      abort();
-    }
+  if (Ty->isPrimitiveType() || Ty->isInteger()) {
+    printSimpleType(Out, Ty, isSigned, NameSoFar);
+    return Out;
+  }
 
   // Check to see if the type is named.
   if (!IgnoreName || isa<OpaqueType>(Ty)) {
@@ -388,11 +419,14 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
     const FunctionType *FTy = cast<FunctionType>(Ty);
     std::stringstream FunctionInnards;
     FunctionInnards << " (" << NameSoFar << ") (";
+    unsigned Idx = 1;
     for (FunctionType::param_iterator I = FTy->param_begin(),
            E = FTy->param_end(); I != E; ++I) {
       if (I != FTy->param_begin())
         FunctionInnards << ", ";
-      printType(FunctionInnards, *I, "");
+      printType(FunctionInnards, *I, 
+         /*isSigned=*/FTy->paramHasAttr(Idx, FunctionType::SExtAttribute), "");
+      ++Idx;
     }
     if (FTy->isVarArg()) {
       if (FTy->getNumParams())
@@ -402,7 +436,8 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
     }
     FunctionInnards << ')';
     std::string tstr = FunctionInnards.str();
-    printType(Out, FTy->getReturnType(), tstr);
+    printType(Out, FTy->getReturnType(), 
+        /*isSigned=*/FTy->paramHasAttr(0, FunctionType::SExtAttribute), tstr);
     return Out;
   }
   case Type::StructTyID: {
@@ -412,7 +447,7 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
     for (StructType::element_iterator I = STy->element_begin(),
            E = STy->element_end(); I != E; ++I) {
       Out << "  ";
-      printType(Out, *I, "field" + utostr(Idx++));
+      printType(Out, *I, false, "field" + utostr(Idx++));
       Out << ";\n";
     }
     return Out << '}';
@@ -426,14 +461,14 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
         isa<PackedType>(PTy->getElementType()))
       ptrName = "(" + ptrName + ")";
 
-    return printType(Out, PTy->getElementType(), ptrName);
+    return printType(Out, PTy->getElementType(), false, ptrName);
   }
 
   case Type::ArrayTyID: {
     const ArrayType *ATy = cast<ArrayType>(Ty);
     unsigned NumElements = ATy->getNumElements();
     if (NumElements == 0) NumElements = 1;
-    return printType(Out, ATy->getElementType(),
+    return printType(Out, ATy->getElementType(), false,
                      NameSoFar + "[" + utostr(NumElements) + "]");
   }
 
@@ -441,7 +476,7 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
     const PackedType *PTy = cast<PackedType>(Ty);
     unsigned NumElements = PTy->getNumElements();
     if (NumElements == 0) NumElements = 1;
-    return printType(Out, PTy->getElementType(),
+    return printType(Out, PTy->getElementType(), false,
                      NameSoFar + "[" + utostr(NumElements) + "]");
   }
 
@@ -466,7 +501,7 @@ void CWriter::printConstantArray(ConstantArray *CPA) {
   // ubytes or an array of sbytes with positive values.
   //
   const Type *ETy = CPA->getType()->getElementType();
-  bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy);
+  bool isString = (ETy == Type::Int8Ty || ETy == Type::Int8Ty);
 
   // Make sure the last character is a null char, as automatically added by C
   if (isString && (CPA->getNumOperands() == 0 ||
@@ -578,41 +613,66 @@ static bool isFPCSafeToPrint(const ConstantFP *CFP) {
 
 /// Print out the casting for a cast operation. This does the double casting
 /// necessary for conversion to the destination type, if necessary. 
-/// @returns true if a closing paren is necessary
 /// @brief Print a cast
 void CWriter::printCast(unsigned opc, const Type *SrcTy, const Type *DstTy) {
-  Out << '(';
-  printType(Out, DstTy);
-  Out << ')';
+  // Print the destination type cast
   switch (opc) {
     case Instruction::UIToFP:
+    case Instruction::SIToFP:
+    case Instruction::IntToPtr:
+    case Instruction::Trunc:
+    case Instruction::BitCast:
+    case Instruction::FPExt:
+    case Instruction::FPTrunc: // For these the DstTy sign doesn't matter
+      Out << '(';
+      printType(Out, DstTy);
+      Out << ')';
+      break;
     case Instruction::ZExt:
-      if (SrcTy->isSigned()) {
-        Out << '(';
-        printType(Out, SrcTy->getUnsignedVersion());
-        Out << ')';
-      }
+    case Instruction::PtrToInt:
+    case Instruction::FPToUI: // For these, make sure we get an unsigned dest
+      Out << '(';
+      printSimpleType(Out, DstTy, false);
+      Out << ')';
+      break;
+    case Instruction::SExt: 
+    case Instruction::FPToSI: // For these, make sure we get a signed dest
+      Out << '(';
+      printSimpleType(Out, DstTy, true);
+      Out << ')';
+      break;
+    default:
+      assert(0 && "Invalid cast opcode");
+  }
+
+  // Print the source type cast
+  switch (opc) {
+    case Instruction::UIToFP:
+    case Instruction::ZExt:
+      Out << '(';
+      printSimpleType(Out, SrcTy, false);
+      Out << ')';
       break;
     case Instruction::SIToFP:
     case Instruction::SExt:
-      if (SrcTy->isUnsigned()) {
-        Out << '(';
-        printType(Out, SrcTy->getSignedVersion());
-        Out << ')';
-      }
+      Out << '(';
+      printSimpleType(Out, SrcTy, true); 
+      Out << ')';
       break;
     case Instruction::IntToPtr:
     case Instruction::PtrToInt:
-        // Avoid "cast to pointer from integer of different size" warnings
-        Out << "(unsigned long)";
-        break;
+      // Avoid "cast to pointer from integer of different size" warnings
+      Out << "(unsigned long)";
+      break;
     case Instruction::Trunc:
     case Instruction::BitCast:
     case Instruction::FPExt:
     case Instruction::FPTrunc:
     case Instruction::FPToSI:
     case Instruction::FPToUI:
+      break; // These don't need a source cast.
     default:
+      assert(0 && "Invalid cast opcode");
       break;
   }
 }
@@ -636,12 +696,12 @@ void CWriter::printConstant(Constant *CPV) {
       Out << "(";
       printCast(CE->getOpcode(), CE->getOperand(0)->getType(), CE->getType());
       if (CE->getOpcode() == Instruction::SExt &&
-          CE->getOperand(0)->getType() == Type::BoolTy) {
+          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::BoolTy &&
+      if (CE->getType() == Type::Int1Ty &&
           (CE->getOpcode() == Instruction::Trunc ||
            CE->getOpcode() == Instruction::FPToUI ||
            CE->getOpcode() == Instruction::FPToSI ||
@@ -679,12 +739,7 @@ void CWriter::printConstant(Constant *CPV) {
     case Instruction::And:
     case Instruction::Or:
     case Instruction::Xor:
-    case Instruction::SetEQ:
-    case Instruction::SetNE:
-    case Instruction::SetLT:
-    case Instruction::SetLE:
-    case Instruction::SetGT:
-    case Instruction::SetGE:
+    case Instruction::ICmp:
     case Instruction::Shl:
     case Instruction::LShr:
     case Instruction::AShr:
@@ -705,15 +760,24 @@ void CWriter::printConstant(Constant *CPV) {
       case Instruction::And: Out << " & "; break;
       case Instruction::Or:  Out << " | "; break;
       case Instruction::Xor: Out << " ^ "; break;
-      case Instruction::SetEQ: Out << " == "; break;
-      case Instruction::SetNE: Out << " != "; break;
-      case Instruction::SetLT: Out << " < "; break;
-      case Instruction::SetLE: Out << " <= "; break;
-      case Instruction::SetGT: Out << " > "; break;
-      case Instruction::SetGE: Out << " >= "; break;
       case Instruction::Shl: Out << " << "; break;
       case Instruction::LShr:
       case Instruction::AShr: Out << " >> "; break;
+      case Instruction::ICmp:
+        switch (CE->getPredicate()) {
+          case ICmpInst::ICMP_EQ: Out << " == "; break;
+          case ICmpInst::ICMP_NE: Out << " != "; break;
+          case ICmpInst::ICMP_SLT: 
+          case ICmpInst::ICMP_ULT: Out << " < "; break;
+          case ICmpInst::ICMP_SLE:
+          case ICmpInst::ICMP_ULE: Out << " <= "; break;
+          case ICmpInst::ICMP_SGT:
+          case ICmpInst::ICMP_UGT: Out << " > "; break;
+          case ICmpInst::ICMP_SGE:
+          case ICmpInst::ICMP_UGE: Out << " >= "; break;
+          default: assert(0 && "Illegal ICmp predicate");
+        }
+        break;
       default: assert(0 && "Illegal opcode here!");
       }
       printConstantWithCast(CE->getOperand(1), CE->getOpcode());
@@ -722,7 +786,42 @@ void CWriter::printConstant(Constant *CPV) {
       Out << ')';
       return;
     }
-
+    case Instruction::FCmp: {
+      Out << '('; 
+      bool NeedsClosingParens = printConstExprCast(CE); 
+      if (CE->getPredicate() == FCmpInst::FCMP_FALSE)
+        Out << "0";
+      else if (CE->getPredicate() == FCmpInst::FCMP_TRUE)
+        Out << "1";
+      else {
+        const char* op = 0;
+        switch (CE->getPredicate()) {
+        default: assert(0 && "Illegal FCmp predicate");
+        case FCmpInst::FCMP_ORD: op = "ord"; break;
+        case FCmpInst::FCMP_UNO: op = "uno"; break;
+        case FCmpInst::FCMP_UEQ: op = "ueq"; break;
+        case FCmpInst::FCMP_UNE: op = "une"; break;
+        case FCmpInst::FCMP_ULT: op = "ult"; break;
+        case FCmpInst::FCMP_ULE: op = "ule"; break;
+        case FCmpInst::FCMP_UGT: op = "ugt"; break;
+        case FCmpInst::FCMP_UGE: op = "uge"; break;
+        case FCmpInst::FCMP_OEQ: op = "oeq"; break;
+        case FCmpInst::FCMP_ONE: op = "one"; break;
+        case FCmpInst::FCMP_OLT: op = "olt"; break;
+        case FCmpInst::FCMP_OLE: op = "ole"; break;
+        case FCmpInst::FCMP_OGT: op = "ogt"; break;
+        case FCmpInst::FCMP_OGE: op = "oge"; break;
+        }
+        Out << "llvm_fcmp_" << op << "(";
+        printConstantWithCast(CE->getOperand(0), CE->getOpcode());
+        Out << ", ";
+        printConstantWithCast(CE->getOperand(1), CE->getOpcode());
+        Out << ")";
+      }
+      if (NeedsClosingParens)
+        Out << "))";
+      Out << ')';
+    }
     default:
       cerr << "CWriter Error: Unhandled constant expression: "
            << *CE << "\n";
@@ -730,44 +829,30 @@ void CWriter::printConstant(Constant *CPV) {
     }
   } else if (isa<UndefValue>(CPV) && CPV->getType()->isFirstClassType()) {
     Out << "((";
-    printType(Out, CPV->getType());
+    printType(Out, CPV->getType()); // sign doesn't matter
     Out << ")/*UNDEF*/0)";
     return;
   }
 
-  switch (CPV->getType()->getTypeID()) {
-  case Type::BoolTyID:
-    Out << (cast<ConstantBool>(CPV)->getValue() ? '1' : '0');
-    break;
-  case Type::SByteTyID:
-  case Type::ShortTyID:
-    Out << cast<ConstantInt>(CPV)->getSExtValue();
-    break;
-  case Type::IntTyID:
-    if ((int)cast<ConstantInt>(CPV)->getSExtValue() == (int)0x80000000)
-      Out << "((int)0x80000000U)";   // Handle MININT specially to avoid warning
-    else
-      Out << cast<ConstantInt>(CPV)->getSExtValue();
-    break;
-
-  case Type::LongTyID:
-    if (cast<ConstantInt>(CPV)->isMinValue(true))
-      Out << "(/*INT64_MIN*/(-9223372036854775807LL)-1)";
-    else
-      Out << cast<ConstantInt>(CPV)->getSExtValue() << "ll";
-    break;
-
-  case Type::UByteTyID:
-  case Type::UShortTyID:
-    Out << cast<ConstantInt>(CPV)->getZExtValue();
-    break;
-  case Type::UIntTyID:
-    Out << cast<ConstantInt>(CPV)->getZExtValue() << 'u';
-    break;
-  case Type::ULongTyID:
-    Out << cast<ConstantInt>(CPV)->getZExtValue() << "ull";
-    break;
+  if (ConstantInt *CI = dyn_cast<ConstantInt>(CPV)) {
+    const Type* Ty = CI->getType();
+    if (Ty == Type::Int1Ty)
+      Out << (CI->getZExtValue() ? '1' : '0') ;
+    else {
+      Out << "((";
+      printSimpleType(Out, Ty, false) << ')';
+      if (CI->isMinValue(true)) 
+        Out << CI->getZExtValue() << 'u';
+      else
+        Out << CI->getSExtValue();
+      if (Ty->getPrimitiveSizeInBits() > 32)
+        Out << "ll";
+      Out << ')';
+    }
+    return;
+  } 
 
+  switch (CPV->getType()->getTypeID()) {
   case Type::FloatTyID:
   case Type::DoubleTyID: {
     ConstantFP *FPC = cast<ConstantFP>(CPV);
@@ -890,7 +975,7 @@ void CWriter::printConstant(Constant *CPV) {
   case Type::PointerTyID:
     if (isa<ConstantPointerNull>(CPV)) {
       Out << "((";
-      printType(Out, CPV->getType());
+      printType(Out, CPV->getType()); // sign doesn't matter
       Out << ")/*NULL*/0)";
       break;
     } else if (GlobalValue *GV = dyn_cast<GlobalValue>(CPV)) {
@@ -910,17 +995,20 @@ void CWriter::printConstant(Constant *CPV) {
 bool CWriter::printConstExprCast(const ConstantExpr* CE) {
   bool NeedsExplicitCast = false;
   const Type *Ty = CE->getOperand(0)->getType();
+  bool TypeIsSigned = false;
   switch (CE->getOpcode()) {
   case Instruction::LShr:
   case Instruction::URem: 
-  case Instruction::UDiv: 
-    NeedsExplicitCast = Ty->isSigned(); break;
+  case Instruction::UDiv: NeedsExplicitCast = true; break;
   case Instruction::AShr:
   case Instruction::SRem: 
-  case Instruction::SDiv: 
-    NeedsExplicitCast = Ty->isUnsigned(); break;
-  case Instruction::ZExt:
+  case Instruction::SDiv: NeedsExplicitCast = true; TypeIsSigned = true; break;
   case Instruction::SExt:
+    Ty = CE->getType();
+    NeedsExplicitCast = true;
+    TypeIsSigned = true;
+    break;
+  case Instruction::ZExt:
   case Instruction::Trunc:
   case Instruction::FPTrunc:
   case Instruction::FPExt:
@@ -938,7 +1026,10 @@ bool CWriter::printConstExprCast(const ConstantExpr* CE) {
   }
   if (NeedsExplicitCast) {
     Out << "((";
-    printType(Out, Ty);
+    if (Ty->isInteger() && Ty != Type::Int1Ty)
+      printSimpleType(Out, Ty, TypeIsSigned);
+    else
+      printType(Out, Ty); // not integer, sign doesn't matter
     Out << ")(";
   }
   return NeedsExplicitCast;
@@ -954,6 +1045,7 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
 
   // Indicate whether to do the cast or not.
   bool shouldCast = false;
+  bool typeIsSigned = false;
 
   // Based on the Opcode for which this Constant is being written, determine
   // the new type to which the operand should be casted by setting the value
@@ -966,20 +1058,13 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
     case Instruction::LShr:
     case Instruction::UDiv:
     case Instruction::URem:
-      // For UDiv/URem get correct type
-      if (OpTy->isSigned()) {
-        OpTy = OpTy->getUnsignedVersion();
-        shouldCast = true;
-      }
+      shouldCast = true;
       break;
     case Instruction::AShr:
     case Instruction::SDiv:
     case Instruction::SRem:
-      // For SDiv/SRem get correct type
-      if (OpTy->isUnsigned()) {
-        OpTy = OpTy->getSignedVersion();
-        shouldCast = true;
-      }
+      shouldCast = true;
+      typeIsSigned = true;
       break;
   }
 
@@ -987,13 +1072,12 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
   // operand.
   if (shouldCast) {
     Out << "((";
-    printType(Out, OpTy);
+    printSimpleType(Out, OpTy, typeIsSigned);
     Out << ")";
     printConstant(CPV);
     Out << ")";
   } else 
-    writeOperand(CPV);
-
+    printConstant(CPV);
 }
 
 void CWriter::writeOperandInternal(Value *Operand) {
@@ -1038,40 +1122,25 @@ void CWriter::writeOperand(Value *Operand) {
 // This function takes care of detecting that case and printing the cast 
 // for the Instruction.
 bool CWriter::writeInstructionCast(const Instruction &I) {
-  bool NeedsExplicitCast = false;
   const Type *Ty = I.getOperand(0)->getType();
   switch (I.getOpcode()) {
   case Instruction::LShr:
   case Instruction::URem: 
   case Instruction::UDiv: 
-    NeedsExplicitCast = Ty->isSigned(); break;
+    Out << "((";
+    printSimpleType(Out, Ty, false);
+    Out << ")(";
+    return true;
   case Instruction::AShr:
   case Instruction::SRem: 
   case Instruction::SDiv: 
-    NeedsExplicitCast = Ty->isUnsigned(); break;
-  case Instruction::ZExt:
-  case Instruction::SExt:
-  case Instruction::Trunc:
-  case Instruction::FPTrunc:
-  case Instruction::FPExt:
-  case Instruction::UIToFP:
-  case Instruction::SIToFP:
-  case Instruction::FPToUI:
-  case Instruction::FPToSI:
-  case Instruction::PtrToInt:
-  case Instruction::IntToPtr:
-  case Instruction::BitCast:
-    Ty = I.getType();
-    NeedsExplicitCast = true;
-    break;
-  default: break;
-  }
-  if (NeedsExplicitCast) {
     Out << "((";
-    printType(Out, Ty);
+    printSimpleType(Out, Ty, true);
     Out << ")(";
+    return true;
+  default: break;
   }
-  return NeedsExplicitCast;
+  return false;
 }
 
 // Write the operand with a cast to another type based on the Opcode being used.
@@ -1085,6 +1154,9 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
   // Indicate whether to do the cast or not.
   bool shouldCast = false;
 
+  // Indicate whether the cast should be to a signed type or not.
+  bool castIsSigned = false;
+
   // Based on the Opcode for which this Operand is being written, determine
   // the new type to which the operand should be casted by setting the value
   // of OpTy. If we change OpTy, also set shouldCast to true.
@@ -1094,20 +1166,15 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
       break; 
     case Instruction::LShr:
     case Instruction::UDiv:
-    case Instruction::URem:
-      // For UDiv to have unsigned operands
-      if (OpTy->isSigned()) {
-        OpTy = OpTy->getUnsignedVersion();
-        shouldCast = true;
-      }
+    case Instruction::URem: // Cast to unsigned first
+      shouldCast = true;
+      castIsSigned = false;
       break;
     case Instruction::AShr:
     case Instruction::SDiv:
-    case Instruction::SRem:
-      if (OpTy->isUnsigned()) {
-        OpTy = OpTy->getSignedVersion();
-        shouldCast = true;
-      }
+    case Instruction::SRem: // Cast to signed first
+      shouldCast = true;
+      castIsSigned = true;
       break;
   }
 
@@ -1115,13 +1182,62 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
   // operand.
   if (shouldCast) {
     Out << "((";
-    printType(Out, OpTy);
+    printSimpleType(Out, OpTy, castIsSigned);
     Out << ")";
     writeOperand(Operand);
     Out << ")";
   } else 
     writeOperand(Operand);
+}
+
+// Write the operand with a cast to another type based on the icmp predicate 
+// being used. 
+void CWriter::writeOperandWithCast(Value* Operand, ICmpInst::Predicate predicate) {
+
+  // Extract the operand's type, we'll need it.
+  const Type* OpTy = Operand->getType();
 
+  // Indicate whether to do the cast or not.
+  bool shouldCast = false;
+
+  // Indicate whether the cast should be to a signed type or not.
+  bool castIsSigned = false;
+
+  // Based on the Opcode for which this Operand is being written, determine
+  // the new type to which the operand should be casted by setting the value
+  // of OpTy. If we change OpTy, also set shouldCast to true.
+  switch (predicate) {
+    default:
+      // for eq and ne, it doesn't matter
+      break; 
+    case ICmpInst::ICMP_UGT:
+    case ICmpInst::ICMP_UGE:
+    case ICmpInst::ICMP_ULT:
+    case ICmpInst::ICMP_ULE:
+      shouldCast = true;
+      break;
+    case ICmpInst::ICMP_SGT:
+    case ICmpInst::ICMP_SGE:
+    case ICmpInst::ICMP_SLT:
+    case ICmpInst::ICMP_SLE:
+      shouldCast = true;
+      castIsSigned = true;
+      break;
+  }
+
+  // Write out the casted operand if we should, otherwise just write the
+  // operand.
+  if (shouldCast) {
+    Out << "((";
+    if (OpTy->isInteger() && OpTy != Type::Int1Ty)
+      printSimpleType(Out, OpTy, castIsSigned);
+    else
+      printType(Out, OpTy); // not integer, sign doesn't matter
+    Out << ")";
+    writeOperand(Operand);
+    Out << ")";
+  } else 
+    writeOperand(Operand);
 }
 
 // generateCompilerSpecificCode - This is where we add conditional compilation
@@ -1175,6 +1291,11 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
       << "#define __ATTRIBUTE_WEAK__\n"
       << "#endif\n\n";
 
+  // Add hidden visibility support. FIXME: APPLE_CC?
+  Out << "#if defined(__GNUC__)\n"
+      << "#define __HIDDEN__ __attribute__((visibility(\"hidden\")))\n"
+      << "#endif\n\n";
+    
   // Define NaN and Inf as GCC builtins if using GCC, as 0 otherwise
   // From the GCC documentation:
   //
@@ -1296,7 +1417,9 @@ bool CWriter::doInitialization(Module &M) {
   // Initialize
   TheModule = &M;
 
-  IL.AddPrototypes(M);
+  TD = new TargetData(&M);
+  IL = new IntrinsicLowering(*TD);
+  IL->AddPrototypes(M);
 
   // Ensure that all structure types have names...
   Mang = new Mangler(M);
@@ -1339,7 +1462,7 @@ bool CWriter::doInitialization(Module &M) {
   //
 
   // Loop over the symbol table, emitting all named constants...
-  printModuleTypes(M.getSymbolTable());
+  printModuleTypes(M.getTypeSymbolTable());
 
   // Global variable declarations...
   if (!M.global_empty()) {
@@ -1348,15 +1471,18 @@ bool CWriter::doInitialization(Module &M) {
          I != E; ++I) {
       if (I->hasExternalLinkage()) {
         Out << "extern ";
-        printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
+        printType(Out, I->getType()->getElementType(), false, 
+                  Mang->getValueName(I));
         Out << ";\n";
       } else if (I->hasDLLImportLinkage()) {
         Out << "__declspec(dllimport) ";
-        printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
+        printType(Out, I->getType()->getElementType(), false, 
+                  Mang->getValueName(I));
         Out << ";\n";        
       } else if (I->hasExternalWeakLinkage()) {
         Out << "extern ";
-        printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
+        printType(Out, I->getType()->getElementType(), false,
+                  Mang->getValueName(I));
         Out << " __EXTERNAL_WEAK__ ;\n";
       }
     }
@@ -1382,6 +1508,8 @@ bool CWriter::doInitialization(Module &M) {
         Out << " __ATTRIBUTE_CTOR__";
       if (StaticDtors.count(I))
         Out << " __ATTRIBUTE_DTOR__";
+      if (I->hasHiddenVisibility())
+        Out << " __HIDDEN__";
       
       if (I->hasName() && I->getName()[0] == 1)
         Out << " LLVM_ASM(\"" << I->getName().c_str()+1 << "\")";
@@ -1395,7 +1523,7 @@ bool CWriter::doInitialization(Module &M) {
     Out << "\n\n/* Global Variable Declarations */\n";
     for (Module::global_iterator I = M.global_begin(), E = M.global_end();
          I != E; ++I)
-      if (!I->isExternal()) {
+      if (!I->isDeclaration()) {
         // Ignore special globals, such as debug info.
         if (getGlobalVariableClass(I))
           continue;
@@ -1404,7 +1532,8 @@ bool CWriter::doInitialization(Module &M) {
           Out << "static ";
         else
           Out << "extern ";
-        printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
+        printType(Out, I->getType()->getElementType(), false, 
+                  Mang->getValueName(I));
 
         if (I->hasLinkOnceLinkage())
           Out << " __attribute__((common))";
@@ -1412,6 +1541,8 @@ bool CWriter::doInitialization(Module &M) {
           Out << " __ATTRIBUTE_WEAK__";
         else if (I->hasExternalWeakLinkage())
           Out << " __EXTERNAL_WEAK__";
+        if (I->hasHiddenVisibility())
+          Out << " __HIDDEN__";
         Out << ";\n";
       }
   }
@@ -1421,7 +1552,7 @@ bool CWriter::doInitialization(Module &M) {
     Out << "\n\n/* Global Variable Definitions and Initialization */\n";
     for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 
          I != E; ++I)
-      if (!I->isExternal()) {
+      if (!I->isDeclaration()) {
         // Ignore special globals, such as debug info.
         if (getGlobalVariableClass(I))
           continue;
@@ -1433,12 +1564,16 @@ bool CWriter::doInitialization(Module &M) {
         else if (I->hasDLLExportLinkage())
           Out << "__declspec(dllexport) ";
             
-        printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
+        printType(Out, I->getType()->getElementType(), false, 
+                  Mang->getValueName(I));
         if (I->hasLinkOnceLinkage())
           Out << " __attribute__((common))";
         else if (I->hasWeakLinkage())
           Out << " __ATTRIBUTE_WEAK__";
 
+        if (I->hasHiddenVisibility())
+          Out << " __HIDDEN__";
+        
         // If the initializer is not null, emit the initializer.  If it is null,
         // we try to avoid emitting large amounts of zeros.  The problem with
         // this, however, occurs when the variable has weak linkage.  In this
@@ -1467,6 +1602,37 @@ bool CWriter::doInitialization(Module &M) {
 
   if (!M.empty())
     Out << "\n\n/* Function Bodies */\n";
+
+  // Emit some helper functions for dealing with FCMP instruction's 
+  // predicates
+  Out << "static inline int llvm_fcmp_ord(double X, double Y) { ";
+  Out << "return X == X && Y == Y; }\n";
+  Out << "static inline int llvm_fcmp_uno(double X, double Y) { ";
+  Out << "return X != X || Y != Y; }\n";
+  Out << "static inline int llvm_fcmp_ueq(double X, double Y) { ";
+  Out << "return X == Y || llvm_fcmp_uno(X, Y); }\n";
+  Out << "static inline int llvm_fcmp_une(double X, double Y) { ";
+  Out << "return X != Y; }\n";
+  Out << "static inline int llvm_fcmp_ult(double X, double Y) { ";
+  Out << "return X <  Y || llvm_fcmp_uno(X, Y); }\n";
+  Out << "static inline int llvm_fcmp_ugt(double X, double Y) { ";
+  Out << "return X >  Y || llvm_fcmp_uno(X, Y); }\n";
+  Out << "static inline int llvm_fcmp_ule(double X, double Y) { ";
+  Out << "return X <= Y || llvm_fcmp_uno(X, Y); }\n";
+  Out << "static inline int llvm_fcmp_uge(double X, double Y) { ";
+  Out << "return X >= Y || llvm_fcmp_uno(X, Y); }\n";
+  Out << "static inline int llvm_fcmp_oeq(double X, double Y) { ";
+  Out << "return X == Y ; }\n";
+  Out << "static inline int llvm_fcmp_one(double X, double Y) { ";
+  Out << "return X != Y && llvm_fcmp_ord(X, Y); }\n";
+  Out << "static inline int llvm_fcmp_olt(double X, double Y) { ";
+  Out << "return X <  Y ; }\n";
+  Out << "static inline int llvm_fcmp_ogt(double X, double Y) { ";
+  Out << "return X >  Y ; }\n";
+  Out << "static inline int llvm_fcmp_ole(double X, double Y) { ";
+  Out << "return X <= Y ; }\n";
+  Out << "static inline int llvm_fcmp_oge(double X, double Y) { ";
+  Out << "return X >= Y ; }\n";
   return false;
 }
 
@@ -1507,42 +1673,39 @@ void CWriter::printFloatingPointConstants(Function &F) {
 /// printSymbolTable - Run through symbol table looking for type names.  If a
 /// type name is found, emit its declaration...
 ///
-void CWriter::printModuleTypes(const SymbolTable &ST) {
+void CWriter::printModuleTypes(const TypeSymbolTable &TST) {
   Out << "/* Helper union for bitcasts */\n";
   Out << "typedef union {\n";
-  Out << "  unsigned int UInt;\n";
-  Out << "  signed int SInt;\n";
-  Out << "  unsigned long long ULong;\n";
-  Out << "  signed long long SLong;\n";
+  Out << "  unsigned int Int32;\n";
+  Out << "  unsigned long long Int64;\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();
+  TypeSymbolTable::const_iterator I   = TST.begin();
+  TypeSymbolTable::const_iterator End = TST.end();
 
   // If there are no type names, exit early.
   if (I == End) return;
 
   // Print out forward declarations for structure types before anything else!
   Out << "/* Structure forward decls */\n";
-  for (; I != End; ++I)
-    if (const Type *STy = dyn_cast<StructType>(I->second)) {
-      std::string Name = "struct l_" + Mang->makeNameProper(I->first);
-      Out << Name << ";\n";
-      TypeNames.insert(std::make_pair(STy, Name));
-    }
+  for (; I != End; ++I) {
+    std::string Name = "struct l_" + Mang->makeNameProper(I->first);
+    Out << Name << ";\n";
+    TypeNames.insert(std::make_pair(I->second, Name));
+  }
 
   Out << '\n';
 
-  // Now we can print out typedefs...
+  // Now we can print out typedefs.  Above, we guaranteed that this can only be
+  // for struct or opaque types.
   Out << "/* Typedefs */\n";
-  for (I = ST.type_begin(); I != End; ++I) {
-    const Type *Ty = cast<Type>(I->second);
+  for (I = TST.begin(); I != End; ++I) {
     std::string Name = "l_" + Mang->makeNameProper(I->first);
     Out << "typedef ";
-    printType(Out, Ty, Name);
+    printType(Out, I->second, false, Name);
     Out << ";\n";
   }
 
@@ -1555,7 +1718,7 @@ void CWriter::printModuleTypes(const SymbolTable &ST) {
   // printed in the correct order.
   //
   Out << "/* Structure contents */\n";
-  for (I = ST.type_begin(); I != End; ++I)
+  for (I = TST.begin(); I != End; ++I)
     if (const StructType *STy = dyn_cast<StructType>(I->second))
       // Only print out used types!
       printContainedStructs(STy, StructPrinted);
@@ -1569,7 +1732,7 @@ void CWriter::printModuleTypes(const SymbolTable &ST) {
 void CWriter::printContainedStructs(const Type *Ty,
                                     std::set<const StructType*> &StructPrinted){
   // Don't walk through pointers.
-  if (isa<PointerType>(Ty) || Ty->isPrimitiveType()) return;
+  if (isa<PointerType>(Ty) || Ty->isPrimitiveType() || Ty->isInteger()) return;
   
   // Print all contained types first.
   for (Type::subtype_iterator I = Ty->subtype_begin(),
@@ -1581,15 +1744,15 @@ void CWriter::printContainedStructs(const Type *Ty,
     if (StructPrinted.insert(STy).second) {
       // Print structure type out.
       std::string Name = TypeNames[STy];
-      printType(Out, STy, Name, true);
+      printType(Out, STy, false, Name, true);
       Out << ";\n\n";
     }
   }
 }
 
 void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
-  /// isCStructReturn - Should this function actually return a struct by-value?
-  bool isCStructReturn = F->getCallingConv() == CallingConv::CSRet;
+  /// isStructReturn - Should this function actually return a struct by-value?
+  bool isStructReturn = F->getFunctionType()->isStructReturn();
   
   if (F->hasInternalLinkage()) Out << "static ";
   if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) ";
@@ -1612,26 +1775,30 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   FunctionInnards << Mang->getValueName(F) << '(';
 
   bool PrintedArg = false;
-  if (!F->isExternal()) {
+  if (!F->isDeclaration()) {
     if (!F->arg_empty()) {
       Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
       
       // If this is a struct-return function, don't print the hidden
       // struct-return argument.
-      if (isCStructReturn) {
+      if (isStructReturn) {
         assert(I != E && "Invalid struct return function!");
         ++I;
       }
       
       std::string ArgName;
+      unsigned Idx = 1;
       for (; I != E; ++I) {
         if (PrintedArg) FunctionInnards << ", ";
         if (I->hasName() || !Prototype)
           ArgName = Mang->getValueName(I);
         else
           ArgName = "";
-        printType(FunctionInnards, I->getType(), ArgName);
+        printType(FunctionInnards, I->getType(), 
+            /*isSigned=*/FT->paramHasAttr(Idx, FunctionType::SExtAttribute), 
+            ArgName);
         PrintedArg = true;
+        ++Idx;
       }
     }
   } else {
@@ -1640,15 +1807,18 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
     
     // If this is a struct-return function, don't print the hidden
     // struct-return argument.
-    if (isCStructReturn) {
+    if (isStructReturn) {
       assert(I != E && "Invalid struct return function!");
       ++I;
     }
     
+    unsigned Idx = 1;
     for (; I != E; ++I) {
       if (PrintedArg) FunctionInnards << ", ";
-      printType(FunctionInnards, *I);
+      printType(FunctionInnards, *I,
+             /*isSigned=*/FT->paramHasAttr(Idx, FunctionType::SExtAttribute));
       PrintedArg = true;
+      ++Idx;
     }
   }
 
@@ -1665,7 +1835,7 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   
   // Get the return tpe for the function.
   const Type *RetTy;
-  if (!isCStructReturn)
+  if (!isStructReturn)
     RetTy = F->getReturnType();
   else {
     // If this is a struct-return function, print the struct-return type.
@@ -1673,7 +1843,9 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   }
     
   // Print out the return type and the signature built above.
-  printType(Out, RetTy, FunctionInnards.str());
+  printType(Out, RetTy, 
+            /*isSigned=*/FT->paramHasAttr(0, FunctionType::SExtAttribute), 
+            FunctionInnards.str());
 }
 
 static inline bool isFPIntBitCast(const Instruction &I) {
@@ -1686,19 +1858,23 @@ static inline bool isFPIntBitCast(const Instruction &I) {
 }
 
 void CWriter::printFunction(Function &F) {
+  /// isStructReturn - Should this function actually return a struct by-value?
+  bool isStructReturn = F.getFunctionType()->isStructReturn();
+
   printFunctionSignature(&F, false);
   Out << " {\n";
   
   // If this is a struct return function, handle the result with magic.
-  if (F.getCallingConv() == CallingConv::CSRet) {
+  if (isStructReturn) {
     const Type *StructTy =
       cast<PointerType>(F.arg_begin()->getType())->getElementType();
     Out << "  ";
-    printType(Out, StructTy, "StructReturn");
+    printType(Out, StructTy, false, "StructReturn");
     Out << ";  /* Struct return temporary */\n";
 
     Out << "  ";
-    printType(Out, F.arg_begin()->getType(), Mang->getValueName(F.arg_begin()));
+    printType(Out, F.arg_begin()->getType(), false, 
+              Mang->getValueName(F.arg_begin()));
     Out << " = &StructReturn;\n";
   }
 
@@ -1708,24 +1884,24 @@ void CWriter::printFunction(Function &F) {
   for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I) {
     if (const AllocaInst *AI = isDirectAlloca(&*I)) {
       Out << "  ";
-      printType(Out, AI->getAllocatedType(), Mang->getValueName(AI));
+      printType(Out, AI->getAllocatedType(), false, Mang->getValueName(AI));
       Out << ";    /* Address-exposed local */\n";
       PrintedVar = true;
     } else if (I->getType() != Type::VoidTy && !isInlinableInst(*I)) {
       Out << "  ";
-      printType(Out, I->getType(), Mang->getValueName(&*I));
+      printType(Out, I->getType(), false, Mang->getValueName(&*I));
       Out << ";\n";
 
       if (isa<PHINode>(*I)) {  // Print out PHI node temporaries as well...
         Out << "  ";
-        printType(Out, I->getType(),
+        printType(Out, I->getType(), false,
                   Mang->getValueName(&*I)+"__PHI_TEMPORARY");
         Out << ";\n";
       }
       PrintedVar = true;
     }
     // We need a temporary for the BitCast to use so it can pluck a value out
-    // of a uniont to do the BitCast. This is separate from the need for a
+    // of a union to do the BitCast. This is separate from the need for a
     // variable to hold the result of the BitCast. 
     if (isFPIntBitCast(*I)) {
       Out << "  llvmBitCastUnion " << Mang->getValueName(&*I)
@@ -1807,7 +1983,10 @@ void CWriter::printBasicBlock(BasicBlock *BB) {
 //
 void CWriter::visitReturnInst(ReturnInst &I) {
   // If this is a struct return function, return the temporary struct.
-  if (I.getParent()->getParent()->getCallingConv() == CallingConv::CSRet) {
+  bool isStructReturn = I.getParent()->getParent()->
+    getFunctionType()->isStructReturn();
+
+  if (isStructReturn) {
     Out << "  return StructReturn;\n";
     return;
   }
@@ -1943,12 +2122,11 @@ void CWriter::visitBinaryOperator(Instruction &I) {
 
   // We must cast the results of binary operations which might be promoted.
   bool needsCast = false;
-  if ((I.getType() == Type::UByteTy) || (I.getType() == Type::SByteTy)
-      || (I.getType() == Type::UShortTy) || (I.getType() == Type::ShortTy)
+  if ((I.getType() == Type::Int8Ty) || (I.getType() == Type::Int16Ty) 
       || (I.getType() == Type::FloatTy)) {
     needsCast = true;
     Out << "((";
-    printType(Out, I.getType());
+    printType(Out, I.getType(), false);
     Out << ")(";
   }
 
@@ -1980,24 +2158,18 @@ void CWriter::visitBinaryOperator(Instruction &I) {
     writeOperandWithCast(I.getOperand(0), I.getOpcode());
 
     switch (I.getOpcode()) {
-    case Instruction::Add: Out << " + "; break;
-    case Instruction::Sub: Out << " - "; break;
-    case Instruction::Mul: Out << '*'; break;
+    case Instruction::Add:  Out << " + "; break;
+    case Instruction::Sub:  Out << " - "; break;
+    case Instruction::Mul:  Out << " * "; break;
     case Instruction::URem:
     case Instruction::SRem:
-    case Instruction::FRem: Out << '%'; break;
+    case Instruction::FRem: Out << " % "; break;
     case Instruction::UDiv:
     case Instruction::SDiv: 
-    case Instruction::FDiv: Out << '/'; break;
-    case Instruction::And: Out << " & "; break;
-    case Instruction::Or: Out << " | "; break;
-    case Instruction::Xor: Out << " ^ "; break;
-    case Instruction::SetEQ: Out << " == "; break;
-    case Instruction::SetNE: Out << " != "; break;
-    case Instruction::SetLE: Out << " <= "; break;
-    case Instruction::SetGE: Out << " >= "; break;
-    case Instruction::SetLT: Out << " < "; break;
-    case Instruction::SetGT: Out << " > "; break;
+    case Instruction::FDiv: Out << " / "; break;
+    case Instruction::And:  Out << " & "; break;
+    case Instruction::Or:   Out << " | "; break;
+    case Instruction::Xor:  Out << " ^ "; break;
     case Instruction::Shl : Out << " << "; break;
     case Instruction::LShr:
     case Instruction::AShr: Out << " >> "; break;
@@ -2014,15 +2186,92 @@ void CWriter::visitBinaryOperator(Instruction &I) {
   }
 }
 
+void CWriter::visitICmpInst(ICmpInst &I) {
+  // We must cast the results of icmp which might be promoted.
+  bool needsCast = false;
+
+  // Write out the cast of the instruction's value back to the proper type
+  // if necessary.
+  bool NeedsClosingParens = writeInstructionCast(I);
+
+  // Certain icmp predicate require the operand to be forced to a specific type
+  // so we use writeOperandWithCast here instead of writeOperand. Similarly
+  // below for operand 1
+  writeOperandWithCast(I.getOperand(0), I.getPredicate());
+
+  switch (I.getPredicate()) {
+  case ICmpInst::ICMP_EQ:  Out << " == "; break;
+  case ICmpInst::ICMP_NE:  Out << " != "; break;
+  case ICmpInst::ICMP_ULE:
+  case ICmpInst::ICMP_SLE: Out << " <= "; break;
+  case ICmpInst::ICMP_UGE:
+  case ICmpInst::ICMP_SGE: Out << " >= "; break;
+  case ICmpInst::ICMP_ULT:
+  case ICmpInst::ICMP_SLT: Out << " < "; break;
+  case ICmpInst::ICMP_UGT:
+  case ICmpInst::ICMP_SGT: Out << " > "; break;
+  default: cerr << "Invalid icmp predicate!" << I; abort();
+  }
+
+  writeOperandWithCast(I.getOperand(1), I.getPredicate());
+  if (NeedsClosingParens)
+    Out << "))";
+
+  if (needsCast) {
+    Out << "))";
+  }
+}
+
+void CWriter::visitFCmpInst(FCmpInst &I) {
+  if (I.getPredicate() == FCmpInst::FCMP_FALSE) {
+    Out << "0";
+    return;
+  }
+  if (I.getPredicate() == FCmpInst::FCMP_TRUE) {
+    Out << "1";
+    return;
+  }
+
+  const char* op = 0;
+  switch (I.getPredicate()) {
+  default: assert(0 && "Illegal FCmp predicate");
+  case FCmpInst::FCMP_ORD: op = "ord"; break;
+  case FCmpInst::FCMP_UNO: op = "uno"; break;
+  case FCmpInst::FCMP_UEQ: op = "ueq"; break;
+  case FCmpInst::FCMP_UNE: op = "une"; break;
+  case FCmpInst::FCMP_ULT: op = "ult"; break;
+  case FCmpInst::FCMP_ULE: op = "ule"; break;
+  case FCmpInst::FCMP_UGT: op = "ugt"; break;
+  case FCmpInst::FCMP_UGE: op = "uge"; break;
+  case FCmpInst::FCMP_OEQ: op = "oeq"; break;
+  case FCmpInst::FCMP_ONE: op = "one"; break;
+  case FCmpInst::FCMP_OLT: op = "olt"; break;
+  case FCmpInst::FCMP_OLE: op = "ole"; break;
+  case FCmpInst::FCMP_OGT: op = "ogt"; break;
+  case FCmpInst::FCMP_OGE: op = "oge"; break;
+  }
+
+  Out << "llvm_fcmp_" << op << "(";
+  // Write the first operand
+  writeOperand(I.getOperand(0));
+  Out << ", ";
+  // Write the second operand
+  writeOperand(I.getOperand(1));
+  Out << ")";
+}
+
 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";
+    case Type::FloatTyID:  return "Float";
+    case Type::DoubleTyID: return "Double";
+    case Type::IntegerTyID: {
+      unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth();
+      if (NumBits <= 32)
+        return "Int32";
+      else
+        return "Int64";
+    }
   }
 }
 
@@ -2039,12 +2288,12 @@ void CWriter::visitCastInst(CastInst &I) {
         << getFloatBitCastField(I.getType());
   } else {
     printCast(I.getOpcode(), SrcTy, DstTy);
-    if (I.getOpcode() == Instruction::SExt && SrcTy == Type::BoolTy) {
+    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));
-    if (DstTy == Type::BoolTy && 
+    if (DstTy == Type::Int1Ty && 
         (I.getOpcode() == Instruction::Trunc ||
          I.getOpcode() == Instruction::FPToUI ||
          I.getOpcode() == Instruction::FPToSI ||
@@ -2102,7 +2351,7 @@ void CWriter::lowerIntrinsics(Function &F) {
             if (CI != &BB->front())
               Before = prior(BasicBlock::iterator(CI));
 
-            IL.LowerIntrinsicCall(CI);
+            IL->LowerIntrinsicCall(CI);
             if (Before) {        // Move iterator to instruction after call
               I = Before; ++I;
             } else {
@@ -2228,9 +2477,12 @@ void CWriter::visitCallInst(CallInst &I) {
 
   Value *Callee = I.getCalledValue();
 
+  const PointerType  *PTy   = cast<PointerType>(Callee->getType());
+  const FunctionType *FTy   = cast<FunctionType>(PTy->getElementType());
+
   // If this is a call to a struct-return function, assign to the first
   // parameter instead of passing it to the call.
-  bool isStructRet = I.getCallingConv() == CallingConv::CSRet;
+  bool isStructRet = FTy->isStructReturn();
   if (isStructRet) {
     Out << "*(";
     writeOperand(I.getOperand(1));
@@ -2238,9 +2490,6 @@ void CWriter::visitCallInst(CallInst &I) {
   }
   
   if (I.isTailCall()) Out << " /*tail*/ ";
-
-  const PointerType  *PTy   = cast<PointerType>(Callee->getType());
-  const FunctionType *FTy   = cast<FunctionType>(PTy->getElementType());
   
   if (!WroteCallee) {
     // If this is an indirect call to a struct return function, we need to cast
@@ -2292,12 +2541,14 @@ void CWriter::visitCallInst(CallInst &I) {
   }
       
   bool PrintedArg = false;
-  for (; AI != AE; ++AI, ++ArgNo) {
+  unsigned Idx = 1;
+  for (; AI != AE; ++AI, ++ArgNo, ++Idx) {
     if (PrintedArg) Out << ", ";
     if (ArgNo < NumDeclaredParams &&
         (*AI)->getType() != FTy->getParamType(ArgNo)) {
       Out << '(';
-      printType(Out, FTy->getParamType(ArgNo));
+      printType(Out, FTy->getParamType(ArgNo), 
+            /*isSigned=*/FTy->paramHasAttr(Idx, FunctionType::SExtAttribute));
       Out << ')';
     }
     writeOperand(*AI);
@@ -2514,7 +2765,7 @@ void CWriter::visitLoadInst(LoadInst &I) {
   Out << '*';
   if (I.isVolatile()) {
     Out << "((";
-    printType(Out, I.getType(), "volatile*");
+    printType(Out, I.getType(), false, "volatile*");
     Out << ")";
   }
 
@@ -2528,7 +2779,7 @@ void CWriter::visitStoreInst(StoreInst &I) {
   Out << '*';
   if (I.isVolatile()) {
     Out << "((";
-    printType(Out, I.getOperand(0)->getType(), " volatile*");
+    printType(Out, I.getOperand(0)->getType(), false, " volatile*");
     Out << ")";
   }
   writeOperand(I.getPointerOperand());