diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 49501978401..3228aa7bb90 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -76,6 +76,8 @@ public: // Allow a target to add behavior to the EmitLabel of MCStreamer. virtual void emitLabel(MCSymbol *Symbol); + + virtual void finish(); }; // FIXME: declared here because it is used from diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 996be956e90..0a69dab0b1f 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -32,6 +32,8 @@ MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) { void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {} +void MCTargetStreamer::finish() {} + MCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false), CurrentW64UnwindInfo(0), LastSymbol(0) { @@ -624,6 +626,10 @@ void MCStreamer::Finish() { if (!FrameInfos.empty() && !FrameInfos.back().End) report_fatal_error("Unfinished frame!"); + MCTargetStreamer *TS = getTargetStreamer(); + if (TS) + TS->finish(); + FinishImpl(); } diff --git a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt index dc20647da20..cf64f4a0a22 100644 --- a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt @@ -4,6 +4,5 @@ add_llvm_library(LLVMMipsDesc MipsMCCodeEmitter.cpp MipsMCTargetDesc.cpp MipsELFObjectWriter.cpp - MipsReginfo.cpp MipsTargetStreamer.cpp ) diff --git a/lib/Target/Mips/MCTargetDesc/MipsReginfo.cpp b/lib/Target/Mips/MCTargetDesc/MipsReginfo.cpp deleted file mode 100644 index 1dc9bcb36a5..00000000000 --- a/lib/Target/Mips/MCTargetDesc/MipsReginfo.cpp +++ /dev/null @@ -1,80 +0,0 @@ -//===-- MipsReginfo.cpp - Registerinfo handling --------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -// .reginfo -// Elf32_Word ri_gprmask -// Elf32_Word ri_cprmask[4] -// Elf32_Word ri_gp_value -// -// .MIPS.options - N64 -// Elf64_Byte kind (ODK_REGINFO) -// Elf64_Byte size (40 bytes) -// Elf64_Section section (0) -// Elf64_Word info (unused) -// Elf64_Word ri_gprmask () -// Elf64_Word ri_pad () -// Elf64_Word[4] ri_cprmask () -// Elf64_Addr ri_gp_value () -// -// .MIPS.options - N32 -// Elf32_Byte kind (ODK_REGINFO) -// Elf32_Byte size (36 bytes) -// Elf32_Section section (0) -// Elf32_Word info (unused) -// Elf32_Word ri_gprmask () -// Elf32_Word ri_pad () -// Elf32_Word[4] ri_cprmask () -// Elf32_Addr ri_gp_value () -// -//===----------------------------------------------------------------------===// -#include "MCTargetDesc/MipsReginfo.h" -#include "MipsSubtarget.h" -#include "MipsTargetObjectFile.h" -#include "llvm/MC/MCStreamer.h" - -using namespace llvm; - -// Integrated assembler version -void -MipsReginfo::emitMipsReginfoSectionCG(MCStreamer &OS, - const TargetLoweringObjectFile &TLOF, - const MipsSubtarget &MST) const -{ - - if (OS.hasRawTextSupport()) - return; - - const MipsTargetObjectFile &TLOFELF = - static_cast<const MipsTargetObjectFile &>(TLOF); - OS.SwitchSection(TLOFELF.getReginfoSection()); - - // .reginfo - if (MST.isABI_O32()) { - OS.EmitIntValue(0, 4); // ri_gprmask - OS.EmitIntValue(0, 4); // ri_cpr[0]mask - OS.EmitIntValue(0, 4); // ri_cpr[1]mask - OS.EmitIntValue(0, 4); // ri_cpr[2]mask - OS.EmitIntValue(0, 4); // ri_cpr[3]mask - OS.EmitIntValue(0, 4); // ri_gp_value - } - // .MIPS.options - else if (MST.isABI_N64()) { - OS.EmitIntValue(1, 1); // kind - OS.EmitIntValue(40, 1); // size - OS.EmitIntValue(0, 2); // section - OS.EmitIntValue(0, 4); // info - OS.EmitIntValue(0, 4); // ri_gprmask - OS.EmitIntValue(0, 4); // pad - OS.EmitIntValue(0, 4); // ri_cpr[0]mask - OS.EmitIntValue(0, 4); // ri_cpr[1]mask - OS.EmitIntValue(0, 4); // ri_cpr[2]mask - OS.EmitIntValue(0, 4); // ri_cpr[3]mask - OS.EmitIntValue(0, 8); // ri_gp_value - } - else llvm_unreachable("Unsupported abi for reginfo"); -} - diff --git a/lib/Target/Mips/MCTargetDesc/MipsReginfo.h b/lib/Target/Mips/MCTargetDesc/MipsReginfo.h deleted file mode 100644 index 039b8eaaf28..00000000000 --- a/lib/Target/Mips/MCTargetDesc/MipsReginfo.h +++ /dev/null @@ -1,31 +0,0 @@ -//=== MipsReginfo.h - MipsReginfo -----------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENCE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef MIPSREGINFO_H -#define MIPSREGINFO_H - -namespace llvm { - class MCStreamer; - class TargetLoweringObjectFile; - class MipsSubtarget; - - class MipsReginfo { - void anchor(); - public: - MipsReginfo() {} - - void emitMipsReginfoSectionCG(MCStreamer &OS, - const TargetLoweringObjectFile &TLOF, - const MipsSubtarget &MST) const; - }; - -} // namespace llvm - -#endif - diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 41b8ad6b96b..825c1644722 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -12,9 +12,12 @@ //===----------------------------------------------------------------------===// #include "InstPrinter/MipsInstPrinter.h" +#include "MipsTargetObjectFile.h" #include "MipsTargetStreamer.h" #include "MipsMCTargetDesc.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCELF.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/CommandLine.h" @@ -118,7 +121,7 @@ void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask, // This part is for ELF object output. MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI) - : MipsTargetStreamer(S), MicroMipsEnabled(false) { + : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) { MCAssembler &MCA = getStreamer().getAssembler(); uint64_t Features = STI.getFeatureBits(); Triple T(STI.getTargetTriple()); @@ -170,6 +173,45 @@ void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) { MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2); } +void MipsTargetELFStreamer::finish() { + MCAssembler &MCA = getStreamer().getAssembler(); + MCContext &Context = MCA.getContext(); + MCStreamer &OS = getStreamer(); + Triple T(STI.getTargetTriple()); + uint64_t Features = STI.getFeatureBits(); + + if (T.isArch64Bit() && (Features & Mips::FeatureN64)) { + const MCSectionELF *Sec = Context.getELFSection( + ".MIPS.options", ELF::SHT_MIPS_OPTIONS, + ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, SectionKind::getMetadata()); + OS.SwitchSection(Sec); + + OS.EmitIntValue(1, 1); // kind + OS.EmitIntValue(40, 1); // size + OS.EmitIntValue(0, 2); // section + OS.EmitIntValue(0, 4); // info + OS.EmitIntValue(0, 4); // ri_gprmask + OS.EmitIntValue(0, 4); // pad + OS.EmitIntValue(0, 4); // ri_cpr[0]mask + OS.EmitIntValue(0, 4); // ri_cpr[1]mask + OS.EmitIntValue(0, 4); // ri_cpr[2]mask + OS.EmitIntValue(0, 4); // ri_cpr[3]mask + OS.EmitIntValue(0, 8); // ri_gp_value + } else { + const MCSectionELF *Sec = + Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, ELF::SHF_ALLOC, + SectionKind::getMetadata()); + OS.SwitchSection(Sec); + + OS.EmitIntValue(0, 4); // ri_gprmask + OS.EmitIntValue(0, 4); // ri_cpr[0]mask + OS.EmitIntValue(0, 4); // ri_cpr[1]mask + OS.EmitIntValue(0, 4); // ri_cpr[2]mask + OS.EmitIntValue(0, 4); // ri_cpr[3]mask + OS.EmitIntValue(0, 4); // ri_gp_value + } +} + MCELFStreamer &MipsTargetELFStreamer::getStreamer() { return static_cast<MCELFStreamer &>(Streamer); } diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index a5ac2ab8bc4..7757132fc62 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -621,12 +621,6 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { OutStreamer.SwitchSection(OutContext.getObjectFileInfo()->getTextSection()); } -void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) { - // Emit Mips ELF register info - Subtarget->getMReginfo().emitMipsReginfoSectionCG( - OutStreamer, getObjFileLowering(), *Subtarget); -} - void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS) { // TODO: implement diff --git a/lib/Target/Mips/MipsAsmPrinter.h b/lib/Target/Mips/MipsAsmPrinter.h index ac019110644..1af4ac8b529 100644 --- a/lib/Target/Mips/MipsAsmPrinter.h +++ b/lib/Target/Mips/MipsAsmPrinter.h @@ -100,7 +100,6 @@ public: void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, const char *Modifier = 0); void EmitStartOfAsmFile(Module &M); - void EmitEndOfAsmFile(Module &M); void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); }; } diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index 50f8194e8d7..bfdb0c945ea 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -14,7 +14,6 @@ #ifndef MIPSSUBTARGET_H #define MIPSSUBTARGET_H -#include "MCTargetDesc/MipsReginfo.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetSubtargetInfo.h" @@ -117,9 +116,6 @@ protected: InstrItineraryData InstrItins; - // The instance to the register info section object - MipsReginfo MRI; - // Relocation Model Reloc::Model RM; @@ -218,9 +214,6 @@ static bool useConstantIslands(); unsigned stackAlignment() const { return hasMips64() ? 16 : 8; } - // Grab MipsRegInfo object - const MipsReginfo &getMReginfo() const { return MRI; } - // Grab relocation model Reloc::Model getRelocationModel() const {return RM;} diff --git a/lib/Target/Mips/MipsTargetObjectFile.cpp b/lib/Target/Mips/MipsTargetObjectFile.cpp index 4c748c5b57c..a476c5c3244 100644 --- a/lib/Target/Mips/MipsTargetObjectFile.cpp +++ b/lib/Target/Mips/MipsTargetObjectFile.cpp @@ -37,21 +37,6 @@ void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ getContext().getELFSection(".sbss", ELF::SHT_NOBITS, ELF::SHF_WRITE |ELF::SHF_ALLOC, SectionKind::getBSS()); - - // Register info information - const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>(); - if (Subtarget.isABI_N64() || Subtarget.isABI_N32()) - ReginfoSection = - getContext().getELFSection(".MIPS.options", - ELF::SHT_MIPS_OPTIONS, - ELF::SHF_ALLOC |ELF::SHF_MIPS_NOSTRIP, - SectionKind::getMetadata()); - else - ReginfoSection = - getContext().getELFSection(".reginfo", - ELF::SHT_MIPS_REGINFO, - ELF::SHF_ALLOC, - SectionKind::getMetadata()); } // A address must be loaded from a small section if its size is less than the diff --git a/lib/Target/Mips/MipsTargetObjectFile.h b/lib/Target/Mips/MipsTargetObjectFile.h index c0e9140c829..658a49a6d81 100644 --- a/lib/Target/Mips/MipsTargetObjectFile.h +++ b/lib/Target/Mips/MipsTargetObjectFile.h @@ -17,7 +17,6 @@ namespace llvm { class MipsTargetObjectFile : public TargetLoweringObjectFileELF { const MCSection *SmallDataSection; const MCSection *SmallBSSSection; - const MCSection *ReginfoSection; public: void Initialize(MCContext &Ctx, const TargetMachine &TM); @@ -34,9 +33,6 @@ namespace llvm { SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const; - - // TODO: Classify globals as mips wishes. - const MCSection *getReginfoSection() const { return ReginfoSection; } }; } // end namespace llvm diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h index 6878343b36b..b5d04ffba18 100644 --- a/lib/Target/Mips/MipsTargetStreamer.h +++ b/lib/Target/Mips/MipsTargetStreamer.h @@ -72,6 +72,7 @@ public: // This part is for ELF object output class MipsTargetELFStreamer : public MipsTargetStreamer { bool MicroMipsEnabled; + const MCSubtargetInfo &STI; public: bool isMicroMipsEnabled() const { return MicroMipsEnabled; } @@ -79,6 +80,7 @@ public: MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); virtual void emitLabel(MCSymbol *Symbol) LLVM_OVERRIDE; + void finish() LLVM_OVERRIDE; virtual void emitDirectiveSetMicroMips(); virtual void emitDirectiveSetNoMicroMips(); diff --git a/test/MC/Mips/elf-reginfo.ll b/test/MC/Mips/elf-reginfo.ll deleted file mode 100644 index a255af931d8..00000000000 --- a/test/MC/Mips/elf-reginfo.ll +++ /dev/null @@ -1,34 +0,0 @@ - ; RUN: llc -filetype=obj -march=mips64el -mcpu=mips64 %s -o - \ - ; RUN: | llvm-readobj -s | FileCheck --check-prefix=CHECK_64 %s - ; RUN: llc -filetype=obj -march=mipsel -mcpu=mips32 %s -o - \ - ; RUN: | llvm-readobj -s | FileCheck --check-prefix=CHECK_32 %s - -; Check for register information sections. -; - -@str = private unnamed_addr constant [12 x i8] c"hello world\00" - -define i32 @main() nounwind { -entry: -; Check that the appropriate relocations were created. - -; check for .MIPS.options -; CHECK_64: Sections [ -; CHECK_64: Section { -; CHECK_64: Name: .MIPS.options -; CHECK_64-NEXT: Type: SHT_MIPS_OPTIONS -; CHECK_64-NEXT: Flags [ (0x8000002) - -; check for .reginfo -; CHECK_32: Sections [ -; CHECK_32: Section { -; CHECK_32: Name: .reginfo -; CHECK_32-NEXT: Type: SHT_MIPS_REGINFO -; CHECK_32-NEXT: Flags [ (0x2) - - - %puts = tail call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @str, i64 0, i64 0)) - ret i32 0 - -} -declare i32 @puts(i8* nocapture) nounwind diff --git a/test/MC/Mips/elf_reginfo.s b/test/MC/Mips/elf_reginfo.s new file mode 100644 index 00000000000..142606458ec --- /dev/null +++ b/test/MC/Mips/elf_reginfo.s @@ -0,0 +1,26 @@ +# These *MUST* match the output of gas compiled with the same triple and +# corresponding options (-mabi=64 -> -mattr=+n64 for example). + +# RUN: llvm-mc -filetype=obj -triple=mips64el-linux -mattr=+n64 %s -o - \ +# RUN: | llvm-readobj -s | FileCheck --check-prefix=CHECK_64 %s +# RUN: llvm-mc -filetype=obj -triple=mipsel %s -mattr=+n32 -o - \ +# RUN: | llvm-readobj -s | FileCheck --check-prefix=CHECK_32 %s + +# Check for register information sections. +# + +# Check that the appropriate relocations were created. + +# check for .MIPS.options +# CHECK_64: Sections [ +# CHECK_64: Section { +# CHECK_64: Name: .MIPS.options +# CHECK_64-NEXT: Type: SHT_MIPS_OPTIONS +# CHECK_64-NEXT: Flags [ (0x8000002) + +# check for .reginfo +# CHECK_32: Sections [ +# CHECK_32: Section { +# CHECK_32: Name: .reginfo +# CHECK_32-NEXT: Type: SHT_MIPS_REGINFO +# CHECK_32-NEXT: Flags [ (0x2)