Rip all of the global variable lowering logic out of TargetAsmInfo. Since
authorChris Lattner <sabre@nondot.org>
Tue, 28 Jul 2009 03:13:23 +0000 (03:13 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 28 Jul 2009 03:13:23 +0000 (03:13 +0000)
it is highly specific to the object file that will be generated in the end,
this introduces a new TargetLoweringObjectFile interface that is implemented
for each of ELF/MachO/COFF/Alpha/PIC16 and XCore.

Though still is still a brutal and ugly refactoring, this is a major step
towards goodness.

This patch also:
1. fixes a bunch of dangling pointer problems in the PIC16 backend.
2. disables the TargetLowering copy ctor which PIC16 was accidentally using.
3. gets us closer to xcore having its own crazy target section flags and
   pic16 not having to shadow sections with its own objects.
4. fixes wierdness where ELF targets would set CStringSection but not
   CStringSection_.  Factor the code better.
5. fixes some bugs in string lowering on ELF targets.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77294 91177308-0d34-0410-b5e6-96231b3b80d8

64 files changed:
include/llvm/CodeGen/AsmPrinter.h
include/llvm/Target/COFFTargetAsmInfo.h
include/llvm/Target/DarwinTargetAsmInfo.h
include/llvm/Target/ELFTargetAsmInfo.h
include/llvm/Target/TargetAsmInfo.h
include/llvm/Target/TargetLowering.h
include/llvm/Target/TargetLoweringObjectFile.h [new file with mode: 0644]
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
lib/CodeGen/ELFWriter.cpp
lib/CodeGen/SelectionDAG/TargetLowering.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMTargetAsmInfo.cpp
lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
lib/Target/Alpha/AlphaISelLowering.cpp
lib/Target/Alpha/AlphaTargetAsmInfo.cpp
lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
lib/Target/CMakeLists.txt
lib/Target/COFFTargetAsmInfo.cpp
lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
lib/Target/CellSPU/SPUISelLowering.cpp
lib/Target/CellSPU/SPUTargetAsmInfo.cpp
lib/Target/DarwinTargetAsmInfo.cpp
lib/Target/ELFTargetAsmInfo.cpp
lib/Target/MSP430/MSP430AsmPrinter.cpp
lib/Target/MSP430/MSP430ISelLowering.cpp
lib/Target/MSP430/MSP430TargetAsmInfo.cpp
lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsTargetAsmInfo.cpp
lib/Target/PIC16/CMakeLists.txt
lib/Target/PIC16/PIC16AsmPrinter.cpp
lib/Target/PIC16/PIC16AsmPrinter.h
lib/Target/PIC16/PIC16ISelLowering.cpp
lib/Target/PIC16/PIC16TargetAsmInfo.cpp
lib/Target/PIC16/PIC16TargetAsmInfo.h
lib/Target/PIC16/PIC16TargetObjectFile.cpp [new file with mode: 0644]
lib/Target/PIC16/PIC16TargetObjectFile.h [new file with mode: 0644]
lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCTargetAsmInfo.cpp
lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
lib/Target/Sparc/SparcISelLowering.cpp
lib/Target/Sparc/SparcTargetAsmInfo.cpp
lib/Target/Sparc/SparcTargetAsmInfo.h
lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
lib/Target/SystemZ/SystemZISelLowering.cpp
lib/Target/SystemZ/SystemZTargetAsmInfo.cpp
lib/Target/TargetAsmInfo.cpp
lib/Target/TargetLoweringObjectFile.cpp [new file with mode: 0644]
lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86TargetAsmInfo.cpp
lib/Target/X86/X86TargetAsmInfo.h
lib/Target/X86/X86TargetMachine.cpp
lib/Target/XCore/CMakeLists.txt
lib/Target/XCore/XCoreAsmPrinter.cpp
lib/Target/XCore/XCoreISelLowering.cpp
lib/Target/XCore/XCoreTargetAsmInfo.cpp
lib/Target/XCore/XCoreTargetAsmInfo.h
lib/Target/XCore/XCoreTargetObjectFile.cpp [new file with mode: 0644]
lib/Target/XCore/XCoreTargetObjectFile.h [new file with mode: 0644]

index 78de33fa72901e178f38756b08f26fc0c350fde4..6cd2d8ea4f82f5e2bd2649e145e070b888cca280 100644 (file)
@@ -39,6 +39,7 @@ namespace llvm {
   class Mangler;
   class Section;
   class TargetAsmInfo;
+  class TargetLoweringObjectFile;
   class Type;
   class formatted_raw_ostream;
 
@@ -75,6 +76,9 @@ namespace llvm {
     ///
     TargetMachine &TM;
     
+    /// getObjFileLowering - Return information about object file lowering.
+    const TargetLoweringObjectFile &getObjFileLowering() const;
+    
     /// Target Asm Printer information.
     ///
     const TargetAsmInfo *TAI;
index 4a60c0cce42d1163dafaab33449504386adce126..a035f2bb873200a89799c8d20cd6773a89c14efd 100644 (file)
@@ -16,15 +16,9 @@ namespace llvm {
   class COFFTargetAsmInfo : public TargetAsmInfo {
   protected:
     explicit COFFTargetAsmInfo(const TargetMachine &TM);
-  public:
-    virtual void getSectionFlagsAsString(SectionKind Kind,
-                                         SmallVectorImpl<char> &Str) const;
-    
-    virtual const Section *
-    SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind) const;
       
   };
 }
 
 
-#endif // LLVM_ELF_TARGET_ASM_INFO_H
+#endif // LLVM_COFF_TARGET_ASM_INFO_H
index 69bc551970db79e5cadc77322e97f5a5d89d2f5d..c934c05742c8bb18164b04ae5404861de48f266a 100644 (file)
@@ -24,27 +24,9 @@ namespace llvm {
   class Mangler;
 
   struct DarwinTargetAsmInfo : public TargetAsmInfo {
-    const Section* TextCoalSection;
-    const Section* ConstTextCoalSection;
-    const Section* ConstDataCoalSection;
-    const Section* ConstDataSection;
-    const Section* DataCoalSection;
-    const Section* FourByteConstantSection;
-    const Section* EightByteConstantSection;
-    const Section* SixteenByteConstantSection;
-
     explicit DarwinTargetAsmInfo(const TargetMachine &TM);
-    virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
-                                                  SectionKind Kind) const;
     virtual bool emitUsedDirectiveFor(const GlobalValue *GV,
                                       Mangler *Mang) const;
-
-    
-    virtual const Section *
-    getSectionForMergeableConstant(SectionKind Kind) const;
-    
-  private:
-    const Section* MergeableStringSection(const GlobalVariable *GV) const;
   };
 }
 
index 1b5bc54db62fc3c8d525aa3fb3bb17d2b9c86ed6..1b141d5181c076c2eef85d60af4a991415ca1e30 100644 (file)
@@ -21,29 +21,6 @@ namespace llvm {
 
   struct ELFTargetAsmInfo : public TargetAsmInfo {
     ELFTargetAsmInfo(const TargetMachine &TM);
-
-    /// getSectionForMergeableConstant - Given a mergeable constant with the
-    /// specified size and relocation information, return a section that it
-    /// should be placed in.
-    virtual const Section *
-    getSectionForMergeableConstant(SectionKind Kind) const;
-    
-    virtual SectionKind::Kind getKindForNamedSection(const char *Section,
-                                                     SectionKind::Kind K) const;
-    void getSectionFlagsAsString(SectionKind Kind,
-                                 SmallVectorImpl<char> &Str) const;
-    
-    virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
-                                                  SectionKind Kind) const;
-    
-    const Section *DataRelSection;
-    const Section *DataRelLocalSection;
-    const Section *DataRelROSection;
-    const Section *DataRelROLocalSection;
-
-    const Section *MergeableConst4Section;
-    const Section *MergeableConst8Section;
-    const Section *MergeableConst16Section;
   };
 }
 
index 9031dd21388ea337d7e92bbf5d18762b9d8ae850..95a6d539c8f821ff42fcbc13e2beee99bbc3229f 100644 (file)
@@ -214,15 +214,12 @@ namespace llvm {
   };
 
   class Section {
-    friend class TargetAsmInfo;
-    friend class StringMapEntry<Section>;
-    friend class StringMap<Section>;
+  public:
 
     std::string Name;
     SectionKind Kind;
-    explicit Section() { }
 
-  public:
+    explicit Section() { }
     const std::string &getName() const { return Name; }
     SectionKind getKind() const { return Kind; }
   };
