diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp new file mode 100644 index 00000000000..89891ff7f93 --- /dev/null +++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp @@ -0,0 +1,61 @@ +//===-- MipsELFStreamer.cpp - MipsELFStreamer ---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===-------------------------------------------------------------------===// +#include "MCTargetDesc/MipsELFStreamer.h" +#include "MipsSubtarget.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/Support/ELF.h" +#include "llvm/Support/ErrorHandling.h" + +namespace llvm { + + MCELFStreamer* createMipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + bool RelaxAll, bool NoExecStack) { + MipsELFStreamer *S = new MipsELFStreamer(Context, TAB, OS, Emitter, + RelaxAll, NoExecStack); + return S; + } + + // For llc. Set a group of ELF header flags + void + MipsELFStreamer::emitELFHeaderFlagsCG(const MipsSubtarget &Subtarget) { + + if (hasRawTextSupport()) + return; + + // Update e_header flags + MCAssembler& MCA = getAssembler(); + unsigned EFlags = MCA.getELFHeaderEFlags(); + + EFlags |= ELF::EF_MIPS_NOREORDER; + + // Architecture + if (Subtarget.hasMips64r2()) + EFlags |= ELF::EF_MIPS_ARCH_64R2; + else if (Subtarget.hasMips64()) + EFlags |= ELF::EF_MIPS_ARCH_64; + else if (Subtarget.hasMips32r2()) + EFlags |= ELF::EF_MIPS_ARCH_32R2; + else + EFlags |= ELF::EF_MIPS_ARCH_32; + + // Relocation Model + Reloc::Model RM = Subtarget.getRelocationModel(); + if (RM == Reloc::PIC_ || RM == Reloc::Default) + EFlags |= ELF::EF_MIPS_PIC; + else if (RM == Reloc::Static) + ; // Do nothing for Reloc::Static + else + llvm_unreachable("Unsupported relocation model for e_flags"); + + MCA.setELFHeaderEFlags(EFlags); + + + } +} diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h new file mode 100644 index 00000000000..7739bd983a6 --- /dev/null +++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h @@ -0,0 +1,37 @@ +//=== MipsELFStreamer.h - MipsELFStreamer ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENCE.TXT for details. +// +//===-------------------------------------------------------------------===// +#ifndef MIPSELFSTREAMER_H_ +#define MIPSELFSTREAMER_H_ + +#include "llvm/MC/MCELFStreamer.h" + +namespace llvm { +class MipsSubtarget; + +class MipsELFStreamer : public MCELFStreamer { +private: + unsigned EFlags; +public: + MipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + bool RelaxAll, bool NoExecStack) + : MCELFStreamer(Context, TAB, OS, Emitter), EFlags(0) { + } + + ~MipsELFStreamer() {} + void emitELFHeaderFlagsCG(const MipsSubtarget &Subtarget); +// void emitELFHeaderFlagCG(unsigned Val); +}; + + MCELFStreamer* createMipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + bool RelaxAll, bool NoExecStack); +} + +#endif /* MIPSELFSTREAMER_H_ */ diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index 936097137d0..be83b54b612 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "MCTargetDesc/MipsELFStreamer.h" #include "MipsMCTargetDesc.h" #include "InstPrinter/MipsInstPrinter.h" #include "MipsMCAsmInfo.h" @@ -131,7 +132,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT, bool NoExecStack) { Triple TheTriple(TT); - return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack); + return createMipsELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack); } extern "C" void LLVMInitializeMipsTargetMC() { diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index e3c34297ce1..df6baaf474e 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -15,6 +15,7 @@ #define DEBUG_TYPE "mips-asm-printer" #include "InstPrinter/MipsInstPrinter.h" #include "MCTargetDesc/MipsBaseInfo.h" +#include "MCTargetDesc/MipsELFStreamer.h" #include "Mips.h" #include "MipsAsmPrinter.h" #include "MipsInstrInfo.h" @@ -545,9 +546,13 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) { + if (OutStreamer.hasRawTextSupport()) return; + // Emit Mips ELF register info Subtarget->getMReginfo().emitMipsReginfoSectionCG( OutStreamer, getObjFileLowering(), *Subtarget); + MipsELFStreamer & MES = static_cast(OutStreamer); + MES.emitELFHeaderFlagsCG(*Subtarget); } MachineLocation diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp index 30d377aef79..6ad97db7626 100644 --- a/lib/Target/Mips/MipsSubtarget.cpp +++ b/lib/Target/Mips/MipsSubtarget.cpp @@ -26,13 +26,13 @@ void MipsSubtarget::anchor() { } MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, const std::string &FS, bool little, - Reloc::Model RM) : + Reloc::Model _RM) : MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(Mips32), MipsABI(UnknownABI), IsLittle(little), IsSingleFloat(false), IsFP64bit(false), IsGP64bit(false), HasVFPU(false), IsLinux(true), HasSEInReg(false), HasCondMov(false), HasSwap(false), HasBitCount(false), HasFPIdx(false), - InMips16Mode(false), HasDSP(false), HasDSPR2(false), IsAndroid(false) + InMips16Mode(false), HasDSP(false), HasDSPR2(false), IsAndroid(false), RM(_RM) { std::string CPUName = CPU; if (CPUName.empty()) diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index 001d8d1b429..63cde8d6689 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -100,6 +100,9 @@ protected: // The instance to the register info section object MipsReginfo MRI; + // Relocation Model + Reloc::Model RM; + public: virtual bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, AntiDepBreakMode& Mode, @@ -152,6 +155,9 @@ public: // Grab MipsRegInfo object const MipsReginfo &getMReginfo() const { return MRI; } + + // Grab relocation model + Reloc::Model getRelocationModel() const {return RM;} }; } // End llvm namespace diff --git a/test/MC/Mips/elf_eflags.ll b/test/MC/Mips/elf_eflags.ll new file mode 100644 index 00000000000..4f29c72345b --- /dev/null +++ b/test/MC/Mips/elf_eflags.ll @@ -0,0 +1,55 @@ +; This tests ELF EFLAGS setting with direct object. +; When the assembler is ready a .s file for it will +; be created. + +; Non-shared (static) is the absence of pic and or cpic. + +; EF_MIPS_NOREORDER (0x00000001) is always on by default currently +; EF_MIPS_PIC (0x00000002) +; EF_MIPS_CPIC (0x00000004) - not tested yet +; EF_MIPS_ABI2 (0x00000020) - n32 not tested yet +; EF_MIPS_ARCH_32 (0x50000000) +; EF_MIPS_ARCH_64 (0x60000000) +; EF_MIPS_ARCH_32R2 (0x70000000) +; EF_MIPS_ARCH_64R2 (0x80000000) + +; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32 -relocation-model=static %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=CHECK-BE32 %s +; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32 %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=CHECK-BE32_PIC %s +; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32r2 -relocation-model=static %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=CHECK-BE32R2 %s +; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32r2 %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=CHECK-BE32R2_PIC %s + +; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips64 -relocation-model=static %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=CHECK-BE64 %s +; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips64 %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=CHECK-BE64_PIC %s +; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips64r2 -relocation-model=static %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=CHECK-BE64R2 %s +; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips64r2 %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=CHECK-BE64R2_PIC %s + + +; 32(R1) bit with NO_REORDER and static +; CHECK-BE32: ('e_flags', 0x50000001) +; +; 32(R1) bit with NO_REORDER and PIC +; CHECK-BE32_PIC: ('e_flags', 0x50000003) +; +; 32R2 bit with NO_REORDER and static +; CHECK-BE32R2: ('e_flags', 0x70000001) +; +; 32R2 bit with NO_REORDER and PIC +; CHECK-BE32R2_PIC: ('e_flags', 0x70000003) +; +; 64(R1) bit with NO_REORDER and static +; CHECK-BE64: ('e_flags', 0x60000001) +; +; 64(R1) bit with NO_REORDER and PIC +; CHECK-BE64_PIC: ('e_flags', 0x60000003) +; +; 64R2 bit with NO_REORDER and static +; CHECK-BE64R2: ('e_flags', 0x80000001) +; +; 64R2 bit with NO_REORDER and PIC +; CHECK-BE64R2_PIC: ('e_flags', 0x80000003) +; + +define i32 @main() nounwind { +entry: + ret i32 0 +}