summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h4
-rw-r--r--include/llvm/Target/COFFTargetAsmInfo.h8
-rw-r--r--include/llvm/Target/DarwinTargetAsmInfo.h18
-rw-r--r--include/llvm/Target/ELFTargetAsmInfo.h23
-rw-r--r--include/llvm/Target/TargetAsmInfo.h102
-rw-r--r--include/llvm/Target/TargetLowering.h8
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h187
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp17
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp13
-rw-r--r--lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp12
-rw-r--r--lib/CodeGen/ELFWriter.cpp12
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp14
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp9
-rw-r--r--lib/Target/ARM/ARMTargetAsmInfo.cpp2
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp7
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.cpp15
-rw-r--r--lib/Target/Alpha/AlphaTargetAsmInfo.cpp3
-rw-r--r--lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp5
-rw-r--r--lib/Target/CMakeLists.txt1
-rw-r--r--lib/Target/COFFTargetAsmInfo.cpp57
-rw-r--r--lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp7
-rw-r--r--lib/Target/CellSPU/SPUISelLowering.cpp18
-rw-r--r--lib/Target/CellSPU/SPUTargetAsmInfo.cpp4
-rw-r--r--lib/Target/DarwinTargetAsmInfo.cpp103
-rw-r--r--lib/Target/ELFTargetAsmInfo.cpp213
-rw-r--r--lib/Target/MSP430/MSP430AsmPrinter.cpp3
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp4
-rw-r--r--lib/Target/MSP430/MSP430TargetAsmInfo.cpp2
-rw-r--r--lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp9
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp12
-rw-r--r--lib/Target/Mips/MipsTargetAsmInfo.cpp2
-rw-r--r--lib/Target/PIC16/CMakeLists.txt1
-rw-r--r--lib/Target/PIC16/PIC16AsmPrinter.cpp42
-rw-r--r--lib/Target/PIC16/PIC16AsmPrinter.h11
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.cpp4
-rw-r--r--lib/Target/PIC16/PIC16TargetAsmInfo.cpp396
-rw-r--r--lib/Target/PIC16/PIC16TargetAsmInfo.h79
-rw-r--r--lib/Target/PIC16/PIC16TargetObjectFile.cpp401
-rw-r--r--lib/Target/PIC16/PIC16TargetObjectFile.h100
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp15
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp10
-rw-r--r--lib/Target/PowerPC/PPCTargetAsmInfo.cpp3
-rw-r--r--lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp5
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp25
-rw-r--r--lib/Target/Sparc/SparcTargetAsmInfo.cpp21
-rw-r--r--lib/Target/Sparc/SparcTargetAsmInfo.h4
-rw-r--r--lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp5
-rw-r--r--lib/Target/SystemZ/SystemZISelLowering.cpp6
-rw-r--r--lib/Target/SystemZ/SystemZTargetAsmInfo.cpp2
-rw-r--r--lib/Target/TargetAsmInfo.cpp218
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp647
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp7
-rw-r--r--lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp3
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp18
-rw-r--r--lib/Target/X86/X86TargetAsmInfo.cpp5
-rw-r--r--lib/Target/X86/X86TargetAsmInfo.h4
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp26
-rw-r--r--lib/Target/XCore/CMakeLists.txt1
-rw-r--r--lib/Target/XCore/XCoreAsmPrinter.cpp5
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp4
-rw-r--r--lib/Target/XCore/XCoreTargetAsmInfo.cpp32
-rw-r--r--lib/Target/XCore/XCoreTargetAsmInfo.h6
-rw-r--r--lib/Target/XCore/XCoreTargetObjectFile.cpp32
-rw-r--r--lib/Target/XCore/XCoreTargetObjectFile.h25
64 files changed, 1655 insertions, 1402 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 78de33fa72..6cd2d8ea4f 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -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;
diff --git a/include/llvm/Target/COFFTargetAsmInfo.h b/include/llvm/Target/COFFTargetAsmInfo.h
index 4a60c0cce4..a035f2bb87 100644
--- a/include/llvm/Target/COFFTargetAsmInfo.h
+++ b/include/llvm/Target/COFFTargetAsmInfo.h
@@ -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
diff --git a/include/llvm/Target/DarwinTargetAsmInfo.h b/include/llvm/Target/DarwinTargetAsmInfo.h
index 69bc551970..c934c05742 100644
--- a/include/llvm/Target/DarwinTargetAsmInfo.h
+++ b/include/llvm/Target/DarwinTargetAsmInfo.h
@@ -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;
};
}
diff --git a/include/llvm/Target/ELFTargetAsmInfo.h b/include/llvm/Target/ELFTargetAsmInfo.h
index 1b5bc54db6..1b141d5181 100644
--- a/include/llvm/Target/ELFTargetAsmInfo.h
+++ b/include/llvm/Target/ELFTargetAsmInfo.h
@@ -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;
};
}
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index 9031dd2138..95a6d539c8 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -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;
}
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 6c216c932c..1dec92b9f9 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -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
index 0000000000..18ce1de01a
--- /dev/null
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -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
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 0303f26d8e..c9b500df08 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -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 ||
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index f26fb0d6fe..fea00f4f95 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -17,9 +17,10 @@
#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);
}
diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index b9a674d3e0..a87fa9eaf6 100644
--- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -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) {
diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp
index 2679d983f4..fe2ba26244 100644
--- a/lib/CodeGen/ELFWriter.cpp
+++ b/lib/CodeGen/ELFWriter.cpp
@@ -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
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index fcc8f1bcda..85b47a001e 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -11,12 +11,13 @@
//
//===----------------------------------------------------------------------===//
-#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.
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 226f1618c9..3b1be76424 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -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()) {
diff --git a/lib/Target/ARM/ARMTargetAsmInfo.cpp b/lib/Target/ARM/ARMTargetAsmInfo.cpp
index 87f8a68564..34c187492f 100644
--- a/lib/Target/ARM/ARMTargetAsmInfo.cpp
+++ b/lib/Target/ARM/ARMTargetAsmInfo.cpp
@@ -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;
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index 1154aaf714..d82b7585f2 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -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);
diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp
index 310a4a6b03..f7a38c2a48 100644
--- a/lib/Target/Alpha/AlphaISelLowering.cpp
+++ b/lib/Target/Alpha/AlphaISelLowering.cpp
@@ -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"
@@ -30,6 +31,17 @@
#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);
diff --git a/lib/Target/Alpha/AlphaTargetAsmInfo.cpp b/lib/Target/Alpha/AlphaTargetAsmInfo.cpp
index 12fadfb542..6499552242 100644
--- a/lib/Target/Alpha/AlphaTargetAsmInfo.cpp
+++ b/lib/Target/Alpha/AlphaTargetAsmInfo.cpp
@@ -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);
}
diff --git a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
index 08a2c3430e..a37dee7d0c 100644
--- a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
+++ b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
@@ -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());
diff --git a/lib/Target/CMakeLists.txt b/lib/Target/CMakeLists.txt
index 98df86cc82..f5c94f22e8 100644
--- a/lib/Target/CMakeLists.txt
+++ b/lib/Target/CMakeLists.txt
@@ -10,6 +10,7 @@ add_llvm_library(LLVMTarget
TargetFrameInfo.cpp
TargetInstrInfo.cpp
TargetIntrinsicInfo.cpp
+ TargetLoweringObjectFile.cpp
TargetMachOWriterInfo.cpp
TargetMachine.cpp
TargetRegisterInfo.cpp
diff --git a/lib/Target/COFFTargetAsmInfo.cpp b/lib/Target/COFFTargetAsmInfo.cpp
index cd7356d551..f1f742e787 100644
--- a/lib/Target/COFFTargetAsmInfo.cpp
+++ b/lib/Target/COFFTargetAsmInfo.cpp
@@ -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();
-}
diff --git a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
index fd1df767dc..e53543c436 100644
--- a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
+++ b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
@@ -34,9 +34,10 @@
#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() &&
diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp
index d0aad070c2..50ba00f636 100644
--- a/lib/Target/CellSPU/SPUISelLowering.cpp
+++ b/lib/Target/CellSPU/SPUISelLowering.cpp
@@ -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"
@@ -24,15 +25,13 @@
#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();
diff --git a/lib/Target/CellSPU/SPUTargetAsmInfo.cpp b/lib/Target/CellSPU/SPUTargetAsmInfo.cpp
index 534d18e60f..1d71605954 100644
--- a/lib/Target/CellSPU/SPUTargetAsmInfo.cpp
+++ b/lib/Target/CellSPU/SPUTargetAsmInfo.cpp
@@ -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";
diff --git a/lib/Target/DarwinTargetAsmInfo.cpp b/lib/Target/DarwinTargetAsmInfo.cpp
index 5429e65926..aa93c0d119 100644
--- a/lib/Target/DarwinTargetAsmInfo.cpp
+++ b/lib/Target/DarwinTargetAsmInfo.cpp
@@ -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
-}
-
diff --git a/lib/Target/ELFTargetAsmInfo.cpp b/lib/Target/ELFTargetAsmInfo.cpp
index 556b494185..e3259bd916 100644
--- a/lib/Target/ELFTargetAsmInfo.cpp
+++ b/lib/Target/ELFTargetAsmInfo.cpp
@@ -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);
-}
-
diff --git a/lib/Target/MSP430/MSP430AsmPrinter.cpp b/lib/Target/MSP430/MSP430AsmPrinter.cpp
index bb112bc255..81bc81b52d 100644
--- a/lib/Target/MSP430/MSP430AsmPrinter.cpp
+++ b/lib/Target/MSP430/MSP430AsmPrinter.cpp
@@ -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);
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index 7476db9214..9413060f08 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -31,13 +31,15 @@
#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);
diff --git a/lib/Target/MSP430/MSP430TargetAsmInfo.cpp b/lib/Target/MSP430/MSP430TargetAsmInfo.cpp
index cd3cdcff06..43a521d376 100644
--- a/lib/Target/MSP430/MSP430TargetAsmInfo.cpp
+++ b/lib/Target/MSP430/MSP430TargetAsmInfo.cpp
@@ -17,6 +17,4 @@ using namespace llvm;
MSP430TargetAsmInfo::MSP430TargetAsmInfo(const TargetMachine &TM)
: ELFTargetAsmInfo(TM) {
AlignmentIsInBytes = false;
-
- BSSSection_ = getOrCreateSection("\t.bss", true, SectionKind::BSS);
}
diff --git a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
index 9eda5e222c..d0f0487dcf 100644
--- a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
@@ -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() &&
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index f6d171b367..ca94d39e46 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -30,15 +30,13 @@
#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
diff --git a/lib/Target/Mips/MipsTargetAsmInfo.cpp b/lib/Target/Mips/MipsTargetAsmInfo.cpp
index 26f4b3b9ee..1fa02f297d 100644
--- a/lib/Target/Mips/MipsTargetAsmInfo.cpp
+++ b/lib/Target/Mips/MipsTargetAsmInfo.cpp
@@ -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
diff --git a/lib/Target/PIC16/CMakeLists.txt b/lib/Target/PIC16/CMakeLists.txt
index 00d737af4c..ba1dfb45fc 100644
--- a/lib/Target/PIC16/CMakeLists.txt
+++ b/lib/Target/PIC16/CMakeLists.txt
@@ -21,4 +21,5 @@ add_llvm_target(PIC16
PIC16Subtarget.cpp
PIC16TargetAsmInfo.cpp
PIC16TargetMachine.cpp
+ PIC16TargetObjectFile.cpp
)
diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp
index ec86585c1d..7fad6f3156 100644
--- a/lib/Target/PIC16/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp
@@ -25,11 +25,20 @@
#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
diff --git a/lib/Target/PIC16/PIC16AsmPrinter.h b/lib/Target/PIC16/PIC16AsmPrinter.h
index 0e05940caf..c365b5a30d 100644
--- a/lib/Target/PIC16/PIC16AsmPrinter.h
+++ b/lib/Target/PIC16/PIC16AsmPrinter.h
@@ -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"
@@ -28,13 +29,10 @@
#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;
diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp
index 13d9654cb0..f194dc85f2 100644
--- a/lib/Target/PIC16/PIC16ISelLowering.cpp
+++ b/lib/Target/PIC16/PIC16ISelLowering.cpp
@@ -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>();
diff --git a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp b/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
index 5a4387ae25..9912543a87 100644
--- a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
+++ b/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
@@ -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_;
-}
-
diff --git a/lib/Target/PIC16/PIC16TargetAsmInfo.h b/lib/Target/PIC16/PIC16TargetAsmInfo.h
index 1ced3bfde1..8fb9e0c29e 100644
--- a/lib/Target/PIC16/PIC16TargetAsmInfo.h
+++ b/lib/Target/PIC16/PIC16TargetAsmInfo.h
@@ -14,91 +14,22 @@
#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
index 0000000000..efc03acce9
--- /dev/null
+++ b/lib/Target/PIC16/PIC16TargetObjectFile.cpp
@@ -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
index 0000000000..77aea7804b
--- /dev/null
+++ b/lib/Target/PIC16/PIC16TargetObjectFile.h
@@ -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
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index bc0a794154..a1b0780e63 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -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) {
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 8beddd635f..fa1989b3d7 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -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();
diff --git a/lib/Target/PowerPC/PPCTargetAsmInfo.cpp b/lib/Target/PowerPC/PPCTargetAsmInfo.cpp
index a56f965857..5ddd120d93 100644
--- a/lib/Target/PowerPC/PPCTargetAsmInfo.cpp
+++ b/lib/Target/PowerPC/PPCTargetAsmInfo.cpp
@@ -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;
diff --git a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
index ad99cca4ac..7569eeee88 100644
--- a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
+++ b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
@@ -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() &&
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp
index fe7bf93ecc..16d922985b 100644
--- a/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/lib/Target/Sparc/SparcISelLowering.cpp
@@ -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);
diff --git a/lib/Target/Sparc/SparcTargetAsmInfo.cpp b/lib/Target/Sparc/SparcTargetAsmInfo.cpp
index 59897e65e8..169eda7127 100644
--- a/lib/Target/Sparc/SparcTargetAsmInfo.cpp
+++ b/lib/Target/Sparc/SparcTargetAsmInfo.cpp
@@ -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());
-}
diff --git a/lib/Target/Sparc/SparcTargetAsmInfo.h b/lib/Target/Sparc/SparcTargetAsmInfo.h
index 943dcef95e..ae646c3911 100644
--- a/lib/Target/Sparc/SparcTargetAsmInfo.h
+++ b/lib/Target/Sparc/SparcTargetAsmInfo.h
@@ -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
diff --git a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
index 7a16684959..9a9a4b7508 100644
--- a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
+++ b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
@@ -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() &&
diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp
index 8a159d78df..38b4c301b7 100644
--- a/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -31,13 +31,15 @@
#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();
diff --git a/lib/Target/SystemZ/SystemZTargetAsmInfo.cpp b/lib/Target/SystemZ/SystemZTargetAsmInfo.cpp
index 0079586dc4..25048b81bc 100644
--- a/lib/Target/SystemZ/SystemZTargetAsmInfo.cpp
+++ b/lib/Target/SystemZ/SystemZTargetAsmInfo.cpp
@@ -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);
}
diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp
index 1cb085bcd1..e71bd01aae 100644
--- a/lib/Target/TargetAsmInfo.cpp
+++ b/lib/Target/TargetAsmInfo.cpp
@@ -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
index 0000000000..b1d9c9a1a1
--- /dev/null
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -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();
+}
+
diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
index 88c6434497..a93510bb75 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
@@ -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)
diff --git a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp
index 6b09b64bf3..337fc79681 100644
--- a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp
@@ -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!");
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 42bd7dc983..29f5765d5e 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -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();
diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp
index 40c46bb1de..b4f503b255 100644
--- a/lib/Target/X86/X86TargetAsmInfo.cpp
+++ b/lib/Target/X86/X86TargetAsmInfo.cpp
@@ -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'";
diff --git a/lib/Target/X86/X86TargetAsmInfo.h b/lib/Target/X86/X86TargetAsmInfo.h
index 0847660f2e..9b4e8092ae 100644
--- a/lib/Target/X86/X86TargetAsmInfo.h
+++ b/lib/Target/X86/X86TargetAsmInfo.h
@@ -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);
};
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index a720e6e894..ee0daed167 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -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,
diff --git a/lib/Target/XCore/CMakeLists.txt b/lib/Target/XCore/CMakeLists.txt
index a7aba14a7a..f4e4c2212c 100644
--- a/lib/Target/XCore/CMakeLists.txt
+++ b/lib/Target/XCore/CMakeLists.txt
@@ -20,4 +20,5 @@ add_llvm_target(XCore
XCoreSubtarget.cpp
XCoreTargetAsmInfo.cpp
XCoreTargetMachine.cpp
+ XCoreTargetObjectFile.cpp
)
diff --git a/lib/Target/XCore/XCoreAsmPrinter.cpp b/lib/Target/XCore/XCoreAsmPrinter.cpp
index 5f2484293f..d57151c026 100644
--- a/lib/Target/XCore/XCoreAsmPrinter.cpp
+++ b/lib/Target/XCore/XCoreAsmPrinter.cpp
@@ -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";
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp
index e4e7f27f33..eaab849375 100644
--- a/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/lib/Target/XCore/XCoreISelLowering.cpp
@@ -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()) {
diff --git a/lib/Target/XCore/XCoreTargetAsmInfo.cpp b/lib/Target/XCore/XCoreTargetAsmInfo.cpp
index fee0a2244c..fd8c9d7852 100644
--- a/lib/Target/XCore/XCoreTargetAsmInfo.cpp
+++ b/lib/Target/XCore/XCoreTargetAsmInfo.cpp
@@ -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;
diff --git a/lib/Target/XCore/XCoreTargetAsmInfo.h b/lib/Target/XCore/XCoreTargetAsmInfo.h
index 6d38340e2c..f220815ff9 100644
--- a/lib/Target/XCore/XCoreTargetAsmInfo.h
+++ b/lib/Target/XCore/XCoreTargetAsmInfo.h
@@ -18,13 +18,9 @@
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
index 0000000000..89880c29f4
--- /dev/null
+++ b/lib/Target/XCore/XCoreTargetObjectFile.cpp
@@ -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
index 0000000000..af40e11f89
--- /dev/null
+++ b/lib/Target/XCore/XCoreTargetObjectFile.h
@@ -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