@@ -230,8 +227,6 @@ namespace llvm {
   /// TargetAsmInfo - This class is intended to be used as a base class for asm
   /// properties and features specific to the target.
   class TargetAsmInfo {
-  private:
-    mutable StringMap<Section> Sections;
   protected:
     /// TM - The current TargetMachine.
     const TargetMachine &TM;
@@ -240,33 +235,11 @@ namespace llvm {
     // Properties to be set by the target writer, used to configure asm printer.
     //
 
-    /// TextSection - Section directive for standard text.
-    ///
-    const Section *TextSection;           // Defaults to ".text".
-
-    /// DataSection - Section directive for standard data.
-    ///
-    const Section *DataSection;           // Defaults to ".data".
-
     /// BSSSection - Section directive for uninitialized data.  Null if this
     /// target doesn't support a BSS section.
     ///
+/// FIXME: REMOVE.
     const char *BSSSection;               // Default to ".bss".
-    const Section *BSSSection_;
-
-    /// ReadOnlySection - This is the directive that is emitted to switch to a
-    /// read-only section for constant data (e.g. data declared const,
-    /// jump tables).
-    const Section *ReadOnlySection;       // Defaults to NULL
-
-    /// TLSDataSection - Section directive for Thread Local data.
-    ///
-    const Section *TLSDataSection;        // Defaults to ".tdata".
-
-    /// TLSBSSSection - Section directive for Thread Local uninitialized data.
-    /// Null if this target doesn't support a BSS section.
-    ///
-    const Section *TLSBSSSection;         // Defaults to ".tbss".
 
     /// ZeroFillDirective - Directive for emitting a global to the ZeroFill
     /// section on this target.  Null if this target doesn't support zerofill.
@@ -456,8 +429,8 @@ namespace llvm {
     /// cstring constants (null terminated string that does not contain any
     /// other null bytes) on this target. This is commonly supported as
     /// ".cstring".
+/// FIXME: REMOVE.
     const char *CStringSection;           // Defaults to NULL
-    const Section *CStringSection_;
 
     /// StaticCtorsSection - This is the directive that is emitted to switch to
     /// a section to emit the static constructor list.
@@ -642,10 +615,6 @@ namespace llvm {
     explicit TargetAsmInfo(const TargetMachine &TM);
     virtual ~TargetAsmInfo();
 
-    const Section *getOrCreateSection(const char *Name,
-                                      bool isDirective,
-                                      SectionKind::Kind K) const;
-
     /// Measure the specified inline asm to determine an approximation of its
     /// length.
     virtual unsigned getInlineAsmLength(const char *Str) const;
@@ -665,48 +634,6 @@ namespace llvm {
     virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
                                            bool Global) const;
 
-    
-    /// getSectionForMergeableConstant - Given a Mergeable constant with the
-    /// specified size and relocation information, return a section that it
-    /// should be placed in.
-    virtual const Section *getSectionForMergeableConstant(SectionKind Kind)const;
-
-    
-    /// getKindForNamedSection - If this target wants to be able to override
-    /// section flags based on the name of the section specified for a global
-    /// variable, it can implement this.  This is used on ELF systems so that
-    /// ".tbss" gets the TLS bit set etc.
-    virtual SectionKind::Kind getKindForNamedSection(const char *Section,
-                                                     SectionKind::Kind K) const{
-      return K;
-    }
-    
-    /// SectionForGlobal - This method computes the appropriate section to emit
-    /// the specified global variable or function definition.  This should not
-    /// be passed external (or available externally) globals.
-    // FIXME: MOVE TO ASMPRINTER.
-    const Section* SectionForGlobal(const GlobalValue *GV) const;
-    
-    /// getSpecialCasedSectionGlobals - Allow the target to completely override
-    /// section assignment of a global.
-    /// FIXME: ELIMINATE this by making PIC16 implement ADDRESS with
-    /// getFlagsForNamedSection.
-    virtual const Section *
-    getSpecialCasedSectionGlobals(const GlobalValue *GV,
-                                  SectionKind Kind) const {
-      return 0;
-    }
-    
-    /// getSectionFlagsAsString - Turn the flags in the specified SectionKind
-    /// into a string that can be printed to the assembly file after the
-    /// ".section foo" part of a section directive.
-    virtual void getSectionFlagsAsString(SectionKind Kind,
-                                         SmallVectorImpl<char> &Str) const {
-    }
-
-// FIXME: Eliminate this.
-    virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
-                                                  SectionKind Kind) const;
 
     /// getSLEB128Size - Compute the number of bytes required for a signed
     /// leb128 value.
@@ -734,27 +661,9 @@ namespace llvm {
 
     // Accessors.
     //
-    const Section *getTextSection() const {
-      return TextSection;
-    }
-    const Section *getDataSection() const {
-      return DataSection;
-    }
     const char *getBSSSection() const {
       return BSSSection;
     }
-    const Section *getBSSSection_() const {
-      return BSSSection_;
-    }
-    const Section *getReadOnlySection() const {
-      return ReadOnlySection;
-    }
-    const Section *getTLSDataSection() const {
-      return TLSDataSection;
-    }
-    const Section *getTLSBSSSection() const {
-      return TLSBSSSection;
-    }
     const char *getZeroFillDirective() const {
       return ZeroFillDirective;
     }
@@ -869,9 +778,6 @@ namespace llvm {
     const char *getCStringSection() const {
       return CStringSection;
     }
-    const Section *getCStringSection_() const {
-      return CStringSection_;
-    }
     const char *getStaticCtorsSection() const {
       return StaticCtorsSection;
     }
index 6c216c932c6399092c90e990db767c573ae13ec8..1dec92b9f921d1c0ee5e504568a1b67466642f41 100644 (file)
@@ -54,6 +54,7 @@ namespace llvm {
   class TargetMachine;
   class TargetRegisterClass;
   class TargetSubtarget;
+  class TargetLoweringObjectFile;
   class Value;
 
   // FIXME: should this be here?
@@ -77,6 +78,8 @@ namespace llvm {
 /// target-specific constructs to SelectionDAG operators.
 ///
 class TargetLowering {
+  TargetLowering(const TargetLowering&);  // DO NOT IMPLEMENT
+  void operator=(const TargetLowering&);  // DO NOT IMPLEMENT
 public:
   /// LegalizeAction - This enum indicates whether operations are valid for a
   /// target, and if not, what action should be used to make them valid.
@@ -98,11 +101,13 @@ public:
     SchedulingForRegPressure       // Scheduling for lowest register pressure.
   };
 
-  explicit TargetLowering(TargetMachine &TM);
+  /// NOTE: The constructor takes ownership of TLOF.
+  explicit TargetLowering(TargetMachine &TM, TargetLoweringObjectFile *TLOF);
   virtual ~TargetLowering();
 
   TargetMachine &getTargetMachine() const { return TM; }
   const TargetData *getTargetData() const { return TD; }
+  const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; }
 
   bool isBigEndian() const { return !IsLittleEndian; }
   bool isLittleEndian() const { return IsLittleEndian; }
@@ -1475,6 +1480,7 @@ public:
 private:
   TargetMachine &TM;
   const TargetData *TD;
+  TargetLoweringObjectFile &TLOF;
 
   /// PointerTy - The type to use for pointers, usually i32 or i64.
   ///
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
new file mode 100644 (file)
index 0000000..18ce1de
--- /dev/null
@@ -0,0 +1,187 @@
+//===-- llvm/Target/TargetLoweringObjectFile.h - Object Info ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
+#define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
+
+// FIXME: Switch to MC.
+#include "llvm/Target/TargetAsmInfo.h"
+
+namespace llvm {
+  
+class TargetLoweringObjectFile {
+private:
+  mutable StringMap<Section> Sections;
+protected:
+  
+  TargetLoweringObjectFile();
+  
+  /// TextSection - Section directive for standard text.
+  ///
+  const Section *TextSection;           // Defaults to ".text".
+  
+  /// DataSection - Section directive for standard data.
+  ///
+  const Section *DataSection;           // Defaults to ".data".
+  
+  
+  
+  // FIXME: SINK THESE.
+  const Section *BSSSection_;
+
+  /// ReadOnlySection - This is the directive that is emitted to switch to a
+  /// read-only section for constant data (e.g. data declared const,
+  /// jump tables).
+  const Section *ReadOnlySection;       // Defaults to NULL
+  
+  /// TLSDataSection - Section directive for Thread Local data.
+  ///
+  const Section *TLSDataSection;        // Defaults to ".tdata".
+  
+  /// TLSBSSSection - Section directive for Thread Local uninitialized data.
+  /// Null if this target doesn't support a BSS section.
+  ///
+  const Section *TLSBSSSection;         // Defaults to ".tbss".
+  
+  const Section *CStringSection_;
+  
+public:
+  // FIXME: NONPUB.
+  const Section *getOrCreateSection(const char *Name,
+                                    bool isDirective,
+                                    SectionKind::Kind K) const;
+public:
+  
+  virtual ~TargetLoweringObjectFile();
+  
+  const Section *getTextSection() const { return TextSection; }
+  const Section *getDataSection() const { return DataSection; }
+  
+  
+  /// getSectionForMergeableConstant - Given a mergeable constant with the
+  /// specified size and relocation information, return a section that it
+  /// should be placed in.
+  virtual const Section *
+  getSectionForMergeableConstant(SectionKind Kind) const;
+  
+  /// getKindForNamedSection - If this target wants to be able to override
+  /// section flags based on the name of the section specified for a global
+  /// variable, it can implement this.  This is used on ELF systems so that
+  /// ".tbss" gets the TLS bit set etc.
+  virtual SectionKind::Kind getKindForNamedSection(const char *Section,
+                                                   SectionKind::Kind K) const{
+    return K;
+  }
+  
+  /// SectionForGlobal - This method computes the appropriate section to emit
+  /// the specified global variable or function definition.  This should not
+  /// be passed external (or available externally) globals.
+  const Section *SectionForGlobal(const GlobalValue *GV,
+                                  const TargetMachine &TM) const;
+  
+  /// getSpecialCasedSectionGlobals - Allow the target to completely override
+  /// section assignment of a global.
+  /// FIXME: ELIMINATE this by making PIC16 implement ADDRESS with
+  /// getFlagsForNamedSection.
+  virtual const Section *
+  getSpecialCasedSectionGlobals(const GlobalValue *GV,
+                                SectionKind Kind) const {
+    return 0;
+  }
+  
+  /// getSectionFlagsAsString - Turn the flags in the specified SectionKind
+  /// into a string that can be printed to the assembly file after the
+  /// ".section foo" part of a section directive.
+  virtual void getSectionFlagsAsString(SectionKind Kind,
+                                       SmallVectorImpl<char> &Str) const {
+  }
+  
+protected:
+  virtual const Section *SelectSectionForGlobal(const GlobalValue *GV,
+                                                SectionKind Kind,
+                                                const TargetMachine &TM) const;
+};
+  
+  
+  
+
+class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
+  bool AtIsCommentChar;  // True if @ is the comment character on this target.
+public:
+  /// ELF Constructor - AtIsCommentChar is true if the CommentCharacter from TAI
+  /// is "@".
+  TargetLoweringObjectFileELF(bool AtIsCommentChar = false,
+                              // FIXME: REMOVE AFTER UNIQUING IS FIXED.
+                              bool HasCrazyBSS = false);
+  
+  /// getSectionForMergeableConstant - Given a mergeable constant with the
+  /// specified size and relocation information, return a section that it
+  /// should be placed in.
+  virtual const Section *
+  getSectionForMergeableConstant(SectionKind Kind) const;
+  
+  virtual SectionKind::Kind getKindForNamedSection(const char *Section,
+                                                   SectionKind::Kind K) const;
+  void getSectionFlagsAsString(SectionKind Kind,
+                               SmallVectorImpl<char> &Str) const;
+  
+  virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
+                                                SectionKind Kind,
+                                                const TargetMachine &TM) const;
+protected:
+  const Section *DataRelSection;
+  const Section *DataRelLocalSection;
+  const Section *DataRelROSection;
+  const Section *DataRelROLocalSection;
+  
+  const Section *MergeableConst4Section;
+  const Section *MergeableConst8Section;
+  const Section *MergeableConst16Section;
+};
+
+class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
+  const Section *TextCoalSection;
+  const Section *ConstTextCoalSection;
+  const Section *ConstDataCoalSection;
+  const Section *ConstDataSection;
+  const Section *DataCoalSection;
+  const Section *FourByteConstantSection;
+  const Section *EightByteConstantSection;
+  const Section *SixteenByteConstantSection;
+public:
+  TargetLoweringObjectFileMachO();
+  virtual const Section *SelectSectionForGlobal(const GlobalValue *GV,
+                                                SectionKind Kind,
+                                                const TargetMachine &TM) const;
+  
+  virtual const Section *
+  getSectionForMergeableConstant(SectionKind Kind) const;
+};
+
+
+
+class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
+public:
+  TargetLoweringObjectFileCOFF();
+  virtual void getSectionFlagsAsString(SectionKind Kind,
+                                       SmallVectorImpl<char> &Str) const;
+  
+  virtual const Section *
+  SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+                         const TargetMachine &TM) const;
+};
+
+} // end namespace llvm
+
+#endif
index 0303f26d8ee8cf7a5bc3d6f80ecb3d4577f2a10f..c9b500df08a4dd991bc50578e30111c437f1dcf6 100644 (file)
@@ -32,6 +32,7 @@
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -72,6 +73,11 @@ AsmPrinter::~AsmPrinter() {
   delete &OutContext;
 }
 
+const TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const {
+  return TM.getTargetLowering()->getObjFileLowering();
+}
+
+
 /// SwitchToTextSection - Switch to the specified text section of the executable
 /// if we are not already in it!
 ///
@@ -146,7 +152,8 @@ void AsmPrinter::SwitchToSection(const Section *NS) {
     // some magic assembler directive.
     if (NS->getKind().hasExplicitSection()) {
       SmallString<32> FlagsStr;
-      TAI->getSectionFlagsAsString(NS->getKind(), FlagsStr);
+      
+      getObjFileLowering().getSectionFlagsAsString(NS->getKind(), FlagsStr);
 
       O << TAI->getSwitchToSectionDirective()
         << CurrentSection
@@ -240,9 +247,6 @@ bool AsmPrinter::doFinalization(Module &M) {
   }
 
   if (TAI->getSetDirective()) {
-    if (!M.alias_empty())
-      SwitchToSection(TAI->getTextSection());
-
     O << '\n';
     for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
          I != E; ++I) {
@@ -339,7 +343,7 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) {
     }
     }
 
-    const Section *S = TAI->getSectionForMergeableConstant(Kind);
+    const Section *S =getObjFileLowering().getSectionForMergeableConstant(Kind);
     
     // The number of sections are small, just do a linear search from the
     // last section to the first.
@@ -410,8 +414,9 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI,
 
   const char* JumpTableDataSection = TAI->getJumpTableDataSection();
   const Function *F = MF.getFunction();
-  const Section *FuncSection = TAI->SectionForGlobal(F);
   
+  const Section *FuncSection = getObjFileLowering().SectionForGlobal(F, TM);
+
   bool JTInDiffSection = false;
   if ((IsPic && !(LoweringInfo && LoweringInfo->usesGlobalOffsetTable())) ||
       !JumpTableDataSection ||
index f26fb0d6fe9f999a4c80c93de6db21452137b94c..fea00f4f954ea4dba8fbe44d5801aeb4988ed125 100644 (file)
 #include "llvm/Support/Timer.h"
 #include "llvm/System/Path.h"
 #include "llvm/Target/TargetAsmInfo.h"
-#include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetRegisterInfo.h"
 using namespace llvm;
 
 static TimerGroup &getDwarfTimerGroup() {
@@ -1328,7 +1329,7 @@ void DwarfDebug::BeginModule(Module *M, MachineModuleInfo *mmi) {
   MMI->setDebugInfoAvailability(true);
 
   // Prime section data.
-  SectionMap.insert(TAI->getTextSection());
+  SectionMap.insert(Asm->getObjFileLowering().getTextSection());
 
   // Print out .file directives to specify files for .loc directives. These are
   // printed out early so that they precede any .loc directives.
@@ -1363,9 +1364,9 @@ void DwarfDebug::EndModule() {
     DebugTimer->startTimer();
 
   // Standard sections final addresses.
-  Asm->SwitchToSection(TAI->getTextSection());
+  Asm->SwitchToSection(Asm->getObjFileLowering().getTextSection());
   EmitLabel("text_end", 0);
-  Asm->SwitchToSection(TAI->getDataSection());
+  Asm->SwitchToSection(Asm->getObjFileLowering().getDataSection());
   EmitLabel("data_end", 0);
 
   // End text sections.
@@ -1893,9 +1894,9 @@ void DwarfDebug::EmitInitial() {
   Asm->SwitchToDataSection(TAI->getDwarfRangesSection());
   EmitLabel("section_ranges", 0);
 
-  Asm->SwitchToSection(TAI->getTextSection());
+  Asm->SwitchToSection(Asm->getObjFileLowering().getTextSection());
   EmitLabel("text_begin", 0);
-  Asm->SwitchToSection(TAI->getDataSection());
+  Asm->SwitchToSection(Asm->getObjFileLowering().getDataSection());
   EmitLabel("data_begin", 0);
 }
 
index b9a674d3e0bc195ca7a9cc464f785b9e5d161f25..a87fa9eaf69aed34500453fe197c70696e15c459 100644 (file)
@@ -20,8 +20,8 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetMachine.h"
-
 using namespace llvm;
 
 namespace {
@@ -64,10 +64,10 @@ static void EmitCamlGlobal(const Module &M, raw_ostream &OS, AsmPrinter &AP,
 
 void OcamlGCMetadataPrinter::beginAssembly(raw_ostream &OS, AsmPrinter &AP,
                                            const TargetAsmInfo &TAI) {
-  AP.SwitchToSection(TAI.getTextSection());
+  AP.SwitchToSection(AP.getObjFileLowering().getTextSection());
   EmitCamlGlobal(getModule(), OS, AP, TAI, "code_begin");
 
-  AP.SwitchToSection(TAI.getDataSection());
+  AP.SwitchToSection(AP.getObjFileLowering().getDataSection());
   EmitCamlGlobal(getModule(), OS, AP, TAI, "data_begin");
 }
 
@@ -99,16 +99,16 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
     AddressAlignLog = 3;
   }
 
-  AP.SwitchToSection(TAI.getTextSection());
+  AP.SwitchToSection(AP.getObjFileLowering().getTextSection());
   EmitCamlGlobal(getModule(), OS, AP, TAI, "code_end");
 
-  AP.SwitchToSection(TAI.getDataSection());
+  AP.SwitchToSection(AP.getObjFileLowering().getDataSection());
   EmitCamlGlobal(getModule(), OS, AP, TAI, "data_end");
 
   OS << AddressDirective << 0; // FIXME: Why does ocaml emit this??
   AP.EOL();
 
-  AP.SwitchToSection(TAI.getDataSection());
+  AP.SwitchToSection(AP.getObjFileLowering().getDataSection());
   EmitCamlGlobal(getModule(), OS, AP, TAI, "frametable");
 
   for (iterator I = begin(), IE = end(); I != IE; ++I) {
index 2679d983f44e3c1451cdc4d086fb7af9e1fdc6ed..fe2ba26244634857e78bbddba3fff75064f6d708 100644 (file)
@@ -45,6 +45,8 @@
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetELFWriterInfo.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Support/Streams.h"
@@ -185,7 +187,10 @@ ELFSection &ELFWriter::getConstantPoolSection(MachineConstantPoolEntry &CPE) {
     }
   }
 
-  return getSection(TAI->getSectionForMergeableConstant(Kind)->getName(),
+  const TargetLoweringObjectFile &TLOF =
+    TM.getTargetLowering()->getObjFileLowering();
+  
+  return getSection(TLOF.getSectionForMergeableConstant(Kind)->getName(),
                     ELFSection::SHT_PROGBITS,
                     ELFSection::SHF_MERGE | ELFSection::SHF_ALLOC,
                     CPE.getAlignment());
@@ -312,8 +317,11 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
     assert(isa<GlobalVariable>(GV) && "GV not a global variable!");
     const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
 
+    const TargetLoweringObjectFile &TLOF =
+      TM.getTargetLowering()->getObjFileLowering();
+
     // Get ELF section from TAI
-    const Section *S = TAI->SectionForGlobal(GV);
+    const Section *S = TLOF.SectionForGlobal(GV, TM);
     unsigned SectionFlags = getElfSectionFlags(S->getKind());
 
     // The symbol align should update the section alignment if needed
index fcc8f1bcda40513dd940e0413c98807962836b6c..85b47a001ebf259c611efac0b4cd87f2b1631816 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetSubtarget.h"
+#include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSubtarget.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
@@ -440,8 +441,9 @@ static void InitCmpLibcallCCs(ISD::CondCode *CCs) {
   CCs[RTLIB::O_F64] = ISD::SETEQ;
 }
 
-TargetLowering::TargetLowering(TargetMachine &tm)
-  : TM(tm), TD(TM.getTargetData()) {
+/// NOTE: The constructor takes ownership of TLOF.
+TargetLowering::TargetLowering(TargetMachine &tm,TargetLoweringObjectFile *tlof)
+  : TM(tm), TD(TM.getTargetData()), TLOF(*tlof) {
   // All operations default to being supported.
   memset(OpActions, 0, sizeof(OpActions));
   memset(LoadExtActions, 0, sizeof(LoadExtActions));
@@ -522,7 +524,9 @@ TargetLowering::TargetLowering(TargetMachine &tm)
     setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
 }
 
-TargetLowering::~TargetLowering() {}
+TargetLowering::~TargetLowering() {
+  delete &TLOF;
+}
 
 /// computeRegisterProperties - Once all of the register classes are added,
 /// this allows us to compute derived properties we expose.
index 226f1618c9a4dd60abcab9eba44341d74fa8c4e0..3b1be7642487dec2af51cac3f3e6856d83be1cd5 100644 (file)
@@ -34,6 +34,7 @@
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/ADT/VectorExtras.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -103,8 +104,14 @@ void ARMTargetLowering::addQRTypeForNEON(MVT VT) {
   addTypeForNEON(VT, MVT::v2f64, MVT::v4i32);
 }
 
+static TargetLoweringObjectFile *createTLOF(TargetMachine &TM) {
+  if (TM.getSubtarget<ARMSubtarget>().isTargetDarwin())
+    return new TargetLoweringObjectFileMachO();
+  return new TargetLoweringObjectFileELF(true);
+}
+
 ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
-    : TargetLowering(TM), ARMPCLabelIndex(0) {
+    : TargetLowering(TM, createTLOF(TM)), ARMPCLabelIndex(0) {
   Subtarget = &TM.getSubtarget<ARMSubtarget>();
 
   if (Subtarget->isTargetDarwin()) {
index 87f8a685640acf8691947d664220c7247cfbdea3..34c187492fdb5415725fc70b1444920fe6135de6 100644 (file)
@@ -59,8 +59,6 @@ ARMELFTargetAsmInfo::ARMELFTargetAsmInfo(const ARMBaseTargetMachine &TM):
   ARMTargetAsmInfo<ELFTargetAsmInfo>(TM) {
   Subtarget = &TM.getSubtarget<ARMSubtarget>();
 
-  BSSSection_ = getOrCreateSection("\t.bss", true, SectionKind::BSS);
-
   NeedsSet = false;
   HasLEB128 = true;
   AbsoluteDebugSectionOffsets = true;
index 1154aaf71447cfde64b5ad7755c9fc2768a4685f..d82b7585f23583ac6898468ddad0f3b42df6dbb9 100644 (file)
@@ -29,6 +29,7 @@
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Target/TargetRegistry.h"
@@ -1127,7 +1128,7 @@ void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
   if (Subtarget->isTargetELF())
     O << "\t.type " << name << ",%object\n";
   
-  const Section *TheSection = TAI->SectionForGlobal(GVar);
+  const Section *TheSection = getObjFileLowering().SectionForGlobal(GVar, TM);
   SwitchToSection(TheSection);
 
   // FIXME: get this stuff from section kind flags.
@@ -1154,7 +1155,7 @@ void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
           O << TAI->getCOMMDirective()  << name << "," << Size
             << ',' << Align;
         } else {
-          SwitchToSection(TAI->SectionForGlobal(GVar));
+          SwitchToSection(getObjFileLowering().SectionForGlobal(GVar, TM));
           O << "\t.globl " << name << '\n'
             << TAI->getWeakDefDirective() << name << '\n';
           EmitAlignment(Align, GVar);
@@ -1285,7 +1286,7 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
     }
 
     if (!HiddenGVNonLazyPtrs.empty()) {
-      SwitchToSection(TAI->getDataSection());
+      SwitchToSection(getObjFileLowering().getDataSection());
       for (StringMap<std::string>::iterator I = HiddenGVNonLazyPtrs.begin(),
              E = HiddenGVNonLazyPtrs.end(); I != E; ++I) {
         EmitAlignment(2);
index 310a4a6b0374846cf0120f0e8d6290602683764e..f7a38c2a480cf8efbf6d731c6827c24e1d0f324f 100644 (file)
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Constants.h"
 #include "llvm/Function.h"
 #include "llvm/Module.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 
+
+class TargetLoweringObjectFileAlpha : public TargetLoweringObjectFile {
+public:
+  TargetLoweringObjectFileAlpha() {
+    TextSection = getOrCreateSection("_text", true, SectionKind::Text);
+    DataSection = getOrCreateSection("_data", true, SectionKind::DataRel);
+  }
+};
+  
+  
+
 /// AddLiveIn - This helper function adds the specified physical register to the
 /// MachineFunction as a live in value.  It also creates a corresponding virtual
 /// register for it.
@@ -41,7 +53,8 @@ static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
   return VReg;
 }
 
-AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) {
+AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM)
+  : TargetLowering(TM, new TargetLoweringObjectFileAlpha()) {
   // Set up the TargetLowering object.
   //I am having problems with shr n i8 1
   setShiftAmountType(MVT::i64);
index 12fadfb5423d1fcd4ecf3880330bcaf9367d12a3..649955224223b65b9ad47c50e12e3b4adf86ad0a 100644 (file)
@@ -23,7 +23,4 @@ AlphaTargetAsmInfo::AlphaTargetAsmInfo(const AlphaTargetMachine &TM)
   JumpTableDirective = ".gprel32";
   JumpTableDataSection = "\t.section .rodata\n";
   WeakRefDirective = "\t.weak\t";
-    
-  TextSection = getOrCreateSection("_text", true, SectionKind::Text);
-  DataSection = getOrCreateSection("_data", true, SectionKind::DataRel);
 }
index 08a2c3430e29920c97445e18e1fe5bceee8356c9..a37dee7d0c6437ba8fabbc43236f9ea409d41ad4 100644 (file)
@@ -23,6 +23,7 @@
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/DwarfWriter.h"
 #include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetRegistry.h"
 #include "llvm/Support/Compiler.h"
@@ -138,7 +139,7 @@ bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   // Print out labels for the function.
   const Function *F = MF.getFunction();
-  SwitchToSection(TAI->SectionForGlobal(F));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(F, TM));
 
   EmitAlignment(MF.getAlignment(), F);
   switch (F->getLinkage()) {
@@ -214,7 +215,7 @@ void AlphaAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
   unsigned Align = TD->getPreferredAlignmentLog(GVar);
 
   // 0: Switch to section
-  SwitchToSection(TAI->SectionForGlobal(GVar));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(GVar, TM));
 
   // 1: Check visibility
   printVisibility(name, GVar->getVisibility());
index 98df86cc82040a99922f32a75283103c9df294ef..f5c94f22e8061153e03b683d9bd53c1584b8e4c1 100644 (file)
@@ -10,6 +10,7 @@ add_llvm_library(LLVMTarget
   TargetFrameInfo.cpp
   TargetInstrInfo.cpp
   TargetIntrinsicInfo.cpp
+  TargetLoweringObjectFile.cpp
   TargetMachOWriterInfo.cpp
   TargetMachine.cpp
   TargetRegisterInfo.cpp
index cd7356d55116d9e7cc376821eb7ac6c318f787b9..f1f742e787b0a7e8d5b21997f24f35e7643ef525 100644 (file)
@@ -19,9 +19,6 @@ using namespace llvm;
 COFFTargetAsmInfo::COFFTargetAsmInfo(const TargetMachine &TM)
   : TargetAsmInfo(TM) {
 
-  TextSection = getOrCreateSection("_text", true, SectionKind::Text);
-  DataSection = getOrCreateSection("_data", true, SectionKind::DataRel);
-
   GlobalPrefix = "_";
   LCOMMDirective = "\t.lcomm\t";
   COMMDirectiveTakesAlignment = false;
@@ -53,57 +50,3 @@ COFFTargetAsmInfo::COFFTargetAsmInfo(const TargetMachine &TM)
   DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"dr\"";
 }
 
-void COFFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
-                                            SmallVectorImpl<char> &Str) const {
-  // FIXME: Inefficient.
-  std::string Res = ",\"";
-  if (Kind.isText())
-    Res += 'x';
-  if (Kind.isWriteable())
-    Res += 'w';
-  Res += "\"";
-  
-  Str.append(Res.begin(), Res.end());
-}
-
-//===----------------------------------------------------------------------===//
-// Move to AsmPrinter (mangler access).
-//===----------------------------------------------------------------------===//
-
-#include "llvm/GlobalVariable.h"
-
-static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
-  if (Kind.isText())
-    return ".text$linkonce";
-  if (Kind.isWriteable())
-    return ".data$linkonce";
-  return ".rdata$linkonce";
-}
-
-const Section *
-COFFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
-                                          SectionKind Kind) const {
-  assert(!Kind.isThreadLocal() && "Doesn't support TLS");
-  
-  // If this global is linkonce/weak and the target handles this by emitting it
-  // into a 'uniqued' section name, create and return the section now.
-  if (Kind.isWeak()) {
-    const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
-    // FIXME: Use mangler interface (PR4584).
-    std::string Name = Prefix+GV->getNameStr();
-    return getOrCreateSection(Name.c_str(), false, Kind.getKind());
-  }
-  
-  if (Kind.isText())
-    return getTextSection();
-  
-  if (Kind.isBSS())
-    if (const Section *S = getBSSSection_())
-      return S;
-  
-  if (Kind.isReadOnly())
-    if (const Section *S = getReadOnlySection())
-      return S;
-  
-  return getDataSection();
-}
index fd1df767dc7bbfa2ec8d6db3edb4026c305ae59a..e53543c43662b89d42e00c82eff3742cfb458c1d 100644 (file)
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Target/TargetAsmInfo.h"
-#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetRegistry.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
@@ -427,7 +428,7 @@ LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF)
   // Print out labels for the function.
   const Function *F = MF.getFunction();
 
-  SwitchToSection(TAI->SectionForGlobal(F));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(F, TM));
   EmitAlignment(MF.getAlignment(), F);
 
   switch (F->getLinkage()) {
@@ -525,7 +526,7 @@ void LinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
   unsigned Size = TD->getTypeAllocSize(Type);
   unsigned Align = TD->getPreferredAlignmentLog(GVar);
 
-  SwitchToSection(TAI->SectionForGlobal(GVar));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(GVar, TM));
 
   if (C->isNullValue() && /* FIXME: Verify correct */
       !GVar->hasSection() &&
index d0aad070c2587b62d6c900c0e45c14b0d3218c91..50ba00f63675302c94f8b4922e2b742b9384c66e 100644 (file)
@@ -15,8 +15,9 @@
 #include "SPUISelLowering.h"
 #include "SPUTargetMachine.h"
 #include "SPUFrameInfo.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/VectorExtras.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Intrinsics.h"
 #include "llvm/CallingConv.h"
 #include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/Intrinsics.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/ADT/VectorExtras.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetOptions.h"
-
 #include <map>
 
 using namespace llvm;
@@ -125,9 +124,8 @@ namespace {
 }
 
 SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
-  : TargetLowering(TM),
-    SPUTM(TM)
-{
+  : TargetLowering(TM, new TargetLoweringObjectFileELF()),
+    SPUTM(TM) {
   // Fold away setcc operations if possible.
   setPow2DivIsCheap();
 
index 534d18e60fc71cc942caf22b4e9645940ca0df4e..1d716059540b5e9c82d0a3b1b943efa7e5587dd1 100644 (file)
@@ -33,10 +33,6 @@ SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo(const SPUTargetMachine &TM) :
   HasLEB128 = true;
   HasDotLocAndDotFile = true;
 
-  // BSS section needs to be emitted as ".section"
-  BSSSection = "\t.section\t.bss";
-  BSSSection_ = getOrCreateSection("\t.bss", false, SectionKind::BSS);
-
   SupportsDebugInformation = true;
   NeedsSet = true;
   DwarfAbbrevSection =  "\t.section        .debug_abbrev,\"\",@progbits";
index 5429e659268020f625637a4d46981a6de658f13b..aa93c0d11960d4b2a2dfb7506a530bd84a39f0e9 100644 (file)
@@ -27,32 +27,7 @@ using namespace llvm;
 
 DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM) 
   : TargetAsmInfo(TM) {
-  TextSection = getOrCreateSection("\t.text", true, SectionKind::Text);
-  DataSection = getOrCreateSection("\t.data", true, SectionKind::DataRel);
-
-  CStringSection_ = getOrCreateSection("\t.cstring", true,
-                                       SectionKind::MergeableCString);
-  FourByteConstantSection = getOrCreateSection("\t.literal4\n", true,
-                                               SectionKind::MergeableConst4);
-  EightByteConstantSection = getOrCreateSection("\t.literal8\n", true,
-                                                SectionKind::MergeableConst8);
-  SixteenByteConstantSection = 
-    getOrCreateSection("\t.literal16\n", true, SectionKind::MergeableConst16);
-
-  ReadOnlySection = getOrCreateSection("\t.const", true, SectionKind::ReadOnly);
-
-  TextCoalSection =
-    getOrCreateSection("\t__TEXT,__textcoal_nt,coalesced,pure_instructions",
-                       false, SectionKind::Text);
-  ConstTextCoalSection = getOrCreateSection("\t__TEXT,__const_coal,coalesced",
-                                            false, SectionKind::Text);
-  ConstDataCoalSection = getOrCreateSection("\t__DATA,__const_coal,coalesced",
-                                            false, SectionKind::Text);
-  ConstDataSection = getOrCreateSection("\t.const_data", true,
-                                        SectionKind::ReadOnlyWithRel);
-  DataCoalSection = getOrCreateSection("\t__DATA,__datacoal_nt,coalesced",
-                                       false, SectionKind::DataRel);
-  
   // Common settings for all Darwin targets.
   // Syntax:
   GlobalPrefix = "_";
@@ -124,79 +99,3 @@ bool DarwinTargetAsmInfo::emitUsedDirectiveFor(const GlobalValue* GV,
   return true;
 }
 
-const Section*
-DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
-                                            SectionKind Kind) const {
-  assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS");
-  
-  if (Kind.isText())
-    return Kind.isWeak() ? TextCoalSection : TextSection;
-  
-  // If this is weak/linkonce, put this in a coalescable section, either in text
-  // or data depending on if it is writable.
-  if (Kind.isWeak()) {
-    if (Kind.isReadOnly())
-      return ConstTextCoalSection;
-    return DataCoalSection;
-  }
-  
-  // FIXME: Alignment check should be handled by section classifier.
-  if (Kind.isMergeableCString())
-    return MergeableStringSection(cast<GlobalVariable>(GV));
-  
-  if (Kind.isMergeableConst()) {
-    if (Kind.isMergeableConst4())
-      return FourByteConstantSection;
-    if (Kind.isMergeableConst8())
-      return EightByteConstantSection;
-    if (Kind.isMergeableConst16())
-      return SixteenByteConstantSection;
-    return ReadOnlySection;  // .const
-  }
-  
-  // FIXME: ROData -> const in -static mode that is relocatable but they happen
-  // by the static linker.  Why not mergeable?
-  if (Kind.isReadOnly())
-    return getReadOnlySection();
-
-  // If this is marked const, put it into a const section.  But if the dynamic
-  // linker needs to write to it, put it in the data segment.
-  if (Kind.isReadOnlyWithRel())
-    return ConstDataSection;
-  
-  // Otherwise, just drop the variable in the normal data section.
-  return DataSection;
-}
-
-const Section*
-DarwinTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const {
-  const TargetData *TD = TM.getTargetData();
-  Constant *C = cast<GlobalVariable>(GV)->getInitializer();
-  const Type *Ty = cast<ArrayType>(C->getType())->getElementType();
-
-  unsigned Size = TD->getTypeAllocSize(Ty);
-  if (Size) {
-    unsigned Align = TD->getPreferredAlignment(GV);
-    if (Align <= 32)
-      return getCStringSection_();
-  }
-
-  return getReadOnlySection();
-}
-
-const Section *
-DarwinTargetAsmInfo::getSectionForMergeableConstant(SectionKind Kind) const {
-  // If this constant requires a relocation, we have to put it in the data
-  // segment, not in the text segment.
-  if (Kind.isDataRel())
-    return ConstDataSection;
-  
-  if (Kind.isMergeableConst4())
-    return FourByteConstantSection;
-  if (Kind.isMergeableConst8())
-    return EightByteConstantSection;
-  if (Kind.isMergeableConst16())
-    return SixteenByteConstantSection;
-  return ReadOnlySection;  // .const
-}
-
index 556b494185ed70d02c8e450fcf9697c8cf54985f..e3259bd916e0cf7b4ff93460354a656985cb7ba4 100644 (file)
@@ -18,217 +18,4 @@ using namespace llvm;
 
 ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM)
   : TargetAsmInfo(TM) {
-    
-  TextSection = getOrCreateSection("\t.text", true, SectionKind::Text);
-  DataSection = getOrCreateSection("\t.data", true, SectionKind::DataRel);
-  ReadOnlySection =
-    getOrCreateSection("\t.rodata", false, SectionKind::ReadOnly);
-  TLSDataSection =
-    getOrCreateSection("\t.tdata", false, SectionKind::ThreadData);
-  TLSBSSSection = getOrCreateSection("\t.tbss", false, SectionKind::ThreadBSS);
-
-  DataRelSection = getOrCreateSection("\t.data.rel", false,
-                                      SectionKind::DataRel);
-  DataRelLocalSection = getOrCreateSection("\t.data.rel.local", false,
-                                           SectionKind::DataRelLocal);
-  DataRelROSection = getOrCreateSection("\t.data.rel.ro", false,
-                                        SectionKind::ReadOnlyWithRel);
-  DataRelROLocalSection =
-    getOrCreateSection("\t.data.rel.ro.local", false,
-                       SectionKind::ReadOnlyWithRelLocal);
-    
-  MergeableConst4Section = getOrCreateSection(".rodata.cst4", false,
-                                              SectionKind::MergeableConst4);
-  MergeableConst8Section = getOrCreateSection(".rodata.cst8", false,
-                                              SectionKind::MergeableConst8);
-  MergeableConst16Section = getOrCreateSection(".rodata.cst16", false,
-                                               SectionKind::MergeableConst16);
-}
-
-/// getFlagsForNamedSection - If this target wants to be able to infer
-/// section flags based on the name of the section specified for a global
-/// variable, it can implement this.
-SectionKind::Kind ELFTargetAsmInfo::getKindForNamedSection(const char *Name,
-                                                   SectionKind::Kind K) const {
-  if (Name[0] != '.') return K;
-  
-  // Some lame default implementation based on some magic section names.
-  if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
-      strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
-      strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
-      strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
-    return SectionKind::BSS;
-  
-  if (strcmp(Name, ".tdata") == 0 ||
-      strncmp(Name, ".tdata.", 7) == 0 ||
-      strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
-      strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
-    return SectionKind::ThreadData;
-  
-  if (strcmp(Name, ".tbss") == 0 ||
-      strncmp(Name, ".tbss.", 6) == 0 ||
-      strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
-      strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
-    return SectionKind::ThreadBSS;
-  
-  return K;
-}
-
-
-void ELFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
-                                             SmallVectorImpl<char> &Str) const {
-  Str.push_back(',');
-  Str.push_back('"');
-  
-  if (!Kind.isMetadata())
-    Str.push_back('a');
-  if (Kind.isText())
-    Str.push_back('x');
-  if (Kind.isWriteable())
-    Str.push_back('w');
-  if (Kind.isMergeableConst() || Kind.isMergeableCString())
-    Str.push_back('M');
-  if (Kind.isMergeableCString())
-    Str.push_back('S');
-  if (Kind.isThreadLocal())
-    Str.push_back('T');
-
-  Str.push_back('"');
-  Str.push_back(',');
-
-  // If comment string is '@', e.g. as on ARM - use '%' instead
-  if (strcmp(CommentString, "@") == 0)
-    Str.push_back('%');
-  else
-    Str.push_back('@');
-
-  const char *KindStr;
-  if (Kind.isBSS())
-    KindStr = "nobits";
-  else
-    KindStr = "progbits";
-  
-  Str.append(KindStr, KindStr+strlen(KindStr));
-
-  if (Kind.isMergeableCString()) {
-    // TODO: Eventually handle multiple byte character strings.  For now, all
-    // mergable C strings are single byte.
-    Str.push_back(',');
-    Str.push_back('1');
-  } else if (Kind.isMergeableConst4()) {
-    Str.push_back(',');
-    Str.push_back('4');
-  } else if (Kind.isMergeableConst8()) {
-    Str.push_back(',');
-    Str.push_back('8');
-  } else if (Kind.isMergeableConst16()) {
-    Str.push_back(',');
-    Str.push_back('1');
-    Str.push_back('6');
-  }
 }
-
-
-
-//===----------------------------------------------------------------------===//
-// Move to AsmPrinter (mangler access).
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DerivedTypes.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/ADT/StringExtras.h"
-
-static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
-  if (Kind.isText())                 return ".gnu.linkonce.t.";
-  if (Kind.isReadOnly())             return ".gnu.linkonce.r.";
-  
-  if (Kind.isThreadData())           return ".gnu.linkonce.td.";
-  if (Kind.isThreadBSS())            return ".gnu.linkonce.tb.";
-  
-  if (Kind.isBSS())                  return ".gnu.linkonce.b.";
-  if (Kind.isDataNoRel())            return ".gnu.linkonce.d.";
-  if (Kind.isDataRelLocal())         return ".gnu.linkonce.d.rel.local.";
-  if (Kind.isDataRel())              return ".gnu.linkonce.d.rel.";
-  if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
-  
-  assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
-  return ".gnu.linkonce.d.rel.ro.";
-}
-
-const Section*
-ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
-                                         SectionKind Kind) const {
-  
-  // If this global is linkonce/weak and the target handles this by emitting it
-  // into a 'uniqued' section name, create and return the section now.
-  if (Kind.isWeak()) {
-    const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
-    // FIXME: Use mangler interface (PR4584).
-    std::string Name = Prefix+GV->getNameStr();
-    return getOrCreateSection(Name.c_str(), false, Kind.getKind());
-  }
-  
-  if (Kind.isText()) return TextSection;
-  if (Kind.isMergeableCString()) {
-    const TargetData *TD = TM.getTargetData();
-    Constant *C = cast<GlobalVariable>(GV)->getInitializer();
-    const Type *Ty = cast<ArrayType>(C->getType())->getElementType();
-    
-    unsigned Size = TD->getTypeAllocSize(Ty);
-    if (Size <= 16) {
-      assert(getCStringSection() && "Should have string section prefix");
-      
-      // We also need alignment here.
-      // FIXME: this is getting the alignment of the character, not the
-      // alignment of the string!!
-      unsigned Align = TD->getPrefTypeAlignment(Ty);
-      if (Align < Size)
-        Align = Size;
-      
-      std::string Name = getCStringSection() + utostr(Size) + '.' +
-      utostr(Align);
-      return getOrCreateSection(Name.c_str(), false,
-                                SectionKind::MergeableCString);
-    }
-    
-    return getReadOnlySection();
-  }
-  
-  if (Kind.isMergeableConst()) {
-    if (Kind.isMergeableConst4())
-      return MergeableConst4Section;
-    if (Kind.isMergeableConst8())
-      return MergeableConst8Section;
-    if (Kind.isMergeableConst16())
-      return MergeableConst16Section;
-    return ReadOnlySection;  // .const
-  }
-  
-  if (Kind.isReadOnly())             return getReadOnlySection();
-  
-  
-  if (Kind.isThreadData())           return TLSDataSection;
-  if (Kind.isThreadBSS())            return TLSBSSSection;
-  
-  if (Kind.isBSS())                  return getBSSSection_();
-  
-  
-  if (Kind.isDataNoRel())            return DataSection;
-  if (Kind.isDataRelLocal())         return DataRelLocalSection;
-  if (Kind.isDataRel())              return DataRelSection;
-  if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
-  
-  assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
-  return DataRelROSection;
-}
-
-/// getSectionForMergeableConstant - Given a Mergeable constant with the
-/// specified size and relocation information, return a section that it
-/// should be placed in.
-const Section *
-ELFTargetAsmInfo::getSectionForMergeableConstant(SectionKind Kind) const {
-  return SelectSectionForGlobal(0, Kind);
-}
-
index bb112bc25502fb3a5c430c1b4f85cdd63c70fb42..81bc81b52de81d80d3f891365da42176b17f4b14 100644 (file)
@@ -27,6 +27,7 @@
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetRegistry.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/Compiler.h"
@@ -77,7 +78,7 @@ namespace {
 void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
   const Function *F = MF.getFunction();
 
-  SwitchToSection(TAI->SectionForGlobal(F));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(F, TM));
 
   unsigned FnAlign = MF.getAlignment();
   EmitAlignment(FnAlign, F);
index 7476db92145f6f323c1c04af91ef9dc6219ab763..9413060f08574fcafd1287a6fdedeaeb246b4d7e 100644 (file)
 #include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/ADT/VectorExtras.h"
 using namespace llvm;
 
 MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
-  TargetLowering(tm), Subtarget(*tm.getSubtargetImpl()), TM(tm) {
+  TargetLowering(tm, new TargetLoweringObjectFileELF()),
+  Subtarget(*tm.getSubtargetImpl()), TM(tm) {
 
   // Set up the register classes.
   addRegisterClass(MVT::i8,  MSP430::GR8RegisterClass);
index cd3cdcff06d8ad84dae30737e8f417be3e9c6f2f..43a521d3768220debb54111832aeb51953bb6a4e 100644 (file)
@@ -17,6 +17,4 @@ using namespace llvm;
 MSP430TargetAsmInfo::MSP430TargetAsmInfo(const TargetMachine &TM)
   : ELFTargetAsmInfo(TM) {
   AlignmentIsInBytes = false;
-    
-  BSSSection_ = getOrCreateSection("\t.bss", true, SectionKind::BSS);
 }
index 9eda5e222cf5cc89dd57e06ca24b5aeb26389173..d0f0487dcf81c768cc692e4dc5d6bce7806cb5ce 100644 (file)
@@ -31,6 +31,7 @@
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLoweringObjectFile.h" 
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Target/TargetRegistry.h"
@@ -211,12 +212,10 @@ emitCurrentABIString(void)
 }  
 
 /// Emit the directives used by GAS on the start of functions
-void MipsAsmPrinter::
-emitFunctionStart(MachineFunction &MF)
-{
+void MipsAsmPrinter::emitFunctionStart(MachineFunction &MF) {
   // Print out the label for the function.
   const Function *F = MF.getFunction();
-  SwitchToSection(TAI->SectionForGlobal(F));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(F, TM));
 
   // 2 bits aligned
   EmitAlignment(MF.getAlignment(), F);
@@ -485,7 +484,7 @@ void MipsAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
 
   printVisibility(name, GVar->getVisibility());
 
-  SwitchToSection(TAI->SectionForGlobal(GVar));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(GVar, TM));
 
   if (C->isNullValue() && !GVar->hasSection()) {
     if (!GVar->isThreadLocal() &&
index f6d171b367abb9074b6780bac124a7ce4c6c829d..ca94d39e4674470199c6562535158b165c04b783 100644 (file)
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 using namespace llvm;
 
-const char *MipsTargetLowering::
-getTargetNodeName(unsigned Opcode) const 
-{
-  switch (Opcode) 
-  {
+const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
+  switch (Opcode) {
     case MipsISD::JmpLink    : return "MipsISD::JmpLink";
     case MipsISD::Hi         : return "MipsISD::Hi";
     case MipsISD::Lo         : return "MipsISD::Lo";
@@ -55,8 +53,8 @@ getTargetNodeName(unsigned Opcode) const
 }
 
 MipsTargetLowering::
-MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM) 
-{
+MipsTargetLowering(MipsTargetMachine &TM)
+  : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
   Subtarget = &TM.getSubtarget<MipsSubtarget>();
 
   // Mips does not have i1 type, so use i32 for
index 26f4b3b9ee14b49f31ffdd309f3bbc6e58629a78..1fa02f297de91442e698e08a0c29b2f516168633 100644 (file)
@@ -30,8 +30,6 @@ MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM)
   BSSSection                  = "\t.section\t.bss";
   CStringSection              = ".rodata.str";
 
-  BSSSection_ = getOrCreateSection("\t.bss", true, SectionKind::BSS);
-    
   if (!TM.getSubtarget<MipsSubtarget>().hasABICall())
     JumpTableDirective = "\t.word\t";
   else
index 00d737af4c2ef68d064420a9316365ce55d369d4..ba1dfb45fc213160e5a02b723a65b88a668e043c 100644 (file)
@@ -21,4 +21,5 @@ add_llvm_target(PIC16
   PIC16Subtarget.cpp
   PIC16TargetAsmInfo.cpp
   PIC16TargetMachine.cpp
+  PIC16TargetObjectFile.cpp
   )
index ec86585c1dba278eacd76af8c38d9b98cbb789b6..7fad6f315683a35337a4e638d484a7c90abf4286 100644 (file)
 #include "llvm/CodeGen/DwarfWriter.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/Target/TargetRegistry.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 
 using namespace llvm;
 
 #include "PIC16GenAsmWriter.inc"
 
+PIC16AsmPrinter::PIC16AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
+                                 const TargetAsmInfo *T, bool V)
+: AsmPrinter(O, TM, T, V), DbgInfo(O, T) {
+  PTLI = static_cast<const PIC16TargetLowering*>(TM.getTargetLowering());
+  PTAI = static_cast<const PIC16TargetAsmInfo*>(T);
+  PTOF = static_cast<const PIC16TargetObjectFile*>(&PTLI->getObjFileLowering());
+}
+
 bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   printInstruction(MI);
   return true;
@@ -59,10 +68,12 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   EmitAutos(CurrentFnName);
 
   // Now emit the instructions of function in its code section.
-  const char *codeSection = PAN::getCodeSectionName(CurrentFnName).c_str();
+  std::string T = PAN::getCodeSectionName(CurrentFnName);
+  const char *codeSection = T.c_str();
  
   const Section *fCodeSection = 
-    TAI->getOrCreateSection(codeSection, false, SectionKind::Text);
+    getObjFileLowering().getOrCreateSection(codeSection, false, 
+                                            SectionKind::Text);
   // Start the Code Section.
   O <<  "\n";
   SwitchToSection(fCodeSection);
@@ -211,9 +222,8 @@ bool PIC16AsmPrinter::doInitialization(Module &M) {
 
   // Set the section names for all globals.
   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
-       I != E; ++I) {
-    I->setSection(TAI->SectionForGlobal(I)->getName());
-  }
+       I != E; ++I)
+    I->setSection(getObjFileLowering().SectionForGlobal(I, TM)->getName());
 
   DbgInfo.BeginModule(M);
   EmitFunctionDecls(M);
@@ -256,7 +266,7 @@ void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
 
 // Emit variables imported from other Modules.
 void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
-  std::vector<const GlobalVariable*> Items = PTAI->ExternalVarDecls->Items;
+  std::vector<const GlobalVariable*> Items = PTOF->ExternalVarDecls->Items;
   if (!Items.size()) return;
 
   O << "\n" << TAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
@@ -268,7 +278,7 @@ void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
 
 // Emit variables defined in this module and are available to other modules.
 void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
-  std::vector<const GlobalVariable*> Items = PTAI->ExternalVarDefs->Items;
+  std::vector<const GlobalVariable*> Items = PTOF->ExternalVarDefs->Items;
   if (!Items.size()) return;
 
   O << "\n" << TAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
@@ -281,12 +291,12 @@ void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
 // Emit initialized data placed in ROM.
 void PIC16AsmPrinter::EmitRomData(Module &M) {
   // Print ROM Data section.
-  const std::vector<PIC16Section*> &ROSections = PTAI->ROSections;
+  const std::vector<PIC16Section*> &ROSections = PTOF->ROSections;
   for (unsigned i = 0; i < ROSections.size(); i++) {
     const std::vector<const GlobalVariable*> &Items = ROSections[i]->Items;
     if (!Items.size()) continue;
     O << "\n";
-    SwitchToSection(PTAI->ROSections[i]->S_);
+    SwitchToSection(PTOF->ROSections[i]->S_);
     for (unsigned j = 0; j < Items.size(); j++) {
       O << Mang->getMangledName(Items[j]);
       Constant *C = Items[j]->getInitializer();
@@ -310,10 +320,12 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
   const TargetData *TD = TM.getTargetData();
   // Emit the data section name.
   O << "\n"; 
-  const char *SectionName = PAN::getFrameSectionName(CurrentFnName).c_str();
+  std::string T = PAN::getFrameSectionName(CurrentFnName);
+  const char *SectionName = T.c_str();
 
   const Section *fPDataSection =
-    TAI->getOrCreateSection(SectionName, false, SectionKind::DataRel);
+    getObjFileLowering().getOrCreateSection(SectionName, false,
+                                            SectionKind::DataRel);
   SwitchToSection(fPDataSection);
   
   // Emit function frame label
@@ -352,7 +364,7 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
 void PIC16AsmPrinter::EmitIData(Module &M) {
 
   // Print all IDATA sections.
-  const std::vector<PIC16Section*> &IDATASections = PTAI->IDATASections;
+  const std::vector<PIC16Section*> &IDATASections = PTOF->IDATASections;
   for (unsigned i = 0; i < IDATASections.size(); i++) {
     O << "\n";
     if (IDATASections[i]->S_->getName().find("llvm.") != std::string::npos)
@@ -373,7 +385,7 @@ void PIC16AsmPrinter::EmitUData(Module &M) {
   const TargetData *TD = TM.getTargetData();
 
   // Print all BSS sections.
-  const std::vector<PIC16Section*> &BSSSections = PTAI->BSSSections;
+  const std::vector<PIC16Section*> &BSSSections = PTOF->BSSSections;
   for (unsigned i = 0; i < BSSSections.size(); i++) {
     O << "\n";
     SwitchToSection(BSSSections[i]->S_);
@@ -395,7 +407,7 @@ void PIC16AsmPrinter::EmitAutos(std::string FunctName) {
 
   // Now print Autos section for this function.
   std::string SectionName = PAN::getAutosSectionName(FunctName);
-  const std::vector<PIC16Section*> &AutosSections = PTAI->AutosSections;
+  const std::vector<PIC16Section*> &AutosSections = PTOF->AutosSections;
   for (unsigned i = 0; i < AutosSections.size(); i++) {
     O << "\n";
     if (AutosSections[i]->S_->getName() == SectionName) { 
@@ -422,7 +434,7 @@ void PIC16AsmPrinter::EmitRemainingAutos() {
   const TargetData *TD = TM.getTargetData();
 
   // Now print Autos section for this function.
-  std::vector <PIC16Section *>AutosSections = PTAI->AutosSections;
+  std::vector <PIC16Section *>AutosSections = PTOF->AutosSections;
   for (unsigned i = 0; i < AutosSections.size(); i++) {
     
     // if the section is already printed then don't print again
index 0e05940caf4a0a0218a4d733c7ebb2b0a01a08c4..c365b5a30dba9f4db0933d5e6e51ba83c4595e8d 100644 (file)
@@ -18,6 +18,7 @@
 #include "PIC16.h"
 #include "PIC16TargetMachine.h"
 #include "PIC16DebugInfo.h"
+#include "PIC16TargetObjectFile.h"
 #include "llvm/Analysis/DebugInfo.h"
 #include "PIC16TargetAsmInfo.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include <string>
 
 namespace llvm {
-  struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter {
+  class VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter {
+  public:
     explicit PIC16AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
-                             const TargetAsmInfo *T, bool V)
-      : AsmPrinter(O, TM, T, V), DbgInfo(O, T) {
-      PTLI = static_cast<const PIC16TargetLowering *> (TM.getTargetLowering());
-      PTAI = static_cast<const PIC16TargetAsmInfo *> (T);
-    }
+                             const TargetAsmInfo *T, bool V);
   private:
     virtual const char *getPassName() const {
       return "PIC16 Assembly Printer";
@@ -66,6 +64,7 @@ namespace llvm {
     }
     
   private:
+    PIC16TargetObjectFile *PTOF;
     PIC16TargetLowering *PTLI;
     PIC16DbgInfo DbgInfo;
     const PIC16TargetAsmInfo *PTAI;
index 13d9654cb03c85851d3211fc642900cec4c9c71f..f194dc85f24c36d06645dc04826d1d1c591fe2c3 100644 (file)
@@ -12,8 +12,8 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "pic16-lower"
-
 #include "PIC16ISelLowering.h"
+#include "PIC16TargetObjectFile.h"
 #include "PIC16TargetMachine.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/GlobalValue.h"
@@ -123,7 +123,7 @@ static const char *getIntrinsicName(unsigned opcode) {
 
 // PIC16TargetLowering Constructor.
 PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
-  : TargetLowering(TM), TmpSize(0) {
+  : TargetLowering(TM, new PIC16TargetObjectFile(TM)), TmpSize(0) {
  
   Subtarget = &TM.getSubtarget<PIC16Subtarget>();
 
index 5a4387ae253afc05b945137a7e2a6a2b5553171b..9912543a87cc3fc3506247cbf3624961e573f7f6 100644 (file)
@@ -31,36 +31,26 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
   Data16bitsDirective = " dw ";
   Data32bitsDirective = " dl ";
   Data64bitsDirective = NULL;
-  RomData8bitsDirective = " dw ";
-  RomData16bitsDirective = " rom_di ";
-  RomData32bitsDirective = " rom_dl ";
   ZeroDirective = NULL;
   AsciiDirective = " dt ";
   AscizDirective = NULL;
-  BSSSection_  = getOrCreateSection("udata.# UDATA", false, SectionKind::BSS);
-  ReadOnlySection = getOrCreateSection("romdata.# ROMDATA", false,
-                                       SectionKind::ReadOnly);
-  DataSection = getOrCreateSection("idata.# IDATA", false,SectionKind::DataRel);
   SwitchToSectionDirective = "";
-  // Need because otherwise a .text symbol is emitted by DwarfWriter
-  // in BeginModule, and gpasm cribbs for that .text symbol.
-  TextSection = getOrCreateSection("", true, SectionKind::Text);
-  PIC16Section *ROSection = new PIC16Section(getReadOnlySection());
-  ROSections.push_back(ROSection);
     
-  // FIXME: I don't know what the classification of these sections really is.
-  ExternalVarDecls = new PIC16Section(getOrCreateSection("ExternalVarDecls",
-                                                         false,
-                                                         SectionKind::Metadata));
-  ExternalVarDefs = new PIC16Section(getOrCreateSection("ExternalVarDefs",
-                                                        false,
-                                                        SectionKind::Metadata));
+  RomData8bitsDirective = " dw ";
+  RomData16bitsDirective = " rom_di ";
+  RomData32bitsDirective = " rom_dl ";
+    
+    
   // Set it to false because we weed to generate c file name and not bc file
   // name.
   HasSingleParameterDotFile = false;
 }
 
-const char *PIC16TargetAsmInfo::getRomDirective(unsigned Size) const {
+const char *PIC16TargetAsmInfo::
+getDataASDirective(unsigned Size, unsigned AS) const {
+  if (AS != PIC16ISD::ROM_SPACE)
+    return 0;
+  
   switch (Size) {
   case  8: return RomData8bitsDirective;
   case 16: return RomData16bitsDirective;
@@ -69,369 +59,3 @@ const char *PIC16TargetAsmInfo::getRomDirective(unsigned Size) const {
   }
 }
 
-
-const char *PIC16TargetAsmInfo::
-getDataASDirective(unsigned Size, unsigned AS) const {
-  if (AS == PIC16ISD::ROM_SPACE)
-    return getRomDirective(Size);
-  return NULL;
-}
-
-const Section *
-PIC16TargetAsmInfo::getBSSSectionForGlobal(const GlobalVariable *GV) const {
-  assert(GV->hasInitializer() && "This global doesn't need space");
-  Constant *C = GV->getInitializer();
-  assert(C->isNullValue() && "Unitialized globals has non-zero initializer");
-
-  // Find how much space this global needs.
-  const TargetData *TD = TM.getTargetData();
-  const Type *Ty = C->getType(); 
-  unsigned ValSize = TD->getTypeAllocSize(Ty);
-  // Go through all BSS Sections and assign this variable
-  // to the first available section having enough space.
-  PIC16Section *FoundBSS = NULL;
-  for (unsigned i = 0; i < BSSSections.size(); i++) {
-    if (DataBankSize - BSSSections[i]->Size >= ValSize) {
-      FoundBSS = BSSSections[i];
-      break;
-    }
-  }
-
-  // No BSS section spacious enough was found. Crate a new one.
-  if (!FoundBSS) {
-    std::string name = PAN::getUdataSectionName(BSSSections.size());
-    const Section *NewSection = getOrCreateSection(name.c_str(), false,
-                                                   // FIXME.
-                                                   SectionKind::Metadata);
-
-    FoundBSS = new PIC16Section(NewSection);
-
-    // Add this newly created BSS section to the list of BSSSections.
-    BSSSections.push_back(FoundBSS);
-  }
-  
-  // Insert the GV into this BSS.
-  FoundBSS->Items.push_back(GV);
-  FoundBSS->Size += ValSize;
-  return FoundBSS->S_;
-} 
-
-const Section *
-PIC16TargetAsmInfo::getIDATASectionForGlobal(const GlobalVariable *GV) const {
-  assert(GV->hasInitializer() && "This global doesn't need space");
-  Constant *C = GV->getInitializer();
-  assert(!C->isNullValue() && "initialized globals has zero initializer");
-  assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
-         "can split initialized RAM data only");
-
-  // Find how much space this global needs.
-  const TargetData *TD = TM.getTargetData();
-  const Type *Ty = C->getType(); 
-  unsigned ValSize = TD->getTypeAllocSize(Ty);
-  // Go through all IDATA Sections and assign this variable
-  // to the first available section having enough space.
-  PIC16Section *FoundIDATA = NULL;
-  for (unsigned i = 0; i < IDATASections.size(); i++) {
-    if (DataBankSize - IDATASections[i]->Size >= ValSize) {
-      FoundIDATA = IDATASections[i]; 
-      break;
-    }
-  }
-
-  // No IDATA section spacious enough was found. Crate a new one.
-  if (!FoundIDATA) {
-    std::string name = PAN::getIdataSectionName(IDATASections.size());
-    const Section *NewSection = getOrCreateSection(name.c_str(),
-                                                   false,
-                                                   // FIXME.
-                                                   SectionKind::Metadata);
-
-    FoundIDATA = new PIC16Section(NewSection);
-
-    // Add this newly created IDATA section to the list of IDATASections.
-    IDATASections.push_back(FoundIDATA);
-  }
-  
-  // Insert the GV into this IDATA.
-  FoundIDATA->Items.push_back(GV);
-  FoundIDATA->Size += ValSize;
-  return FoundIDATA->S_;
-} 
-
-// Get the section for an automatic variable of a function.
-// For PIC16 they are globals only with mangled names.
-const Section *
-PIC16TargetAsmInfo::getSectionForAuto(const GlobalVariable *GV) const {
-
-  const std::string name = PAN::getSectionNameForSym(GV->getName());
-
-  // Go through all Auto Sections and assign this variable
-  // to the appropriate section.
-  PIC16Section *FoundAutoSec = NULL;
-  for (unsigned i = 0; i < AutosSections.size(); i++) {
-    if (AutosSections[i]->S_->getName() == name) {
-      FoundAutoSec = AutosSections[i];
-      break;
-    }
-  }
-
-  // No Auto section was found. Crate a new one.
-  if (!FoundAutoSec) {
-    const Section *NewSection = getOrCreateSection(name.c_str(),
-                                                   // FIXME.
-                                                   false,
-                                                   SectionKind::Metadata);
-
-    FoundAutoSec = new PIC16Section(NewSection);
-
-    // Add this newly created autos section to the list of AutosSections.
-    AutosSections.push_back(FoundAutoSec);
-  }
-
-  // Insert the auto into this section.
-  FoundAutoSec->Items.push_back(GV);
-
-  return FoundAutoSec->S_;
-}
-
-
-// Override default implementation to put the true globals into
-// multiple data sections if required.
-const Section*
-PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1,
-                                           SectionKind Kind) const {
-  // We select the section based on the initializer here, so it really
-  // has to be a GlobalVariable.
-  const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1); 
-  if (!GV)
-    return TargetAsmInfo::SelectSectionForGlobal(GV1, Kind);
-
-  // Record External Var Decls.
-  if (GV->isDeclaration()) {
-    ExternalVarDecls->Items.push_back(GV);
-    return ExternalVarDecls->S_;
-  }
-    
-  assert(GV->hasInitializer() && "A def without initializer?");
-
-  // First, if this is an automatic variable for a function, get the section
-  // name for it and return.
-  std::string name = GV->getName();
-  if (PAN::isLocalName(name))
-    return getSectionForAuto(GV);
-
-  // Record Exteranl Var Defs.
-  if (GV->hasExternalLinkage() || GV->hasCommonLinkage())
-    ExternalVarDefs->Items.push_back(GV);
-
-  // See if this is an uninitialized global.
-  const Constant *C = GV->getInitializer();
-  if (C->isNullValue()) 
-    return getBSSSectionForGlobal(GV); 
-
-  // If this is initialized data in RAM. Put it in the correct IDATA section.
-  if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) 
-    return getIDATASectionForGlobal(GV);
-
-  // This is initialized data in rom, put it in the readonly section.
-  if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) 
-    return getROSectionForGlobal(GV);
-
-  // Else let the default implementation take care of it.
-  return TargetAsmInfo::SelectSectionForGlobal(GV, Kind);
-}
-
-PIC16TargetAsmInfo::~PIC16TargetAsmInfo() {
-  for (unsigned i = 0; i < BSSSections.size(); i++)
-    delete BSSSections[i]; 
-  for (unsigned i = 0; i < IDATASections.size(); i++)
-    delete IDATASections[i]; 
-  for (unsigned i = 0; i < AutosSections.size(); i++)
-    delete AutosSections[i]; 
-  for (unsigned i = 0; i < ROSections.size(); i++)
-    delete ROSections[i];
-  delete ExternalVarDecls;
-  delete ExternalVarDefs;
-}
-
-
-/// getSpecialCasedSectionGlobals - Allow the target to completely override
-/// section assignment of a global.
-const Section *
-PIC16TargetAsmInfo::getSpecialCasedSectionGlobals(const GlobalValue *GV,
-                                                  SectionKind Kind) const {
-  // If GV has a sectin name or section address create that section now.
-  if (GV->hasSection()) {
-    if (const GlobalVariable *GVar = cast<GlobalVariable>(GV)) {
-      std::string SectName = GVar->getSection();
-      // If address for a variable is specified, get the address and create
-      // section.
-      std::string AddrStr = "Address=";
-      if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) {
-        std::string SectAddr = SectName.substr(AddrStr.length());
-        return CreateSectionForGlobal(GVar, SectAddr);
-      }
-       
-      // Create the section specified with section attribute. 
-      return CreateSectionForGlobal(GVar);
-    }
-  }
-
-  return 0;
-}
-
-// Create a new section for global variable. If Addr is given then create
-// section at that address else create by name.
-const Section *
-PIC16TargetAsmInfo::CreateSectionForGlobal(const GlobalVariable *GV,
-                                           const std::string &Addr) const {
-  // See if this is an uninitialized global.
-  const Constant *C = GV->getInitializer();
-  if (C->isNullValue())
-    return CreateBSSSectionForGlobal(GV, Addr);
-
-  // If this is initialized data in RAM. Put it in the correct IDATA section.
-  if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
-    return CreateIDATASectionForGlobal(GV, Addr);
-
-  // This is initialized data in rom, put it in the readonly section.
-  if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) 
-    return CreateROSectionForGlobal(GV, Addr);
-
-  // Else let the default implementation take care of it.
-  return TargetAsmInfo::SectionForGlobal(GV);
-}
-
-// Create uninitialized section for a variable.
-const Section *
-PIC16TargetAsmInfo::CreateBSSSectionForGlobal(const GlobalVariable *GV,
-                                              std::string Addr) const {
-  assert(GV->hasInitializer() && "This global doesn't need space");
-  assert(GV->getInitializer()->isNullValue() &&
-         "Unitialized global has non-zero initializer");
-  std::string Name;
-  // If address is given then create a section at that address else create a
-  // section by section name specified in GV.
-  PIC16Section *FoundBSS = NULL;
-  if (Addr.empty()) { 
-    Name = GV->getSection() + " UDATA";
-    for (unsigned i = 0; i < BSSSections.size(); i++) {
-      if (BSSSections[i]->S_->getName() == Name) {
-        FoundBSS = BSSSections[i];
-        break;
-      }
-    }
-  } else {
-    std::string Prefix = GV->getNameStr() + "." + Addr + ".";
-    Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr;
-  }
-  
-  PIC16Section *NewBSS = FoundBSS;
-  if (NewBSS == NULL) {
-    const Section *NewSection = getOrCreateSection(Name.c_str(),
-                                                   false, SectionKind::BSS);
-    NewBSS = new PIC16Section(NewSection);
-    BSSSections.push_back(NewBSS);
-  }
-
-  // Insert the GV into this BSS.
-  NewBSS->Items.push_back(GV);
-
-  // We do not want to put any  GV without explicit section into this section
-  // so set its size to DatabankSize.
-  NewBSS->Size = DataBankSize;
-  return NewBSS->S_;
-}
-
-// Get rom section for a variable. Currently there can be only one rom section
-// unless a variable explicitly requests a section.
-const Section *
-PIC16TargetAsmInfo::getROSectionForGlobal(const GlobalVariable *GV) const {
-  ROSections[0]->Items.push_back(GV);
-  return ROSections[0]->S_;
-}
-
-// Create initialized data section for a variable.
-const Section *
-PIC16TargetAsmInfo::CreateIDATASectionForGlobal(const GlobalVariable *GV,
-                                                std::string Addr) const {
-  assert(GV->hasInitializer() && "This global doesn't need space");
-  assert(!GV->getInitializer()->isNullValue() &&
-         "initialized global has zero initializer");
-  assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
-         "can be used for initialized RAM data only");
-
-  std::string Name;
-  // If address is given then create a section at that address else create a
-  // section by section name specified in GV.
-  PIC16Section *FoundIDATASec = NULL;
-  if (Addr.empty()) {
-    Name = GV->getSection() + " IDATA";
-    for (unsigned i = 0; i < IDATASections.size(); i++) {
-      if (IDATASections[i]->S_->getName() == Name) {
-        FoundIDATASec = IDATASections[i];
-        break;
-      }
-    }
-  } else {
-    std::string Prefix = GV->getNameStr() + "." + Addr + ".";
-    Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr;
-  }
-
-  PIC16Section *NewIDATASec = FoundIDATASec;
-  if (NewIDATASec == NULL) {
-    const Section *NewSection = getOrCreateSection(Name.c_str(),
-                                                   false,
-                                                   // FIXME:
-                                                   SectionKind::Metadata);
-    NewIDATASec = new PIC16Section(NewSection);
-    IDATASections.push_back(NewIDATASec);
-  }
-  // Insert the GV into this IDATA Section.
-  NewIDATASec->Items.push_back(GV);
-  // We do not want to put any  GV without explicit section into this section 
-  // so set its size to DatabankSize.
-  NewIDATASec->Size = DataBankSize;
-  return NewIDATASec->S_;
-}
-
-// Create a section in rom for a variable.
-const Section *
-PIC16TargetAsmInfo::CreateROSectionForGlobal(const GlobalVariable *GV,
-                                             std::string Addr) const {
-  assert(GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE &&
-         "can be used for ROM data only");
-
-  std::string Name;
-  // If address is given then create a section at that address else create a
-  // section by section name specified in GV.
-  PIC16Section *FoundROSec = NULL;
-  if (Addr.empty()) {
-    Name = GV->getSection() + " ROMDATA";
-    for (unsigned i = 1; i < ROSections.size(); i++) {
-      if (ROSections[i]->S_->getName() == Name) {
-        FoundROSec = ROSections[i];
-        break;
-      }
-    }
-  } else {
-    std::string Prefix = GV->getNameStr() + "." + Addr + ".";
-    Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr;
-  }
-
-  PIC16Section *NewRomSec = FoundROSec;
-  if (NewRomSec == NULL) {
-    const Section *NewSection = getOrCreateSection(Name.c_str(),
-                                                   false,
-                                                   SectionKind::ReadOnly);
-    NewRomSec = new PIC16Section(NewSection);
-    ROSections.push_back(NewRomSec);
-  }
-
-  // Insert the GV into this ROM Section.
-  NewRomSec->Items.push_back(GV);
-  return NewRomSec->S_;
-}
-
index 1ced3bfde123860d9f69a680a123102a8569ca10..8fb9e0c29eb48cddfc023b81725c048923e1ba73 100644 (file)
 #ifndef PIC16TARGETASMINFO_H
 #define PIC16TARGETASMINFO_H
 
-#include "PIC16.h"
 #include "llvm/Target/TargetAsmInfo.h"
-#include <vector>
-#include "llvm/Module.h"
 
 namespace llvm {
 
-  enum { DataBankSize = 80 };
-
   // Forward declaration.
   class PIC16TargetMachine;
-  class GlobalVariable;
-
-  /// PIC16 Splits the global data into mulitple udata and idata sections.
-  /// Each udata and idata section needs to contain a list of globals that
-  /// they contain, in order to avoid scanning over all the global values 
-  /// again and printing only those that match the current section. 
-  /// Keeping values inside the sections make printing a section much easier.
-  struct PIC16Section {
-    const Section *S_; // Connection to actual Section.
-    unsigned Size;  // Total size of the objects contained.
-    bool SectionPrinted;
-    std::vector<const GlobalVariable*> Items;
-   
-    PIC16Section(const Section *s) {
-      S_ = s;
-      Size = 0;
-      SectionPrinted = false;
-    }
-    bool isPrinted() const { return SectionPrinted; }
-    void setPrintedStatus(bool status) { SectionPrinted = status; } 
-  };
       
-  struct PIC16TargetAsmInfo : public TargetAsmInfo {
-    std::string getSectionNameForSym(const std::string &Sym) const;
-    PIC16TargetAsmInfo(const PIC16TargetMachine &TM);
-    mutable std::vector<PIC16Section *> BSSSections;
-    mutable std::vector<PIC16Section *> IDATASections;
-    mutable std::vector<PIC16Section *> AutosSections;
-    mutable std::vector<PIC16Section *> ROSections;
-    mutable PIC16Section *ExternalVarDecls;
-    mutable PIC16Section *ExternalVarDefs;
-    virtual ~PIC16TargetAsmInfo();
-
-  private:
+  class PIC16TargetAsmInfo : public TargetAsmInfo {
     const char *RomData8bitsDirective;
     const char *RomData16bitsDirective;
     const char *RomData32bitsDirective;
-    const char *getRomDirective(unsigned size) const;
-    virtual const char *getDataASDirective(unsigned size, unsigned AS) const;
-    const Section *getBSSSectionForGlobal(const GlobalVariable *GV) const;
-    const Section *getIDATASectionForGlobal(const GlobalVariable *GV) const;
-    const Section *getSectionForAuto(const GlobalVariable *GV) const;
-    const Section *CreateBSSSectionForGlobal(const GlobalVariable *GV,
-                                             std::string Addr = "") const;
-    const Section *CreateIDATASectionForGlobal(const GlobalVariable *GV,
-                                               std::string Addr = "") const;
-    const Section *getROSectionForGlobal(const GlobalVariable *GV) const;
-    const Section *CreateROSectionForGlobal(const GlobalVariable *GV,
-                                            std::string Addr = "") const;
-    virtual const Section *SelectSectionForGlobal(const GlobalValue *GV,
-                                                  SectionKind Kind) const;
-    const Section *CreateSectionForGlobal(const GlobalVariable *GV,
-                                          const std::string &Addr = "") const;
-  public:
-    void SetSectionForGVs(Module &M);
-    const std::vector<PIC16Section*> &getBSSSections() const {
-      return BSSSections;
-    }
-    const std::vector<PIC16Section*> &getIDATASections() const {
-      return IDATASections;
-    }
-    const std::vector<PIC16Section*> &getAutosSections() const {
-      return AutosSections;
-    }
-    const std::vector<PIC16Section*> &getROSections() const {
-      return ROSections;
-    }
-    
-    /// getSpecialCasedSectionGlobals - Allow the target to completely override
-    /// section assignment of a global.
-    virtual const Section *
-    getSpecialCasedSectionGlobals(const GlobalValue *GV,
-                                  SectionKind Kind) const;
+  public:    
+    PIC16TargetAsmInfo(const PIC16TargetMachine &TM);
+
     
+    virtual const char *getDataASDirective(unsigned size, unsigned AS) const;
   };
 
 } // namespace llvm
diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.cpp b/lib/Target/PIC16/PIC16TargetObjectFile.cpp
new file mode 100644 (file)
index 0000000..efc03ac
--- /dev/null
@@ -0,0 +1,401 @@
+//===-- PIC16TargetObjectFile.cpp - PIC16 object files --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PIC16TargetObjectFile.h"
+#include "PIC16ISelLowering.h"
+#include "PIC16TargetMachine.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+using namespace llvm;
+
+
+PIC16TargetObjectFile::PIC16TargetObjectFile(const PIC16TargetMachine &tm) 
+: TM (tm) {
+  BSSSection_  = getOrCreateSection("udata.# UDATA", false, SectionKind::BSS);
+  ReadOnlySection = getOrCreateSection("romdata.# ROMDATA", false,
+                                       SectionKind::ReadOnly);
+  DataSection = getOrCreateSection("idata.# IDATA", false,SectionKind::DataRel);
+  
+  // Need because otherwise a .text symbol is emitted by DwarfWriter
+  // in BeginModule, and gpasm cribbs for that .text symbol.
+  TextSection = getOrCreateSection("", true, SectionKind::Text);
+
+  
+  PIC16Section *ROSection = new PIC16Section(ReadOnlySection);
+  ROSections.push_back(ROSection);
+  
+  // FIXME: I don't know what the classification of these sections really is.
+  ExternalVarDecls = new PIC16Section(getOrCreateSection("ExternalVarDecls",
+                                                         false,
+                                                        SectionKind::Metadata));
+  ExternalVarDefs = new PIC16Section(getOrCreateSection("ExternalVarDefs",
+                                                        false,
+                                                        SectionKind::Metadata));
+}
+
+
+const Section *
+PIC16TargetObjectFile::getBSSSectionForGlobal(const GlobalVariable *GV) const {
+  assert(GV->hasInitializer() && "This global doesn't need space");
+  Constant *C = GV->getInitializer();
+  assert(C->isNullValue() && "Unitialized globals has non-zero initializer");
+
+  // Find how much space this global needs.
+  const TargetData *TD = TM.getTargetData();
+  const Type *Ty = C->getType(); 
+  unsigned ValSize = TD->getTypeAllocSize(Ty);
+  // Go through all BSS Sections and assign this variable
+  // to the first available section having enough space.
+  PIC16Section *FoundBSS = NULL;
+  for (unsigned i = 0; i < BSSSections.size(); i++) {
+    if (DataBankSize - BSSSections[i]->Size >= ValSize) {
+      FoundBSS = BSSSections[i];
+      break;
+    }
+  }
+
+  // No BSS section spacious enough was found. Crate a new one.
+  if (!FoundBSS) {
+    std::string name = PAN::getUdataSectionName(BSSSections.size());
+    const Section *NewSection = getOrCreateSection(name.c_str(), false,
+                                                   // FIXME.
+                                                   SectionKind::Metadata);
+
+    FoundBSS = new PIC16Section(NewSection);
+
+    // Add this newly created BSS section to the list of BSSSections.
+    BSSSections.push_back(FoundBSS);
+  }
+  
+  // Insert the GV into this BSS.
+  FoundBSS->Items.push_back(GV);
+  FoundBSS->Size += ValSize;
+  return FoundBSS->S_;
+} 
+
+const Section *
+PIC16TargetObjectFile::getIDATASectionForGlobal(const GlobalVariable *GV) const{
+  assert(GV->hasInitializer() && "This global doesn't need space");
+  Constant *C = GV->getInitializer();
+  assert(!C->isNullValue() && "initialized globals has zero initializer");
+  assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
+         "can split initialized RAM data only");
+
+  // Find how much space this global needs.
+  const TargetData *TD = TM.getTargetData();
+  const Type *Ty = C->getType(); 
+  unsigned ValSize = TD->getTypeAllocSize(Ty);
+  // Go through all IDATA Sections and assign this variable
+  // to the first available section having enough space.
+  PIC16Section *FoundIDATA = NULL;
+  for (unsigned i = 0; i < IDATASections.size(); i++) {
+    if (DataBankSize - IDATASections[i]->Size >= ValSize) {
+      FoundIDATA = IDATASections[i]; 
+      break;
+    }
+  }
+
+  // No IDATA section spacious enough was found. Crate a new one.
+  if (!FoundIDATA) {
+    std::string name = PAN::getIdataSectionName(IDATASections.size());
+    const Section *NewSection = getOrCreateSection(name.c_str(),
+                                                   false,
+                                                   // FIXME.
+                                                   SectionKind::Metadata);
+
+    FoundIDATA = new PIC16Section(NewSection);
+
+    // Add this newly created IDATA section to the list of IDATASections.
+    IDATASections.push_back(FoundIDATA);
+  }
+  
+  // Insert the GV into this IDATA.
+  FoundIDATA->Items.push_back(GV);
+  FoundIDATA->Size += ValSize;
+  return FoundIDATA->S_;
+} 
+
+// Get the section for an automatic variable of a function.
+// For PIC16 they are globals only with mangled names.
+const Section *
+PIC16TargetObjectFile::getSectionForAuto(const GlobalVariable *GV) const {
+
+  const std::string name = PAN::getSectionNameForSym(GV->getName());
+
+  // Go through all Auto Sections and assign this variable
+  // to the appropriate section.
+  PIC16Section *FoundAutoSec = NULL;
+  for (unsigned i = 0; i < AutosSections.size(); i++) {
+    if (AutosSections[i]->S_->getName() == name) {
+      FoundAutoSec = AutosSections[i];
+      break;
+    }
+  }
+
+  // No Auto section was found. Crate a new one.
+  if (!FoundAutoSec) {
+    const Section *NewSection = getOrCreateSection(name.c_str(),
+                                                   // FIXME.
+                                                   false,
+                                                   SectionKind::Metadata);
+
+    FoundAutoSec = new PIC16Section(NewSection);
+
+    // Add this newly created autos section to the list of AutosSections.
+    AutosSections.push_back(FoundAutoSec);
+  }
+
+  // Insert the auto into this section.
+  FoundAutoSec->Items.push_back(GV);
+
+  return FoundAutoSec->S_;
+}
+
+
+// Override default implementation to put the true globals into
+// multiple data sections if required.
+const Section*
+PIC16TargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV1,
+                                              SectionKind Kind,
+                                              const TargetMachine &TM) const {
+  // We select the section based on the initializer here, so it really
+  // has to be a GlobalVariable.
+  const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1); 
+  if (!GV)
+    return TargetLoweringObjectFile::SelectSectionForGlobal(GV1, Kind, TM);
+
+  // Record External Var Decls.
+  if (GV->isDeclaration()) {
+    ExternalVarDecls->Items.push_back(GV);
+    return ExternalVarDecls->S_;
+  }
+    
+  assert(GV->hasInitializer() && "A def without initializer?");
+
+  // First, if this is an automatic variable for a function, get the section
+  // name for it and return.
+  std::string name = GV->getName();
+  if (PAN::isLocalName(name))
+    return getSectionForAuto(GV);
+
+  // Record Exteranl Var Defs.
+  if (GV->hasExternalLinkage() || GV->hasCommonLinkage())
+    ExternalVarDefs->Items.push_back(GV);
+
+  // See if this is an uninitialized global.
+  const Constant *C = GV->getInitializer();
+  if (C->isNullValue()) 
+    return getBSSSectionForGlobal(GV); 
+
+  // If this is initialized data in RAM. Put it in the correct IDATA section.
+  if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) 
+    return getIDATASectionForGlobal(GV);
+
+  // This is initialized data in rom, put it in the readonly section.
+  if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) 
+    return getROSectionForGlobal(GV);
+
+  // Else let the default implementation take care of it.
+  return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, TM);
+}
+
+PIC16TargetObjectFile::~PIC16TargetObjectFile() {
+  for (unsigned i = 0; i < BSSSections.size(); i++)
+    delete BSSSections[i]; 
+  for (unsigned i = 0; i < IDATASections.size(); i++)
+    delete IDATASections[i]; 
+  for (unsigned i = 0; i < AutosSections.size(); i++)
+    delete AutosSections[i]; 
+  for (unsigned i = 0; i < ROSections.size(); i++)
+    delete ROSections[i];
+  delete ExternalVarDecls;
+  delete ExternalVarDefs;
+}
+
+
+/// getSpecialCasedSectionGlobals - Allow the target to completely override
+/// section assignment of a global.
+const Section *
+PIC16TargetObjectFile::getSpecialCasedSectionGlobals(const GlobalValue *GV,
+                                                     SectionKind Kind) const {
+  // If GV has a sectin name or section address create that section now.
+  if (GV->hasSection()) {
+    if (const GlobalVariable *GVar = cast<GlobalVariable>(GV)) {
+      std::string SectName = GVar->getSection();
+      // If address for a variable is specified, get the address and create
+      // section.
+      std::string AddrStr = "Address=";
+      if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) {
+        std::string SectAddr = SectName.substr(AddrStr.length());
+        return CreateSectionForGlobal(GVar, SectAddr);
+      }
+       
+      // Create the section specified with section attribute. 
+      return CreateSectionForGlobal(GVar);
+    }
+  }
+
+  return 0;
+}
+
+// Create a new section for global variable. If Addr is given then create
+// section at that address else create by name.
+const Section *
+PIC16TargetObjectFile::CreateSectionForGlobal(const GlobalVariable *GV,
+                                              const std::string &Addr) const {
+  // See if this is an uninitialized global.
+  const Constant *C = GV->getInitializer();
+  if (C->isNullValue())
+    return CreateBSSSectionForGlobal(GV, Addr);
+
+  // If this is initialized data in RAM. Put it in the correct IDATA section.
+  if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
+    return CreateIDATASectionForGlobal(GV, Addr);
+
+  // This is initialized data in rom, put it in the readonly section.
+  if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) 
+    return CreateROSectionForGlobal(GV, Addr);
+
+  // Else let the default implementation take care of it.
+  return TargetLoweringObjectFile::SectionForGlobal(GV, TM);
+}
+
+// Create uninitialized section for a variable.
+const Section *
+PIC16TargetObjectFile::CreateBSSSectionForGlobal(const GlobalVariable *GV,
+                                                 std::string Addr) const {
+  assert(GV->hasInitializer() && "This global doesn't need space");
+  assert(GV->getInitializer()->isNullValue() &&
+         "Unitialized global has non-zero initializer");
+  std::string Name;
+  // If address is given then create a section at that address else create a
+  // section by section name specified in GV.
+  PIC16Section *FoundBSS = NULL;
+  if (Addr.empty()) { 
+    Name = GV->getSection() + " UDATA";
+    for (unsigned i = 0; i < BSSSections.size(); i++) {
+      if (BSSSections[i]->S_->getName() == Name) {
+        FoundBSS = BSSSections[i];
+        break;
+      }
+    }
+  } else {
+    std::string Prefix = GV->getNameStr() + "." + Addr + ".";
+    Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr;
+  }
+  
+  PIC16Section *NewBSS = FoundBSS;
+  if (NewBSS == NULL) {
+    const Section *NewSection = getOrCreateSection(Name.c_str(),
+                                                   false, SectionKind::BSS);
+    NewBSS = new PIC16Section(NewSection);
+    BSSSections.push_back(NewBSS);
+  }
+
+  // Insert the GV into this BSS.
+  NewBSS->Items.push_back(GV);
+
+  // We do not want to put any  GV without explicit section into this section
+  // so set its size to DatabankSize.
+  NewBSS->Size = DataBankSize;
+  return NewBSS->S_;
+}
+
+// Get rom section for a variable. Currently there can be only one rom section
+// unless a variable explicitly requests a section.
+const Section *
+PIC16TargetObjectFile::getROSectionForGlobal(const GlobalVariable *GV) const {
+  ROSections[0]->Items.push_back(GV);
+  return ROSections[0]->S_;
+}
+
+// Create initialized data section for a variable.
+const Section *
+PIC16TargetObjectFile::CreateIDATASectionForGlobal(const GlobalVariable *GV,
+                                                   std::string Addr) const {
+  assert(GV->hasInitializer() && "This global doesn't need space");
+  assert(!GV->getInitializer()->isNullValue() &&
+         "initialized global has zero initializer");
+  assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
+         "can be used for initialized RAM data only");
+
+  std::string Name;
+  // If address is given then create a section at that address else create a
+  // section by section name specified in GV.
+  PIC16Section *FoundIDATASec = NULL;
+  if (Addr.empty()) {
+    Name = GV->getSection() + " IDATA";
+    for (unsigned i = 0; i < IDATASections.size(); i++) {
+      if (IDATASections[i]->S_->getName() == Name) {
+        FoundIDATASec = IDATASections[i];
+        break;
+      }
+    }
+  } else {
+    std::string Prefix = GV->getNameStr() + "." + Addr + ".";
+    Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr;
+  }
+
+  PIC16Section *NewIDATASec = FoundIDATASec;
+  if (NewIDATASec == NULL) {
+    const Section *NewSection = getOrCreateSection(Name.c_str(),
+                                                   false,
+                                                   // FIXME:
+                                                   SectionKind::Metadata);
+    NewIDATASec = new PIC16Section(NewSection);
+    IDATASections.push_back(NewIDATASec);
+  }
+  // Insert the GV into this IDATA Section.
+  NewIDATASec->Items.push_back(GV);
+  // We do not want to put any  GV without explicit section into this section 
+  // so set its size to DatabankSize.
+  NewIDATASec->Size = DataBankSize;
+  return NewIDATASec->S_;
+}
+
+// Create a section in rom for a variable.
+const Section *
+PIC16TargetObjectFile::CreateROSectionForGlobal(const GlobalVariable *GV,
+                                                std::string Addr) const {
+  assert(GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE &&
+         "can be used for ROM data only");
+
+  std::string Name;
+  // If address is given then create a section at that address else create a
+  // section by section name specified in GV.
+  PIC16Section *FoundROSec = NULL;
+  if (Addr.empty()) {
+    Name = GV->getSection() + " ROMDATA";
+    for (unsigned i = 1; i < ROSections.size(); i++) {
+      if (ROSections[i]->S_->getName() == Name) {
+        FoundROSec = ROSections[i];
+        break;
+      }
+    }
+  } else {
+    std::string Prefix = GV->getNameStr() + "." + Addr + ".";
+    Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr;
+  }
+
+  PIC16Section *NewRomSec = FoundROSec;
+  if (NewRomSec == NULL) {
+    const Section *NewSection = getOrCreateSection(Name.c_str(),
+                                                   false,
+                                                   SectionKind::ReadOnly);
+    NewRomSec = new PIC16Section(NewSection);
+    ROSections.push_back(NewRomSec);
+  }
+
+  // Insert the GV into this ROM Section.
+  NewRomSec->Items.push_back(GV);
+  return NewRomSec->S_;
+}
+
diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.h b/lib/Target/PIC16/PIC16TargetObjectFile.h
new file mode 100644 (file)
index 0000000..77aea78
--- /dev/null
@@ -0,0 +1,100 @@
+//===-- PIC16TargetObjectFile.h - PIC16 Object Info -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_PIC16_TARGETOBJECTFILE_H
+#define LLVM_TARGET_PIC16_TARGETOBJECTFILE_H
+
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include <vector>
+
+namespace llvm {
+  class GlobalVariable;
+  class Module;
+  class PIC16TargetMachine;
+  
+  enum { DataBankSize = 80 };
+
+  /// PIC16 Splits the global data into mulitple udata and idata sections.
+  /// Each udata and idata section needs to contain a list of globals that
+  /// they contain, in order to avoid scanning over all the global values 
+  /// again and printing only those that match the current section. 
+  /// Keeping values inside the sections make printing a section much easier.
+  ///
+  /// FIXME: Reimplement by inheriting from MCSection.
+  ///
+  struct PIC16Section {
+    const Section *S_; // Connection to actual Section.
+    unsigned Size;  // Total size of the objects contained.
+    bool SectionPrinted;
+    std::vector<const GlobalVariable*> Items;
+    
+    PIC16Section(const Section *s) {
+      S_ = s;
+      Size = 0;
+      SectionPrinted = false;
+    }
+    bool isPrinted() const { return SectionPrinted; }
+    void setPrintedStatus(bool status) { SectionPrinted = status; } 
+  };
+  
+  class PIC16TargetObjectFile : public TargetLoweringObjectFile {
+    const PIC16TargetMachine &TM;
+  public:
+    mutable std::vector<PIC16Section*> BSSSections;
+    mutable std::vector<PIC16Section*> IDATASections;
+    mutable std::vector<PIC16Section*> AutosSections;
+    mutable std::vector<PIC16Section*> ROSections;
+    mutable PIC16Section *ExternalVarDecls;
+    mutable PIC16Section *ExternalVarDefs;
+    
+    PIC16TargetObjectFile(const PIC16TargetMachine &TM);
+    ~PIC16TargetObjectFile();
+    
+    /// getSpecialCasedSectionGlobals - Allow the target to completely override
+    /// section assignment of a global.
+    virtual const Section *
+    getSpecialCasedSectionGlobals(const GlobalValue *GV,
+                                  SectionKind Kind) const;
+    virtual const Section *SelectSectionForGlobal(const GlobalValue *GV,
+                                                  SectionKind Kind,
+                                                  const TargetMachine&) const;
+  private:
+    std::string getSectionNameForSym(const std::string &Sym) const;
+
+    const Section *getBSSSectionForGlobal(const GlobalVariable *GV) const;
+    const Section *getIDATASectionForGlobal(const GlobalVariable *GV) const;
+    const Section *getSectionForAuto(const GlobalVariable *GV) const;
+    const Section *CreateBSSSectionForGlobal(const GlobalVariable *GV,
+                                             std::string Addr = "") const;
+    const Section *CreateIDATASectionForGlobal(const GlobalVariable *GV,
+                                               std::string Addr = "") const;
+    const Section *getROSectionForGlobal(const GlobalVariable *GV) const;
+    const Section *CreateROSectionForGlobal(const GlobalVariable *GV,
+                                            std::string Addr = "") const;
+    const Section *CreateSectionForGlobal(const GlobalVariable *GV,
+                                          const std::string &Addr = "") const;
+  public:
+    void SetSectionForGVs(Module &M);
+    const std::vector<PIC16Section*> &getBSSSections() const {
+      return BSSSections;
+    }
+    const std::vector<PIC16Section*> &getIDATASections() const {
+      return IDATASections;
+    }
+    const std::vector<PIC16Section*> &getAutosSections() const {
+      return AutosSections;
+    }
+    const std::vector<PIC16Section*> &getROSections() const {
+      return ROSections;
+    }
+    
+  };
+} // end namespace llvm
+
+#endif
index bc0a794154333b64a7746c915aac797f3ec31abf..a1b0780e63608990651b8524b78b3ff870daeb4f 100644 (file)
@@ -40,6 +40,7 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetOptions.h"
@@ -590,7 +591,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   // Print out labels for the function.
   const Function *F = MF.getFunction();
-  SwitchToSection(TAI->SectionForGlobal(F));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(F, TM));
 
   switch (F->getLinkage()) {
   default: llvm_unreachable("Unknown linkage type!");
@@ -639,7 +640,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   // Print out jump tables referenced by the function.
   EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
 
-  SwitchToSection(TAI->SectionForGlobal(F));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(F, TM));
 
   // Emit post-function debug information.
   DW->EndFunction(&MF);
@@ -681,7 +682,7 @@ void PPCLinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
   unsigned Size = TD->getTypeAllocSize(Type);
   unsigned Align = TD->getPreferredAlignmentLog(GVar);
 
-  SwitchToSection(TAI->SectionForGlobal(GVar));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(GVar, TM));
 
   if (C->isNullValue() && /* FIXME: Verify correct */
       !GVar->hasSection() &&
@@ -762,7 +763,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   // Print out labels for the function.
   const Function *F = MF.getFunction();
-  SwitchToSection(TAI->SectionForGlobal(F));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(F, TM));
 
   switch (F->getLinkage()) {
   default: llvm_unreachable("Unknown linkage type!");
@@ -861,7 +862,7 @@ bool PPCDarwinAsmPrinter::doInitialization(Module &M) {
     SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs,"
                         "pure_instructions,16");
   }
-  SwitchToSection(TAI->getTextSection());
+  SwitchToSection(getObjFileLowering().getTextSection());
 
   return Result;
 }
@@ -891,7 +892,7 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
   unsigned Size = TD->getTypeAllocSize(Type);
   unsigned Align = TD->getPreferredAlignmentLog(GVar);
 
-  const Section *TheSection = TAI->SectionForGlobal(GVar);
+  const Section *TheSection = getObjFileLowering().SectionForGlobal(GVar, TM);
   SwitchToSection(TheSection);
 
   if (C->isNullValue() && /* FIXME: Verify correct */
@@ -1051,7 +1052,7 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
   }
 
   if (!HiddenGVStubs.empty()) {
-    SwitchToSection(TAI->getDataSection());
+    SwitchToSection(getObjFileLowering().getDataSection());
     EmitAlignment(isPPC64 ? 3 : 2);
     for (StringMap<std::string>::iterator I = HiddenGVStubs.begin(),
          E = HiddenGVStubs.end(); I != E; ++I) {
index 8beddd635febfb41cde25125c9a8496f8029f4d5..fa1989b3d7e0c9323d96a9d2b1feede1b9242cbb 100644 (file)
@@ -31,6 +31,7 @@
 #include "llvm/Intrinsics.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
@@ -56,8 +57,15 @@ static cl::opt<bool> EnablePPCPreinc("enable-ppc-preinc",
 cl::desc("enable preincrement load/store generation on PPC (experimental)"),
                                      cl::Hidden);
 
+static TargetLoweringObjectFile *CreateTLOF(const PPCTargetMachine &TM) {
+  if (TM.getSubtargetImpl()->isDarwin())
+    return new TargetLoweringObjectFileMachO();
+  return new TargetLoweringObjectFileELF(false, true);
+}
+
+
 PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
-  : TargetLowering(TM), PPCSubTarget(*TM.getSubtargetImpl()) {
+  : TargetLowering(TM, CreateTLOF(TM)), PPCSubTarget(*TM.getSubtargetImpl()) {
 
   setPow2DivIsCheap();
 
index a56f965857ff264f7f0297b05f08f23113bad786..5ddd120d931b36236574eb9bf6a4b5e23ea77c6d 100644 (file)
@@ -70,9 +70,6 @@ PPCLinuxTargetAsmInfo::PPCLinuxTargetAsmInfo(const PPCTargetMachine &TM) :
   WeakRefDirective = "\t.weak\t";
   BSSSection = "\t.section\t\".sbss\",\"aw\",@nobits";
 
-  // PPC/Linux normally uses named section for BSS.
-  BSSSection_ = getOrCreateSection("\t.bss", true, SectionKind::BSS);
-
   // Debug Information
   AbsoluteDebugSectionOffsets = true;
   SupportsDebugInformation = true;
index ad99cca4ac05a452a8fea7de8f9028a947fc5e46..7569eeee883ce85fae42150fd59e033ce112f122 100644 (file)
@@ -26,6 +26,7 @@
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetRegistry.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormattedStream.h"
@@ -95,7 +96,7 @@ bool SparcAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   // Print out the label for the function.
   const Function *F = MF.getFunction();
-  SwitchToSection(TAI->SectionForGlobal(F));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(F, TM));
   EmitAlignment(MF.getAlignment(), F);
   O << "\t.globl\t" << CurrentFnName << '\n';
 
@@ -229,7 +230,7 @@ void SparcAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
 
   printVisibility(name, GVar->getVisibility());
 
-  SwitchToSection(TAI->SectionForGlobal(GVar));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(GVar, TM));
 
   if (C->isNullValue() && !GVar->hasSection()) {
     if (!GVar->isThreadLocal() &&
index fe7bf93ecc60c701e231d08901009e4737d77433..16d922985b27191e66302a5627ed1f6e9035cbe0 100644 (file)
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/ADT/VectorExtras.h"
 #include "llvm/Support/ErrorHandling.h"
 using namespace llvm;
@@ -548,9 +549,31 @@ static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) {
   }
 }
 
+class TargetLoweringObjectFileSparc : public TargetLoweringObjectFileELF {
+public:
+  void getSectionFlagsAsString(SectionKind Kind,
+                               SmallVectorImpl<char> &Str) const {
+    if (Kind.isMergeableConst() || Kind.isMergeableCString())
+      return TargetLoweringObjectFileELF::getSectionFlagsAsString(Kind, Str);
+    
+    // FIXME: Inefficient.
+    std::string Res;
+    if (!Kind.isMetadata())
+      Res += ",#alloc";
+    if (Kind.isText())
+      Res += ",#execinstr";
+    if (Kind.isWriteable())
+      Res += ",#write";
+    if (Kind.isThreadLocal())
+      Res += ",#tls";
+    
+    Str.append(Res.begin(), Res.end());
+  }
+};
+
 
 SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
-  : TargetLowering(TM) {
+  : TargetLowering(TM, new TargetLoweringObjectFileSparc()) {
 
   // Set up the register classes.
   addRegisterClass(MVT::i32, SP::IntRegsRegisterClass);
index 59897e65e81e60e9e7e13c66484ef6ce107fd45f..169eda71273306a13dc01ced18c30a399b7d3a06 100644 (file)
@@ -25,27 +25,6 @@ SparcELFTargetAsmInfo::SparcELFTargetAsmInfo(const TargetMachine &TM)
   ConstantPoolSection = "\t.section \".rodata\",#alloc\n";
   COMMDirectiveTakesAlignment = true;
   CStringSection=".rodata.str";
-
-  // Sparc normally uses named section for BSS.
-  BSSSection_ = getOrCreateSection("\t.bss", true, SectionKind::BSS);
 }
 
 
-void SparcELFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
-                                            SmallVectorImpl<char> &Str) const {
-  if (Kind.isMergeableConst() || Kind.isMergeableCString())
-    return ELFTargetAsmInfo::getSectionFlagsAsString(Kind, Str);
-
-  // FIXME: Inefficient.
-  std::string Res;
-  if (!Kind.isMetadata())
-    Res += ",#alloc";
-  if (Kind.isText())
-    Res += ",#execinstr";
-  if (Kind.isWriteable())
-    Res += ",#write";
-  if (Kind.isThreadLocal())
-    Res += ",#tls";
-
-  Str.append(Res.begin(), Res.end());
-}
index 943dcef95e5705e07520447fa44f43b3c5caac53..ae646c3911d7846a9ebf2c399d32eb83db106857 100644 (file)
@@ -23,10 +23,6 @@ namespace llvm {
 
   struct SparcELFTargetAsmInfo : public ELFTargetAsmInfo {
     explicit SparcELFTargetAsmInfo(const TargetMachine &TM);
-
-    virtual void getSectionFlagsAsString(SectionKind Kind,
-                                         SmallVectorImpl<char> &Str) const;
-
   };
 
 } // namespace llvm
index 7a1668495911d5e726d3867612695fc05df2f256..9a9a4b75083e236eea235943a93480d818d17feb 100644 (file)
@@ -27,6 +27,7 @@
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetRegistry.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/Compiler.h"
@@ -82,7 +83,7 @@ void SystemZAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
   unsigned FnAlign = MF.getAlignment();
   const Function *F = MF.getFunction();
 
-  SwitchToSection(TAI->SectionForGlobal(F));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(F, TM));
 
   EmitAlignment(FnAlign, F);
 
@@ -330,7 +331,7 @@ void SystemZAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
 
   O << "\t.type\t" << name << ",@object\n";
 
-  SwitchToSection(TAI->SectionForGlobal(GVar));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(GVar, TM));
 
   if (C->isNullValue() && !GVar->hasSection() &&
       !GVar->isThreadLocal() &&
index 8a159d78dfc4d1f85de0fc5b5e3a6e9c64a14b50..38b4c301b7825bbff631d0c3265a11be415dd9e3 100644 (file)
 #include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/Support/Debug.h"
 #include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/ADT/VectorExtras.h"
 using namespace llvm;
 
 SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) :
-  TargetLowering(tm), Subtarget(*tm.getSubtargetImpl()), TM(tm) {
+  TargetLowering(tm, new TargetLoweringObjectFileELF()),
+  Subtarget(*tm.getSubtargetImpl()), TM(tm) {
 
   RegInfo = TM.getRegisterInfo();
 
index 0079586dc40826bcccd9134bd5738e89e0453d9a..25048b81bc4e49d31977f2bf8b078f12497bb3e9 100644 (file)
@@ -27,6 +27,4 @@ SystemZTargetAsmInfo::SystemZTargetAsmInfo(const SystemZTargetMachine &TM)
   PCSymbol = ".";
 
   NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits";
-    
-  BSSSection_ = getOrCreateSection("\t.bss", true, SectionKind::BSS);
 }
index 1cb085bcd15305311fb0977a71d877d97bcb6725..e71bd01aae0465abb845cb1c5cecdc5bd195cdae 100644 (file)
@@ -30,10 +30,6 @@ using namespace llvm;
 
 TargetAsmInfo::TargetAsmInfo(const TargetMachine &tm) : TM(tm) {
   BSSSection = "\t.bss";
-  BSSSection_ = 0;
-  ReadOnlySection = 0;
-  TLSDataSection = 0;
-  TLSBSSSection = 0;
   ZeroFillDirective = 0;
   NonexecutableStackDirective = 0;
   NeedsSet = false;
@@ -78,7 +74,6 @@ TargetAsmInfo::TargetAsmInfo(const TargetMachine &tm) : TM(tm) {
   JumpTableDataSection = "\t.section .rodata";
   JumpTableDirective = 0;
   CStringSection = 0;
-  CStringSection_ = 0;
   // FIXME: Flags are ELFish - replace with normal section stuff.
   StaticCtorsSection = "\t.section .ctors,\"aw\",@progbits";
   StaticDtorsSection = "\t.section .dtors,\"aw\",@progbits";
@@ -158,219 +153,6 @@ unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
   return dwarf::DW_EH_PE_absptr;
 }
 
-static bool isSuitableForBSS(const GlobalVariable *GV) {
-  Constant *C = GV->getInitializer();
-  
-  // Must have zero initializer.
-  if (!C->isNullValue())
-    return false;
-  
-  // Leave constant zeros in readonly constant sections, so they can be shared.
-  if (GV->isConstant())
-    return false;
-  
-  // If the global has an explicit section specified, don't put it in BSS.
-  if (!GV->getSection().empty())
-    return false;
-  
-  // If -nozero-initialized-in-bss is specified, don't ever use BSS.
-  if (NoZerosInBSS)
-    return false;
-  
-  // Otherwise, put it in BSS!
-  return true;
-}
-
-static bool isConstantString(const Constant *C) {
-  // First check: is we have constant array of i8 terminated with zero
-  const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
-  // Check, if initializer is a null-terminated string
-  if (CVA && CVA->isCString())
-    return true;
-
-  // Another possibility: [1 x i8] zeroinitializer
-  if (isa<ConstantAggregateZero>(C))
-    if (const ArrayType *Ty = dyn_cast<ArrayType>(C->getType()))
-      return (Ty->getElementType() == Type::Int8Ty &&
-              Ty->getNumElements() == 1);
-
-  return false;
-}
-
-static SectionKind::Kind SectionKindForGlobal(const GlobalValue *GV,
-                                              const TargetMachine &TM) {
-  Reloc::Model ReloModel = TM.getRelocationModel();
-  
-  // Early exit - functions should be always in text sections.
-  const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
-  if (GVar == 0)
-    return SectionKind::Text;
-
-  
-  // Handle thread-local data first.
-  if (GVar->isThreadLocal()) {
-    if (isSuitableForBSS(GVar))
-      return SectionKind::ThreadBSS;
-    return SectionKind::ThreadData;
-  }
-
-  // Variable can be easily put to BSS section.
-  if (isSuitableForBSS(GVar))
-    return SectionKind::BSS;
-
-  Constant *C = GVar->getInitializer();
-  
-  // If the global is marked constant, we can put it into a mergable section,
-  // a mergable string section, or general .data if it contains relocations.
-  if (GVar->isConstant()) {
-    // If the initializer for the global contains something that requires a
-    // relocation, then we may have to drop this into a wriable data section
-    // even though it is marked const.
-    switch (C->getRelocationInfo()) {
-    default: llvm_unreachable("unknown relocation info kind");
-    case Constant::NoRelocation:
-      // If initializer is a null-terminated string, put it in a "cstring"
-      // section if the target has it.
-      if (isConstantString(C))
-        return SectionKind::MergeableCString;
-      
-      // Otherwise, just drop it into a mergable constant section.  If we have
-      // a section for this size, use it, otherwise use the arbitrary sized
-      // mergable section.
-      switch (TM.getTargetData()->getTypeAllocSize(C->getType())) {
-      case 4:  return SectionKind::MergeableConst4;
-      case 8:  return SectionKind::MergeableConst8;
-      case 16: return SectionKind::MergeableConst16;
-      default: return SectionKind::MergeableConst;
-      }
-      
-    case Constant::LocalRelocation:
-      // In static relocation model, the linker will resolve all addresses, so
-      // the relocation entries will actually be constants by the time the app
-      // starts up.  However, we can't put this into a mergable section, because
-      // the linker doesn't take relocations into consideration when it tries to
-      // merge entries in the section.
-      if (ReloModel == Reloc::Static)
-        return SectionKind::ReadOnly;
-              
-      // Otherwise, the dynamic linker needs to fix it up, put it in the
-      // writable data.rel.local section.
-      return SectionKind::ReadOnlyWithRelLocal;
-              
-    case Constant::GlobalRelocations:
-      // In static relocation model, the linker will resolve all addresses, so
-      // the relocation entries will actually be constants by the time the app
-      // starts up.  However, we can't put this into a mergable section, because
-      // the linker doesn't take relocations into consideration when it tries to
-      // merge entries in the section.
-      if (ReloModel == Reloc::Static)
-        return SectionKind::ReadOnly;
-      
-      // Otherwise, the dynamic linker needs to fix it up, put it in the
-      // writable data.rel section.
-      return SectionKind::ReadOnlyWithRel;
-    }
-  }
-
-  // Okay, this isn't a constant.  If the initializer for the global is going
-  // to require a runtime relocation by the dynamic linker, put it into a more
-  // specific section to improve startup time of the app.  This coalesces these
-  // globals together onto fewer pages, improving the locality of the dynamic
-  // linker.
-  if (ReloModel == Reloc::Static)
-    return SectionKind::DataNoRel;
-
-  switch (C->getRelocationInfo()) {
-  default: llvm_unreachable("unknown relocation info kind");
-  case Constant::NoRelocation:
-    return SectionKind::DataNoRel;
-  case Constant::LocalRelocation:
-    return SectionKind::DataRelLocal;
-  case Constant::GlobalRelocations:
-    return SectionKind::DataRel;
-  }
-}
-
-/// SectionForGlobal - This method computes the appropriate section to emit
-/// the specified global variable or function definition.  This should not
-/// be passed external (or available externally) globals.
-const Section *TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
-  assert(!GV->isDeclaration() && !GV->hasAvailableExternallyLinkage() &&
-         "Can only be used for global definitions");
-  
-  SectionKind::Kind GVKind = SectionKindForGlobal(GV, TM);
-  
-  SectionKind Kind = SectionKind::get(GVKind, GV->isWeakForLinker(),
-                                      GV->hasSection());
-
-
-  // Select section name.
-  if (GV->hasSection()) {
-    // If the target has special section hacks for specifically named globals,
-    // return them now.
-    if (const Section *TS = getSpecialCasedSectionGlobals(GV, Kind))
-      return TS;
-    
-    // If the target has magic semantics for certain section names, make sure to
-    // pick up the flags.  This allows the user to write things with attribute
-    // section and still get the appropriate section flags printed.
-    GVKind = getKindForNamedSection(GV->getSection().c_str(), GVKind);
-    
-    return getOrCreateSection(GV->getSection().c_str(), false, GVKind);
-  }
-
-  
-  // Use default section depending on the 'type' of global
-  return SelectSectionForGlobal(GV, Kind);
-}
-
-// Lame default implementation. Calculate the section name for global.
-const Section*
-TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
-                                      SectionKind Kind) const {
-  assert(!Kind.isThreadLocal() && "Doesn't support TLS");
-  
-  if (Kind.isText())
-    return getTextSection();
-  
-  if (Kind.isBSS())
-    if (const Section *S = getBSSSection_())
-      return S;
-  
-  if (Kind.isReadOnly())
-    if (const Section *S = getReadOnlySection())
-      return S;
-
-  return getDataSection();
-}
-
-/// getSectionForMergableConstant - Given a mergable constant with the
-/// specified size and relocation information, return a section that it
-/// should be placed in.
-const Section *
-TargetAsmInfo::getSectionForMergeableConstant(SectionKind Kind) const {
-  if (Kind.isReadOnly())
-    if (const Section *S = getReadOnlySection())
-      return S;
-  
-  return getDataSection();
-}
-
-
-const Section *TargetAsmInfo::getOrCreateSection(const char *Name,
-                                                 bool isDirective,
-                                                 SectionKind::Kind Kind) const {
-  Section &S = Sections[Name];
-
-  // This is newly-created section, set it up properly.
-  if (S.Name.empty()) {
-    S.Kind = SectionKind::get(Kind, false /*weak*/, !isDirective);
-    S.Name = Name;
-  }
-
-  return &S;
-}
-
 unsigned TargetAsmInfo::getULEB128Size(unsigned Value) {
   unsigned Size = 0;
   do {
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
new file mode 100644 (file)
index 0000000..b1d9c9a
--- /dev/null
@@ -0,0 +1,647 @@
+//===-- llvm/Target/TargetLoweringObjectFile.cpp - Object File Info -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/ADT/StringExtras.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+//                              Generic Code
+//===----------------------------------------------------------------------===//
+
+TargetLoweringObjectFile::TargetLoweringObjectFile() {
+  TextSection = 0;
+  DataSection = 0;
+  BSSSection_ = 0;
+  ReadOnlySection = 0;
+  TLSDataSection = 0;
+  TLSBSSSection = 0;
+  CStringSection_ = 0;
+}
+
+TargetLoweringObjectFile::~TargetLoweringObjectFile() {
+}
+
+static bool isSuitableForBSS(const GlobalVariable *GV) {
+  Constant *C = GV->getInitializer();
+  
+  // Must have zero initializer.
+  if (!C->isNullValue())
+    return false;
+  
+  // Leave constant zeros in readonly constant sections, so they can be shared.
+  if (GV->isConstant())
+    return false;
+  
+  // If the global has an explicit section specified, don't put it in BSS.
+  if (!GV->getSection().empty())
+    return false;
+  
+  // If -nozero-initialized-in-bss is specified, don't ever use BSS.
+  if (NoZerosInBSS)
+    return false;
+  
+  // Otherwise, put it in BSS!
+  return true;
+}
+
+static bool isConstantString(const Constant *C) {
+  // First check: is we have constant array of i8 terminated with zero
+  const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
+  // Check, if initializer is a null-terminated string
+  if (CVA && CVA->isCString())
+    return true;
+
+  // Another possibility: [1 x i8] zeroinitializer
+  if (isa<ConstantAggregateZero>(C))
+    if (const ArrayType *Ty = dyn_cast<ArrayType>(C->getType()))
+      return (Ty->getElementType() == Type::Int8Ty &&
+              Ty->getNumElements() == 1);
+
+  return false;
+}
+
+static SectionKind::Kind SectionKindForGlobal(const GlobalValue *GV,
+                                              const TargetMachine &TM) {
+  Reloc::Model ReloModel = TM.getRelocationModel();
+  
+  // Early exit - functions should be always in text sections.
+  const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
+  if (GVar == 0)
+    return SectionKind::Text;
+
+  
+  // Handle thread-local data first.
+  if (GVar->isThreadLocal()) {
+    if (isSuitableForBSS(GVar))
+      return SectionKind::ThreadBSS;
+    return SectionKind::ThreadData;
+  }
+
+  // Variable can be easily put to BSS section.
+  if (isSuitableForBSS(GVar))
+    return SectionKind::BSS;
+
+  Constant *C = GVar->getInitializer();
+  
+  // If the global is marked constant, we can put it into a mergable section,
+  // a mergable string section, or general .data if it contains relocations.
+  if (GVar->isConstant()) {
+    // If the initializer for the global contains something that requires a
+    // relocation, then we may have to drop this into a wriable data section
+    // even though it is marked const.
+    switch (C->getRelocationInfo()) {
+    default: llvm_unreachable("unknown relocation info kind");
+    case Constant::NoRelocation:
+      // If initializer is a null-terminated string, put it in a "cstring"
+      // section if the target has it.
+      if (isConstantString(C))
+        return SectionKind::MergeableCString;
+      
+      // Otherwise, just drop it into a mergable constant section.  If we have
+      // a section for this size, use it, otherwise use the arbitrary sized
+      // mergable section.
+      switch (TM.getTargetData()->getTypeAllocSize(C->getType())) {
+      case 4:  return SectionKind::MergeableConst4;
+      case 8:  return SectionKind::MergeableConst8;
+      case 16: return SectionKind::MergeableConst16;
+      default: return SectionKind::MergeableConst;
+      }
+      
+    case Constant::LocalRelocation:
+      // In static relocation model, the linker will resolve all addresses, so
+      // the relocation entries will actually be constants by the time the app
+      // starts up.  However, we can't put this into a mergable section, because
+      // the linker doesn't take relocations into consideration when it tries to
+      // merge entries in the section.
+      if (ReloModel == Reloc::Static)
+        return SectionKind::ReadOnly;
+              
+      // Otherwise, the dynamic linker needs to fix it up, put it in the
+      // writable data.rel.local section.
+      return SectionKind::ReadOnlyWithRelLocal;
+              
+    case Constant::GlobalRelocations:
+      // In static relocation model, the linker will resolve all addresses, so
+      // the relocation entries will actually be constants by the time the app
+      // starts up.  However, we can't put this into a mergable section, because
+      // the linker doesn't take relocations into consideration when it tries to
+      // merge entries in the section.
+      if (ReloModel == Reloc::Static)
+        return SectionKind::ReadOnly;
+      
+      // Otherwise, the dynamic linker needs to fix it up, put it in the
+      // writable data.rel section.
+      return SectionKind::ReadOnlyWithRel;
+    }
+  }
+
+  // Okay, this isn't a constant.  If the initializer for the global is going
+  // to require a runtime relocation by the dynamic linker, put it into a more
+  // specific section to improve startup time of the app.  This coalesces these
+  // globals together onto fewer pages, improving the locality of the dynamic
+  // linker.
+  if (ReloModel == Reloc::Static)
+    return SectionKind::DataNoRel;
+
+  switch (C->getRelocationInfo()) {
+  default: llvm_unreachable("unknown relocation info kind");
+  case Constant::NoRelocation:
+    return SectionKind::DataNoRel;
+  case Constant::LocalRelocation:
+    return SectionKind::DataRelLocal;
+  case Constant::GlobalRelocations:
+    return SectionKind::DataRel;
+  }
+}
+
+/// SectionForGlobal - This method computes the appropriate section to emit
+/// the specified global variable or function definition.  This should not
+/// be passed external (or available externally) globals.
+const Section *TargetLoweringObjectFile::
+SectionForGlobal(const GlobalValue *GV, const TargetMachine &TM) const {
+  assert(!GV->isDeclaration() && !GV->hasAvailableExternallyLinkage() &&
+         "Can only be used for global definitions");
+  
+  SectionKind::Kind GVKind = SectionKindForGlobal(GV, TM);
+  
+  SectionKind Kind = SectionKind::get(GVKind, GV->isWeakForLinker(),
+                                      GV->hasSection());
+
+
+  // Select section name.
+  if (GV->hasSection()) {
+    // If the target has special section hacks for specifically named globals,
+    // return them now.
+    if (const Section *TS = getSpecialCasedSectionGlobals(GV, Kind))
+      return TS;
+    
+    // If the target has magic semantics for certain section names, make sure to
+    // pick up the flags.  This allows the user to write things with attribute
+    // section and still get the appropriate section flags printed.
+    GVKind = getKindForNamedSection(GV->getSection().c_str(), GVKind);
+    
+    return getOrCreateSection(GV->getSection().c_str(), false, GVKind);
+  }
+
+  
+  // Use default section depending on the 'type' of global
+  return SelectSectionForGlobal(GV, Kind, TM);
+}
+
+// Lame default implementation. Calculate the section name for global.
+const Section*
+TargetLoweringObjectFile::SelectSectionForGlobal(const GlobalValue *GV,
+                                                 SectionKind Kind,
+                                                 const TargetMachine &TM) const{
+  assert(!Kind.isThreadLocal() && "Doesn't support TLS");
+  
+  if (Kind.isText())
+    return getTextSection();
+  
+  if (Kind.isBSS() && BSSSection_ != 0)
+    return BSSSection_;
+  
+  if (Kind.isReadOnly() && ReadOnlySection != 0)
+    return ReadOnlySection;
+
+  return getDataSection();
+}
+
+/// getSectionForMergableConstant - Given a mergable constant with the
+/// specified size and relocation information, return a section that it
+/// should be placed in.
+const Section *
+TargetLoweringObjectFile::
+getSectionForMergeableConstant(SectionKind Kind) const {
+  if (Kind.isReadOnly() && ReadOnlySection != 0)
+    return ReadOnlySection;
+  
+  return DataSection;
+}
+
+
+const Section *TargetLoweringObjectFile::
+getOrCreateSection(const char *Name, bool isDirective,
+                   SectionKind::Kind Kind) const {
+  Section &S = Sections[Name];
+
+  // This is newly-created section, set it up properly.
+  if (S.Name.empty()) {
+    S.Kind = SectionKind::get(Kind, false /*weak*/, !isDirective);
+    S.Name = Name;
+  }
+
+  return &S;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+//                                  ELF
+//===----------------------------------------------------------------------===//
+
+TargetLoweringObjectFileELF::TargetLoweringObjectFileELF(bool atIsCommentChar,
+                                                         bool HasCrazyBSS)
+  : AtIsCommentChar(atIsCommentChar) {
+    
+  if (!HasCrazyBSS)
+    BSSSection_ = getOrCreateSection("\t.bss", true, SectionKind::BSS);
+  else
+    // PPC/Linux doesn't support the .bss directive, it needs .section .bss.
+    // FIXME: Does .section .bss work everywhere??
+    BSSSection_ = getOrCreateSection("\t.bss", false, SectionKind::BSS);
+
+    
+  TextSection = getOrCreateSection("\t.text", true, SectionKind::Text);
+  DataSection = getOrCreateSection("\t.data", true, SectionKind::DataRel);
+  ReadOnlySection =
+    getOrCreateSection("\t.rodata", false, SectionKind::ReadOnly);
+  TLSDataSection =
+    getOrCreateSection("\t.tdata", false, SectionKind::ThreadData);
+  CStringSection_ = getOrCreateSection("\t.rodata.str", true,
+                                       SectionKind::MergeableCString);
+
+  TLSBSSSection = getOrCreateSection("\t.tbss", false, SectionKind::ThreadBSS);
+
+  DataRelSection = getOrCreateSection("\t.data.rel", false,
+                                      SectionKind::DataRel);
+  DataRelLocalSection = getOrCreateSection("\t.data.rel.local", false,
+                                           SectionKind::DataRelLocal);
+  DataRelROSection = getOrCreateSection("\t.data.rel.ro", false,
+                                        SectionKind::ReadOnlyWithRel);
+  DataRelROLocalSection =
+    getOrCreateSection("\t.data.rel.ro.local", false,
+                       SectionKind::ReadOnlyWithRelLocal);
+    
+  MergeableConst4Section = getOrCreateSection(".rodata.cst4", false,
+                                              SectionKind::MergeableConst4);
+  MergeableConst8Section = getOrCreateSection(".rodata.cst8", false,
+                                              SectionKind::MergeableConst8);
+  MergeableConst16Section = getOrCreateSection(".rodata.cst16", false,
+                                               SectionKind::MergeableConst16);
+}
+
+
+SectionKind::Kind TargetLoweringObjectFileELF::
+getKindForNamedSection(const char *Name, SectionKind::Kind K) const {
+  if (Name[0] != '.') return K;
+  
+  // Some lame default implementation based on some magic section names.
+  if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
+      strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
+      strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
+      strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
+    return SectionKind::BSS;
+  
+  if (strcmp(Name, ".tdata") == 0 ||
+      strncmp(Name, ".tdata.", 7) == 0 ||
+      strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
+      strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
+    return SectionKind::ThreadData;
+  
+  if (strcmp(Name, ".tbss") == 0 ||
+      strncmp(Name, ".tbss.", 6) == 0 ||
+      strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
+      strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
+    return SectionKind::ThreadBSS;
+  
+  return K;
+}
+
+void TargetLoweringObjectFileELF::
+getSectionFlagsAsString(SectionKind Kind, SmallVectorImpl<char> &Str) const {
+  Str.push_back(',');
+  Str.push_back('"');
+  
+  if (!Kind.isMetadata())
+    Str.push_back('a');
+  if (Kind.isText())
+    Str.push_back('x');
+  if (Kind.isWriteable())
+    Str.push_back('w');
+  if (Kind.isMergeableConst() || Kind.isMergeableCString())
+    Str.push_back('M');
+  if (Kind.isMergeableCString())
+    Str.push_back('S');
+  if (Kind.isThreadLocal())
+    Str.push_back('T');
+  
+  Str.push_back('"');
+  Str.push_back(',');
+  
+  // If comment string is '@', e.g. as on ARM - use '%' instead
+  if (AtIsCommentChar)
+    Str.push_back('%');
+  else
+    Str.push_back('@');
+  
+  const char *KindStr;
+  if (Kind.isBSS())
+    KindStr = "nobits";
+  else
+    KindStr = "progbits";
+  
+  Str.append(KindStr, KindStr+strlen(KindStr));
+  
+  if (Kind.isMergeableCString()) {
+    // TODO: Eventually handle multiple byte character strings.  For now, all
+    // mergable C strings are single byte.
+    Str.push_back(',');
+    Str.push_back('1');
+  } else if (Kind.isMergeableConst4()) {
+    Str.push_back(',');
+    Str.push_back('4');
+  } else if (Kind.isMergeableConst8()) {
+    Str.push_back(',');
+    Str.push_back('8');
+  } else if (Kind.isMergeableConst16()) {
+    Str.push_back(',');
+    Str.push_back('1');
+    Str.push_back('6');
+  }
+}
+
+
+static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
+  if (Kind.isText())                 return ".gnu.linkonce.t.";
+  if (Kind.isReadOnly())             return ".gnu.linkonce.r.";
+  
+  if (Kind.isThreadData())           return ".gnu.linkonce.td.";
+  if (Kind.isThreadBSS())            return ".gnu.linkonce.tb.";
+  
+  if (Kind.isBSS())                  return ".gnu.linkonce.b.";
+  if (Kind.isDataNoRel())            return ".gnu.linkonce.d.";
+  if (Kind.isDataRelLocal())         return ".gnu.linkonce.d.rel.local.";
+  if (Kind.isDataRel())              return ".gnu.linkonce.d.rel.";
+  if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
+  
+  assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+  return ".gnu.linkonce.d.rel.ro.";
+}
+
+const Section *TargetLoweringObjectFileELF::
+SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+                       const TargetMachine &TM) const {
+  
+  // If this global is linkonce/weak and the target handles this by emitting it
+  // into a 'uniqued' section name, create and return the section now.
+  if (Kind.isWeak()) {
+    const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
+    // FIXME: Use mangler interface (PR4584).
+    std::string Name = Prefix+GV->getNameStr();
+    return getOrCreateSection(Name.c_str(), false, Kind.getKind());
+  }
+  
+  if (Kind.isText()) return TextSection;
+  if (Kind.isMergeableCString()) {
+    Constant *C = cast<GlobalVariable>(GV)->getInitializer();
+    
+    // FIXME: This is completely wrong.  Why is it comparing the size of the
+    // character type to 1?
+    /// cast<ArrayType>(C->getType())->getNumElements();
+    uint64_t Size = 1;
+    if (Size <= 16) {
+      assert(CStringSection_ && "Should have string section prefix");
+      
+      // We also need alignment here.
+      // FIXME: this is getting the alignment of the character, not the
+      // alignment of the global!
+      unsigned Align = 
+        TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV));
+      
+      std::string Name = CStringSection_->getName() + utostr(Size) + '.' +
+      utostr(Align);
+      return getOrCreateSection(Name.c_str(), false,
+                                SectionKind::MergeableCString);
+    }
+    
+    return ReadOnlySection;
+  }
+  
+  if (Kind.isMergeableConst()) {
+    if (Kind.isMergeableConst4())
+      return MergeableConst4Section;
+    if (Kind.isMergeableConst8())
+      return MergeableConst8Section;
+    if (Kind.isMergeableConst16())
+      return MergeableConst16Section;
+    return ReadOnlySection;  // .const
+  }
+  
+  if (Kind.isReadOnly())             return ReadOnlySection;
+  
+  if (Kind.isThreadData())           return TLSDataSection;
+  if (Kind.isThreadBSS())            return TLSBSSSection;
+  
+  if (Kind.isBSS())                  return BSSSection_;
+  
+  if (Kind.isDataNoRel())            return DataSection;
+  if (Kind.isDataRelLocal())         return DataRelLocalSection;
+  if (Kind.isDataRel())              return DataRelSection;
+  if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
+  
+  assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+  return DataRelROSection;
+}
+
+/// getSectionForMergeableConstant - Given a mergeable constant with the
+/// specified size and relocation information, return a section that it
+/// should be placed in.
+const Section *TargetLoweringObjectFileELF::
+getSectionForMergeableConstant(SectionKind Kind) const {
+  if (Kind.isMergeableConst4())
+    return MergeableConst4Section;
+  if (Kind.isMergeableConst8())
+    return MergeableConst8Section;
+  if (Kind.isMergeableConst16())
+    return MergeableConst16Section;
+  if (Kind.isReadOnly())
+    return ReadOnlySection;
+  
+  if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection;
+  assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+  return DataRelROSection;
+}
+
+//===----------------------------------------------------------------------===//
+//                                 MachO
+//===----------------------------------------------------------------------===//
+
+TargetLoweringObjectFileMachO::
+TargetLoweringObjectFileMachO() {
+  TextSection = getOrCreateSection("\t.text", true, SectionKind::Text);
+  DataSection = getOrCreateSection("\t.data", true, SectionKind::DataRel);
+  
+  CStringSection_ = getOrCreateSection("\t.cstring", true,
+                                       SectionKind::MergeableCString);
+  FourByteConstantSection = getOrCreateSection("\t.literal4\n", true,
+                                               SectionKind::MergeableConst4);
+  EightByteConstantSection = getOrCreateSection("\t.literal8\n", true,
+                                                SectionKind::MergeableConst8);
+  SixteenByteConstantSection = 
+  getOrCreateSection("\t.literal16\n", true, SectionKind::MergeableConst16);
+  
+  ReadOnlySection = getOrCreateSection("\t.const", true, SectionKind::ReadOnly);
+  
+  TextCoalSection =
+  getOrCreateSection("\t__TEXT,__textcoal_nt,coalesced,pure_instructions",
+                     false, SectionKind::Text);
+  ConstTextCoalSection = getOrCreateSection("\t__TEXT,__const_coal,coalesced",
+                                            false, SectionKind::Text);
+  ConstDataCoalSection = getOrCreateSection("\t__DATA,__const_coal,coalesced",
+                                            false, SectionKind::Text);
+  ConstDataSection = getOrCreateSection("\t.const_data", true,
+                                        SectionKind::ReadOnlyWithRel);
+  DataCoalSection = getOrCreateSection("\t__DATA,__datacoal_nt,coalesced",
+                                       false, SectionKind::DataRel);
+}
+
+const Section *
+TargetLoweringObjectFileMachO::SelectSectionForGlobal(const GlobalValue *GV,
+                                                      SectionKind Kind,
+                                                const TargetMachine &TM) const {
+  assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS");
+  
+  if (Kind.isText())
+    return Kind.isWeak() ? TextCoalSection : TextSection;
+  
+  // If this is weak/linkonce, put this in a coalescable section, either in text
+  // or data depending on if it is writable.
+  if (Kind.isWeak()) {
+    if (Kind.isReadOnly())
+      return ConstTextCoalSection;
+    return DataCoalSection;
+  }
+  
+  // FIXME: Alignment check should be handled by section classifier.
+  if (Kind.isMergeableCString()) {
+    Constant *C = cast<GlobalVariable>(GV)->getInitializer();
+    const Type *Ty = cast<ArrayType>(C->getType())->getElementType();
+    const TargetData &TD = *TM.getTargetData();
+    unsigned Size = TD.getTypeAllocSize(Ty);
+    if (Size) {
+      unsigned Align = TD.getPreferredAlignment(cast<GlobalVariable>(GV));
+      if (Align <= 32)
+        return CStringSection_;
+    }
+    
+    return ReadOnlySection;
+  }
+  
+  if (Kind.isMergeableConst()) {
+    if (Kind.isMergeableConst4())
+      return FourByteConstantSection;
+    if (Kind.isMergeableConst8())
+      return EightByteConstantSection;
+    if (Kind.isMergeableConst16())
+      return SixteenByteConstantSection;
+    return ReadOnlySection;  // .const
+  }
+  
+  // FIXME: ROData -> const in -static mode that is relocatable but they happen
+  // by the static linker.  Why not mergeable?
+  if (Kind.isReadOnly())
+    return ReadOnlySection;
+
+  // If this is marked const, put it into a const section.  But if the dynamic
+  // linker needs to write to it, put it in the data segment.
+  if (Kind.isReadOnlyWithRel())
+    return ConstDataSection;
+  
+  // Otherwise, just drop the variable in the normal data section.
+  return DataSection;
+}
+
+const Section *
+TargetLoweringObjectFileMachO::
+getSectionForMergeableConstant(SectionKind Kind) const {
+  // If this constant requires a relocation, we have to put it in the data
+  // segment, not in the text segment.
+  if (Kind.isDataRel())
+    return ConstDataSection;
+  
+  if (Kind.isMergeableConst4())
+    return FourByteConstantSection;
+  if (Kind.isMergeableConst8())
+    return EightByteConstantSection;
+  if (Kind.isMergeableConst16())
+    return SixteenByteConstantSection;
+  return ReadOnlySection;  // .const
+}
+
+//===----------------------------------------------------------------------===//
+//                                  COFF
+//===----------------------------------------------------------------------===//
+
+TargetLoweringObjectFileCOFF::TargetLoweringObjectFileCOFF() {
+  TextSection = getOrCreateSection("_text", true, SectionKind::Text);
+  DataSection = getOrCreateSection("_data", true, SectionKind::DataRel);
+}
+
+void TargetLoweringObjectFileCOFF::
+getSectionFlagsAsString(SectionKind Kind, SmallVectorImpl<char> &Str) const {
+  // FIXME: Inefficient.
+  std::string Res = ",\"";
+  if (Kind.isText())
+    Res += 'x';
+  if (Kind.isWriteable())
+    Res += 'w';
+  Res += "\"";
+  
+  Str.append(Res.begin(), Res.end());
+}
+
+static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
+  if (Kind.isText())
+    return ".text$linkonce";
+  if (Kind.isWriteable())
+    return ".data$linkonce";
+  return ".rdata$linkonce";
+}
+
+
+const Section *TargetLoweringObjectFileCOFF::
+SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+                       const TargetMachine &TM) const {
+  assert(!Kind.isThreadLocal() && "Doesn't support TLS");
+  
+  // If this global is linkonce/weak and the target handles this by emitting it
+  // into a 'uniqued' section name, create and return the section now.
+  if (Kind.isWeak()) {
+    const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind);
+    // FIXME: Use mangler interface (PR4584).
+    std::string Name = Prefix+GV->getNameStr();
+    return getOrCreateSection(Name.c_str(), false, Kind.getKind());
+  }
+  
+  if (Kind.isText())
+    return getTextSection();
+  
+  if (Kind.isBSS())
+    if (const Section *S = BSSSection_)
+      return S;
+  
+  if (Kind.isReadOnly() && ReadOnlySection != 0)
+    return ReadOnlySection;
+  
+  return getDataSection();
+}
+
index 88c6434497340ce0c7824891d99789cd73aa8912..a93510bb7534569f50be85b9bc256b2698e2c432 100644 (file)
@@ -37,6 +37,7 @@
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetOptions.h"
 using namespace llvm;
 
@@ -166,7 +167,7 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
   if (Subtarget->isTargetCygMing())
     DecorateCygMingName(CurrentFnName, F);
 
-  SwitchToSection(TAI->SectionForGlobal(F));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(F, TM));
   switch (F->getLinkage()) {
   default: llvm_unreachable("Unknown linkage type!");
   case Function::InternalLinkage:  // Symbols default to internal.
@@ -782,7 +783,7 @@ void X86ATTAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
   if (Subtarget->isTargetELF())
     O << "\t.type\t" << name << ",@object\n";
 
-  const Section *TheSection = TAI->SectionForGlobal(GVar);
+  const Section *TheSection = getObjFileLowering().SectionForGlobal(GVar, TM);
   SwitchToSection(TheSection);
 
   if (C->isNullValue() && !GVar->hasSection() &&
@@ -931,7 +932,7 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
     }
 
     if (!HiddenGVStubs.empty()) {
-      SwitchToSection(TAI->getDataSection());
+      SwitchToSection(getObjFileLowering().getDataSection());
       EmitAlignment(2);
       for (StringMap<std::string>::iterator I = HiddenGVStubs.begin(),
            E = HiddenGVStubs.end(); I != E; ++I)
index 6b09b64bf3d97047f393e030f407d00d8f3f6179..337fc7968164eead9e183ddcb03ec39623babe01 100644 (file)
@@ -29,6 +29,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetOptions.h"
 using namespace llvm;
 
@@ -513,7 +514,7 @@ void X86IntelAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
     O << "\tpublic " << name << "\n";
     // FALL THROUGH
   case GlobalValue::InternalLinkage:
-    SwitchToSection(TAI->getDataSection());
+    SwitchToSection(getObjFileLowering().getDataSection());
     break;
   default:
     llvm_unreachable("Unknown linkage type!");
index 42bd7dc98322de40ed13eca8c876ae9c6149e7bb..29f5765d5e10e9a90e5133e36146e400ed96bab0 100644 (file)
@@ -36,6 +36,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
@@ -50,8 +51,23 @@ DisableMMX("disable-mmx", cl::Hidden, cl::desc("Disable use of MMX"));
 static SDValue getMOVL(SelectionDAG &DAG, DebugLoc dl, MVT VT, SDValue V1,
                        SDValue V2);
 
+static TargetLoweringObjectFile *createTLOF(X86TargetMachine &TM) {
+  switch (TM.getSubtarget<X86Subtarget>().TargetType) {
+  default: llvm_unreachable("unknown subtarget type");
+  case X86Subtarget::isDarwin:
+    return new TargetLoweringObjectFileMachO();
+  case X86Subtarget::isELF:
+    return new TargetLoweringObjectFileELF();
+  case X86Subtarget::isMingw:
+  case X86Subtarget::isCygwin:
+  case X86Subtarget::isWindows:
+    return new TargetLoweringObjectFileCOFF();
+  }
+  
+}
+
 X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
-  : TargetLowering(TM) {
+  : TargetLowering(TM, createTLOF(TM)) {
   Subtarget = &TM.getSubtarget<X86Subtarget>();
   X86ScalarSSEf64 = Subtarget->hasSSE2();
   X86ScalarSSEf32 = Subtarget->hasSSE1();
index 40c46bb1de0ca36e66751ac1edb44f7e6237a5f3..b4f503b255ca11eb1d8a8e4af4d031c221af27d9 100644 (file)
@@ -121,8 +121,6 @@ X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM) :
   // Set up DWARF directives
   HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)
 
-  BSSSection_ = getOrCreateSection("\t.bss", true, SectionKind::BSS);
-
   // Debug Information
   AbsoluteDebugSectionOffsets = true;
   SupportsDebugInformation = true;
@@ -252,9 +250,6 @@ X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM):
 
   AlignmentIsInBytes = true;
 
-  TextSection = getOrCreateSection("_text", true, SectionKind::Text);
-  DataSection = getOrCreateSection("_data", true, SectionKind::DataRel);
-
   JumpTableDataSection = NULL;
   SwitchToSectionDirective = "";
   TextSectionStartSuffix = "\tSEGMENT PARA 'CODE'";
index 0847660f2e5842fb3e071694e26610de158f8acc..9b4e8092ae45cc616e99b2f06bc8bb3449c26d8f 100644 (file)
@@ -33,8 +33,6 @@ namespace llvm {
     }
   };
 
-  typedef X86TargetAsmInfo<TargetAsmInfo> X86GenericTargetAsmInfo;
-
   EXTERN_TEMPLATE_INSTANTIATION(class X86TargetAsmInfo<TargetAsmInfo>);
 
   struct X86DarwinTargetAsmInfo : public X86TargetAsmInfo<DarwinTargetAsmInfo> {
@@ -58,7 +56,7 @@ namespace llvm {
   };
   
 
-  struct X86WinTargetAsmInfo : public X86GenericTargetAsmInfo {
+  struct X86WinTargetAsmInfo : public X86TargetAsmInfo<TargetAsmInfo> {
     explicit X86WinTargetAsmInfo(const X86TargetMachine &TM);
   };
 
index a720e6e894d4abf272f25fcb7cce32e7a83deacc..ee0daed167c68ee2f0bf8ecd930cd6634324dd15 100644 (file)
@@ -32,20 +32,18 @@ extern "C" void LLVMInitializeX86Target() {
 const TargetAsmInfo *X86TargetMachine::createTargetAsmInfo() const {
   if (Subtarget.isFlavorIntel())
     return new X86WinTargetAsmInfo(*this);
-  else
-    switch (Subtarget.TargetType) {
-     case X86Subtarget::isDarwin:
-      return new X86DarwinTargetAsmInfo(*this);
-     case X86Subtarget::isELF:
-      return new X86ELFTargetAsmInfo(*this);
-     case X86Subtarget::isMingw:
-     case X86Subtarget::isCygwin:
-      return new X86COFFTargetAsmInfo(*this);
-     case X86Subtarget::isWindows:
-      return new X86WinTargetAsmInfo(*this);
-     default:
-      return new X86GenericTargetAsmInfo(*this);
-    }
+  switch (Subtarget.TargetType) {
+  default: llvm_unreachable("unknown subtarget type");
+  case X86Subtarget::isDarwin:
+    return new X86DarwinTargetAsmInfo(*this);
+  case X86Subtarget::isELF:
+    return new X86ELFTargetAsmInfo(*this);
+  case X86Subtarget::isMingw:
+  case X86Subtarget::isCygwin:
+    return new X86COFFTargetAsmInfo(*this);
+  case X86Subtarget::isWindows:
+    return new X86WinTargetAsmInfo(*this);
+  }
 }
 
 X86_32TargetMachine::X86_32TargetMachine(const Target &T, const Module &M, 
index a7aba14a7a14c5e29d8cba225864d9599525be7c..f4e4c2212c28839e19bc368fb90881f0e882bfa9 100644 (file)
@@ -20,4 +20,5 @@ add_llvm_target(XCore
   XCoreSubtarget.cpp
   XCoreTargetAsmInfo.cpp
   XCoreTargetMachine.cpp
+  XCoreTargetObjectFile.cpp
   )
index 5f2484293f66b095a2850e7abee49f4337ad097f..d57151c0264584d07313d9edc659a5fb899b5d48 100644 (file)
@@ -28,6 +28,7 @@
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetRegistry.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/ADT/Statistic.h"
@@ -133,7 +134,7 @@ void XCoreAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
 
   const TargetData *TD = TM.getTargetData();
   
-  SwitchToSection(TAI->SectionForGlobal(GV));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(GV, TM));
   
   std::string name = Mang->getMangledName(GV);
   Constant *C = GV->getInitializer();
@@ -204,7 +205,7 @@ void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
   // Print out the label for the function.
   const Function *F = MF.getFunction();
 
-  SwitchToSection(TAI->SectionForGlobal(F));
+  SwitchToSection(getObjFileLowering().SectionForGlobal(F, TM));
   
   // Mark the start of the function
   O << "\t.cc_top " << CurrentFnName << ".function," << CurrentFnName << "\n";
index e4e7f27f337e7ba243f4027813dbb0b3c0e5956c..eaab84937504675f9fe2d9274e0fe553ceb26c6b 100644 (file)
@@ -16,6 +16,7 @@
 #include "XCoreISelLowering.h"
 #include "XCoreMachineFunctionInfo.h"
 #include "XCore.h"
+#include "XCoreTargetObjectFile.h"
 #include "XCoreTargetMachine.h"
 #include "XCoreSubtarget.h"
 #include "llvm/DerivedTypes.h"
@@ -55,7 +56,8 @@ getTargetNodeName(unsigned Opcode) const
 }
 
 XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM)
-  : TargetLowering(XTM),
+  : TargetLowering(XTM,
+                   new XCoreTargetObjectFile(XTM.getSubtargetImpl()->isXS1A())),
     TM(XTM),
     Subtarget(*XTM.getSubtargetImpl()) {
 
index fee0a2244cef780f8c3e8d7acaa039bb2a469c9d..fd8c9d7852cb6ab90fcfce53697fbf09021b1578 100644 (file)
@@ -1,4 +1,4 @@
-//===-- XCoreTargetAsmInfo.cpp - XCore asm properties -----------*- C++ -*-===//
+//===-- XCoreTargetAsmInfo.cpp - XCore asm properties ---------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -6,41 +6,13 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
-// This file contains the declarations of the XCoreTargetAsmInfo properties.
-// We use the small section flag for the CP relative and DP relative
-// flags. If a section is small and writable then it is DP relative. If a
-// section is small and not writable then it is CP relative.
-//
-//===----------------------------------------------------------------------===//
 
 #include "XCoreTargetAsmInfo.h"
-#include "XCoreTargetMachine.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/ADT/StringExtras.h"
-
 using namespace llvm;
 
-XCoreTargetAsmInfo::XCoreTargetAsmInfo(const XCoreTargetMachine &TM)
+XCoreTargetAsmInfo::XCoreTargetAsmInfo(const TargetMachine &TM)
   : ELFTargetAsmInfo(TM) {
   SupportsDebugInformation = true;
-  TextSection = getOrCreateSection("\t.text", true, SectionKind::Text);
-  DataSection = getOrCreateSection("\t.dp.data", false, SectionKind::DataRel);
-  BSSSection_ = getOrCreateSection("\t.dp.bss", false, SectionKind::BSS);
-
-  // TLS globals are lowered in the backend to arrays indexed by the current
-  // thread id. After lowering they require no special handling by the linker
-  // and can be placed in the standard data / bss sections.
-  TLSDataSection = DataSection;
-  TLSBSSSection = BSSSection_;
-
-  if (TM.getSubtargetImpl()->isXS1A())
-    // FIXME: Why is this writable???
-    ReadOnlySection = getOrCreateSection("\t.dp.rodata", false,
-                                         SectionKind::DataRel);
-  else
-    ReadOnlySection = getOrCreateSection("\t.cp.rodata", false,
-                                         SectionKind::ReadOnly);
   Data16bitsDirective = "\t.short\t";
   Data32bitsDirective = "\t.long\t";
   Data64bitsDirective = 0;
index 6d38340e2c05b477a57eaf53fce30a11d76dd410..f220815ff982b1a3cb726ff4af7ce9d0853129a0 100644 (file)
 
 namespace llvm {
 
-  // Forward declarations.
-  class XCoreTargetMachine;
-  class XCoreSubtarget;
-
   class XCoreTargetAsmInfo : public ELFTargetAsmInfo {
   public:
-    explicit XCoreTargetAsmInfo(const XCoreTargetMachine &TM);
+    explicit XCoreTargetAsmInfo(const TargetMachine &TM);
   };
 
 } // namespace llvm
diff --git a/lib/Target/XCore/XCoreTargetObjectFile.cpp b/lib/Target/XCore/XCoreTargetObjectFile.cpp
new file mode 100644 (file)
index 0000000..89880c2
--- /dev/null
@@ -0,0 +1,32 @@
+//===-- XCoreTargetObjectFile.cpp - XCore object files --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "XCoreTargetObjectFile.h"
+using namespace llvm;
+
+
+XCoreTargetObjectFile::XCoreTargetObjectFile(bool isXS1A) {
+  TextSection = getOrCreateSection("\t.text", true, SectionKind::Text);
+  DataSection = getOrCreateSection("\t.dp.data", false, SectionKind::DataRel);
+  BSSSection_ = getOrCreateSection("\t.dp.bss", false, SectionKind::BSS);
+  
+  // TLS globals are lowered in the backend to arrays indexed by the current
+  // thread id. After lowering they require no special handling by the linker
+  // and can be placed in the standard data / bss sections.
+  TLSDataSection = DataSection;
+  TLSBSSSection = BSSSection_;
+  
+  if (isXS1A)
+    // FIXME: Why is this writable ("datarel")???
+    ReadOnlySection = getOrCreateSection("\t.dp.rodata", false,
+                                         SectionKind::DataRel);
+  else
+    ReadOnlySection = getOrCreateSection("\t.cp.rodata", false,
+                                         SectionKind::ReadOnly);
+}
\ No newline at end of file
diff --git a/lib/Target/XCore/XCoreTargetObjectFile.h b/lib/Target/XCore/XCoreTargetObjectFile.h
new file mode 100644 (file)
index 0000000..af40e11
--- /dev/null
@@ -0,0 +1,25 @@
+//===-- llvm/Target/XCoreTargetObjectFile.h - XCore Object Info -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_XCORE_TARGETOBJECTFILE_H
+#define LLVM_TARGET_XCORE_TARGETOBJECTFILE_H
+
+#include "llvm/Target/TargetLoweringObjectFile.h"
+
+namespace llvm {
+
+  class XCoreTargetObjectFile : public TargetLoweringObjectFileELF {
+  public:
+    XCoreTargetObjectFile(bool isXS1A);
+    
+    // TODO: Classify globals as xcore wishes.
+  };
+} // end namespace llvm
+
+#endif