This is to fix the bug in IntrinsicLowering.cpp,
[oota-llvm.git] / lib / CodeGen / MachOWriter.cpp
index 0c743759da6c0aef0a4e80fc01edba2e1f9c514e..ef37db8ac9daaf501720384bc896a1342142c94f 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Nate Begeman and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/OutputBuffer.h"
 #include "llvm/Support/Streams.h"
+#include "llvm/Support/raw_ostream.h"
 #include <algorithm>
+#include <cstring>
 using namespace llvm;
 
 /// AddMachOWriter - Concrete function to add the Mach-O writer to the function
 /// pass manager.
-MachineCodeEmitter *llvm::AddMachOWriter(FunctionPassManager &FPM,
-                                         std::ostream &O,
+MachineCodeEmitter *llvm::AddMachOWriter(PassManagerBase &PM,
+                                         raw_ostream &O,
                                          TargetMachine &TM) {
   MachOWriter *MOW = new MachOWriter(O, TM);
-  FPM.add(MOW);
+  PM.add(MOW);
   return &MOW->getMachineCodeEmitter();
 }
 
@@ -73,7 +75,7 @@ namespace llvm {
     
     /// CPLocations - This is a map of constant pool indices to offsets from the
     /// start of the section for that constant pool index.
-    std::vector<intptr_t> CPLocations;
+    std::vector<uintptr_t> CPLocations;
 
     /// CPSections - This is a map of constant pool indices to the MachOSection
     /// containing the constant pool entry for that index.
@@ -81,12 +83,12 @@ namespace llvm {
 
     /// JTLocations - This is a map of jump table indices to offsets from the
     /// start of the section for that jump table index.
-    std::vector<intptr_t> JTLocations;
+    std::vector<uintptr_t> JTLocations;
 
     /// MBBLocations - This vector is a mapping from MBB ID's to their address.
     /// It is filled in by the StartMachineBasicBlock callback and queried by
     /// the getMachineBasicBlockAddress callback.
-    std::vector<intptr_t> MBBLocations;
+    std::vector<uintptr_t> MBBLocations;
     
   public:
     MachOCodeEmitter(MachOWriter &mow) : MOW(mow), TM(MOW.TM) {
@@ -104,11 +106,11 @@ namespace llvm {
     void emitConstantPool(MachineConstantPool *MCP);
     void emitJumpTables(MachineJumpTableInfo *MJTI);
     
-    virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const {
+    virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
       assert(CPLocations.size() > Index && "CP not emitted!");
       return CPLocations[Index];
     }
-    virtual intptr_t getJumpTableEntryAddress(unsigned Index) const {
+    virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
       assert(JTLocations.size() > Index && "JT not emitted!");
       return JTLocations[Index];
     }
@@ -119,18 +121,33 @@ namespace llvm {
       MBBLocations[MBB->getNumber()] = getCurrentPCOffset();
     }
 
-    virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
+    virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
       assert(MBBLocations.size() > (unsigned)MBB->getNumber() && 
              MBBLocations[MBB->getNumber()] && "MBB not emitted!");
       return MBBLocations[MBB->getNumber()];
     }
 
+    virtual uintptr_t getLabelAddress(uint64_t Label) const {
+      assert(0 && "get Label not implemented");
+      abort();
+      return 0;
+    }
+
+    virtual void emitLabel(uint64_t LabelID) {
+      assert(0 && "emit Label not implemented");
+      abort();
+    }
+
+
+    virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
+
     /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
-    virtual void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) {
+    virtual void startGVStub(const GlobalValue* F, unsigned StubSize,
+                             unsigned Alignment = 1) {
       assert(0 && "JIT specific function called!");
       abort();
     }
-    virtual void *finishFunctionStub(const Function *F) {
+    virtual void *finishGVStub(const GlobalValue* F) {
       assert(0 && "JIT specific function called!");
       abort();
       return 0;
@@ -247,8 +264,8 @@ void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
   if (CP.empty()) return;
 
   // FIXME: handle PIC codegen
-  bool isPIC = TM.getRelocationModel() == Reloc::PIC_;
-  assert(!isPIC && "PIC codegen not yet handled for mach-o jump tables!");
+  assert(TM.getRelocationModel() != Reloc::PIC_ &&
+         "PIC codegen not yet handled for mach-o jump tables!");
 
   // Although there is no strict necessity that I am aware of, we will do what
   // gcc for OS X does and put each constant pool entry in a section of constant
@@ -259,7 +276,7 @@ void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
   // "giant object for PIC" optimization.
   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
     const Type *Ty = CP[i].getType();
-    unsigned Size = TM.getTargetData()->getTypeSize(Ty);
+    unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty);
 
     MachOWriter::MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal);
     OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
@@ -288,8 +305,8 @@ void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
   if (JT.empty()) return;
 
   // FIXME: handle PIC codegen
-  bool isPIC = TM.getRelocationModel() == Reloc::PIC_;
-  assert(!isPIC && "PIC codegen not yet handled for mach-o jump tables!");
+  assert(TM.getRelocationModel() != Reloc::PIC_ &&
+         "PIC codegen not yet handled for mach-o jump tables!");
 
   MachOWriter::MachOSection *Sec = MOW.getJumpTableSection();
   unsigned TextSecIndex = MOW.getTextSection()->Index;
@@ -318,8 +335,8 @@ void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
 //===----------------------------------------------------------------------===//
 
 char MachOWriter::ID = 0;
-MachOWriter::MachOWriter(std::ostream &o, TargetMachine &tm) 
-  : MachineFunctionPass((intptr_t)&ID), O(o), TM(tm) {
+MachOWriter::MachOWriter(raw_ostream &o, TargetMachine &tm) 
+  : MachineFunctionPass(&ID), O(o), TM(tm) {
   is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
   isLittleEndian = TM.getTargetData()->isLittleEndian();
 
@@ -333,11 +350,9 @@ MachOWriter::~MachOWriter() {
 
 void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
   const Type *Ty = GV->getType()->getElementType();
-  unsigned Size = TM.getTargetData()->getTypeSize(Ty);
-  unsigned Align = GV->getAlignment();
-  if (Align == 0)
-    Align = TM.getTargetData()->getPrefTypeAlignment(Ty);
-  
+  unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty);
+  unsigned Align = TM.getTargetData()->getPreferredAlignment(GV);
+
   // Reserve space in the .bss section for this symbol while maintaining the
   // desired section alignment, which must be at least as much as required by
   // this symbol.
@@ -356,7 +371,7 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
       SecDataOut.outbyte(0);
   }
   // Globals without external linkage apparently do not go in the symbol table.
-  if (GV->getLinkage() != GlobalValue::InternalLinkage) {
+  if (!GV->hasLocalLinkage()) {
     MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TM);
     Sym.n_value = Sec->size;
     SymbolTable.push_back(Sym);
@@ -380,7 +395,7 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
 
 void MachOWriter::EmitGlobal(GlobalVariable *GV) {
   const Type *Ty = GV->getType()->getElementType();
-  unsigned Size = TM.getTargetData()->getTypeSize(Ty);
+  unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty);
   bool NoInit = !GV->hasInitializer();
   
   // If this global has a zero initializer, it is part of the .bss or common
@@ -389,7 +404,8 @@ void MachOWriter::EmitGlobal(GlobalVariable *GV) {
     // If this global is part of the common block, add it now.  Variables are
     // part of the common block if they are zero initialized and allowed to be
     // merged with other symbols.
-    if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) {
+    if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
+        GV->hasCommonLinkage()) {
       MachOSym ExtOrCommonSym(GV, Mang->getValueName(GV), MachOSym::NO_SECT,TM);
       // For undefined (N_UNDF) external (N_EXT) types, n_value is the size in
       // bytes of the symbol.
@@ -803,7 +819,8 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
     if (isa<UndefValue>(PC)) {
       continue;
     } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(PC)) {
-      unsigned ElementSize = TD->getTypeSize(CP->getType()->getElementType());
+      unsigned ElementSize =
+        TD->getTypePaddedSize(CP->getType()->getElementType());
       for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
         WorkList.push_back(CPair(CP->getOperand(i), PA+i*ElementSize));
     } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(PC)) {
@@ -824,7 +841,7 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
         abort();
         break;
       }
-    } else if (PC->getType()->isFirstClassType()) {
+    } else if (PC->getType()->isSingleValueType()) {
       unsigned char *ptr = (unsigned char *)PA;
       switch (PC->getType()->getTypeID()) {
       case Type::IntegerTyID: {
@@ -861,7 +878,7 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
         break;
       }
       case Type::FloatTyID: {
-        uint32_t val = cast<ConstantFP>(PC)->getValueAPF().convertToAPInt().
+        uint32_t val = cast<ConstantFP>(PC)->getValueAPF().bitcastToAPInt().
                         getZExtValue();
         if (TD->isBigEndian())
           val = ByteSwap_32(val);
@@ -872,7 +889,7 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
         break;
       }
       case Type::DoubleTyID: {
-        uint64_t val = cast<ConstantFP>(PC)->getValueAPF().convertToAPInt().
+        uint64_t val = cast<ConstantFP>(PC)->getValueAPF().bitcastToAPInt().
                          getZExtValue();
         if (TD->isBigEndian())
           val = ByteSwap_64(val);
@@ -904,9 +921,10 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
         abort();
       }
     } else if (isa<ConstantAggregateZero>(PC)) {
-      memset((void*)PA, 0, (size_t)TD->getTypeSize(PC->getType()));
+      memset((void*)PA, 0, (size_t)TD->getTypePaddedSize(PC->getType()));
     } else if (const ConstantArray *CPA = dyn_cast<ConstantArray>(PC)) {
-      unsigned ElementSize = TD->getTypeSize(CPA->getType()->getElementType());
+      unsigned ElementSize =
+        TD->getTypePaddedSize(CPA->getType()->getElementType());
       for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i)
         WorkList.push_back(CPair(CPA->getOperand(i), PA+i*ElementSize));
     } else if (const ConstantStruct *CPS = dyn_cast<ConstantStruct>(PC)) {
@@ -935,11 +953,15 @@ MachOSym::MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
     break;
   case GlobalValue::WeakLinkage:
   case GlobalValue::LinkOnceLinkage:
+  case GlobalValue::CommonLinkage:
     assert(!isa<Function>(gv) && "Unexpected linkage type for Function!");
   case GlobalValue::ExternalLinkage:
     GVName = TAI->getGlobalPrefix() + name;
     n_type |= GV->hasHiddenVisibility() ? N_PEXT : N_EXT;
     break;
+  case GlobalValue::PrivateLinkage:
+    GVName = TAI->getPrivateGlobalPrefix() + name;
+    break;
   case GlobalValue::InternalLinkage:
     GVName = TAI->getGlobalPrefix() + name;
     break;