diff options
-rw-r--r-- | lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 59 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 14 | ||||
-rw-r--r-- | lib/Target/Mips/MipsAsmPrinter.cpp | 26 | ||||
-rw-r--r-- | lib/Target/Mips/MipsAsmPrinter.h | 6 | ||||
-rw-r--r-- | lib/Target/Mips/MipsTargetStreamer.h | 6 | ||||
-rw-r--r-- | test/MC/Mips/elf_eflags.ll | 102 | ||||
-rw-r--r-- | test/MC/Mips/elf_eflags.s | 20 | ||||
-rw-r--r-- | test/MC/Mips/elf_st_other.ll | 5 |
8 files changed, 162 insertions, 76 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index aae2dcd16e..35ad7680be 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -21,6 +21,9 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetAsmParser.h" +#include "llvm/Support/ELF.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/ADT/APInt.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/TargetRegistry.h" @@ -194,7 +197,6 @@ class MipsAsmParser : public MCTargetAsmParser { bool isEvaluated(const MCExpr *Expr); bool parseDirectiveSet(); - bool parseDirectiveMipsHackELFFlags(); bool parseDirectiveOption(); bool parseSetAtDirective(); @@ -257,6 +259,9 @@ class MipsAsmParser : public MCTargetAsmParser { // Example: INSERT.B $w0[n], $1 => 16 > n >= 0 bool validateMSAIndex(int Val, int RegKind); + // Set ELF flags based on defaults and commandline arguments. + void processInitialEFlags(); + public: MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, const MCInstrInfo &MII) @@ -264,6 +269,7 @@ public: hasConsumedDollar(false) { // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); + processInitialEFlags(); } MCAsmParser &getParser() const { return Parser; } @@ -2429,17 +2435,6 @@ bool MipsAsmParser::parseDirectiveSet() { return true; } -bool MipsAsmParser::parseDirectiveMipsHackELFFlags() { - int64_t Flags = 0; - if (Parser.parseAbsoluteExpression(Flags)) { - TokError("unexpected token"); - return false; - } - - getTargetStreamer().emitMipsHackELFFlags(Flags); - return false; -} - /// parseDirectiveWord /// ::= .word [ expression (, expression)* ] bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { @@ -2558,9 +2553,6 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { return false; } - if (IDVal == ".mips_hack_elf_flags") - return parseDirectiveMipsHackELFFlags(); - if (IDVal == ".option") return parseDirectiveOption(); @@ -2577,6 +2569,43 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { return true; } +void MipsAsmParser::processInitialEFlags() { + // Start will a clean slate. + unsigned EFlags = 0; + unsigned FeatureBits = STI.getFeatureBits(); + + // Default settings + EFlags |= ELF::EF_MIPS_NOREORDER | ELF::EF_MIPS_PIC | ELF::EF_MIPS_ABI_O32; + + // ISA + if (FeatureBits & Mips::FeatureMips64r2) { + EFlags |= ELF::EF_MIPS_ARCH_64R2; + EFlags &= ~ELF::EF_MIPS_ABI_O32; + } else if (FeatureBits & Mips::FeatureMips64) { + EFlags |= ELF::EF_MIPS_ARCH_64; + EFlags &= ~ELF::EF_MIPS_ABI_O32; + } else if (FeatureBits & Mips::FeatureMips32r2) + EFlags |= ELF::EF_MIPS_ARCH_32R2; + else if (FeatureBits & Mips::FeatureMips32) + EFlags |= ELF::EF_MIPS_ARCH_32; + else if (FeatureBits & Mips::FeatureO32) + EFlags |= ELF::EF_MIPS_ABI_O32; // This is really a zero + + // ASE + if (FeatureBits & Mips::FeatureMicroMips) + EFlags |= ELF::EF_MIPS_MICROMIPS; + else if (FeatureBits & Mips::FeatureMips16) + EFlags |= ELF::EF_MIPS_ARCH_ASE_M16; + + // ABI + // TODO: n32/eabi + + // Linkage model + // TODO: pic/cpic/static + + getTargetStreamer().emitMipsELFFlags(EFlags); +} + extern "C" void LLVMInitializeMipsAsmParser() { RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 6b57dff2c8..d026471d0f 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -21,23 +21,13 @@ using namespace llvm; -static cl::opt<bool> PrintHackDirectives("print-hack-directives", - cl::init(false), cl::Hidden); - // Pin vtable to this file. void MipsTargetStreamer::anchor() {} MipsTargetAsmStreamer::MipsTargetAsmStreamer(formatted_raw_ostream &OS) : OS(OS) {} -void MipsTargetAsmStreamer::emitMipsHackELFFlags(unsigned Flags) { - if (!PrintHackDirectives) - return; - - OS << "\t.mips_hack_elf_flags 0x"; - OS.write_hex(Flags); - OS << '\n'; -} +void MipsTargetAsmStreamer::emitMipsELFFlags(unsigned Flags) { return; } void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() { OS << "\t.set\tmicromips\n"; @@ -85,7 +75,7 @@ MCELFStreamer &MipsTargetELFStreamer::getStreamer() { return static_cast<MCELFStreamer &>(*Streamer); } -void MipsTargetELFStreamer::emitMipsHackELFFlags(unsigned Flags) { +void MipsTargetELFStreamer::emitMipsELFFlags(unsigned Flags) { MCAssembler &MCA = getStreamer().getAssembler(); MCA.setELFHeaderEFlags(Flags); } diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index 2f49e74ab8..24c3b61b01 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -108,7 +108,6 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { return; } - MachineBasicBlock::const_instr_iterator I = MI; MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); @@ -634,8 +633,12 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { } -static void emitELFHeaderFlagsCG(MipsTargetStreamer &TargetStreamer, - const MipsSubtarget &Subtarget) { +void MipsAsmPrinter::processInitialEFlags() { + // Not having this check would work too, but would have us chew through + // code that it doesn't use for RawText. + if (OutStreamer.hasRawTextSupport()) + return; + // Update e_header flags unsigned EFlags = 0; @@ -643,30 +646,30 @@ static void emitELFHeaderFlagsCG(MipsTargetStreamer &TargetStreamer, // Currently we assume that -mabicalls is the default. EFlags |= ELF::EF_MIPS_CPIC; - if (Subtarget.inMips16Mode()) + if (Subtarget->inMips16Mode()) EFlags |= ELF::EF_MIPS_ARCH_ASE_M16; else EFlags |= ELF::EF_MIPS_NOREORDER; // Architecture - if (Subtarget.hasMips64r2()) + if (Subtarget->hasMips64r2()) EFlags |= ELF::EF_MIPS_ARCH_64R2; - else if (Subtarget.hasMips64()) + else if (Subtarget->hasMips64()) EFlags |= ELF::EF_MIPS_ARCH_64; - else if (Subtarget.hasMips32r2()) + else if (Subtarget->hasMips32r2()) EFlags |= ELF::EF_MIPS_ARCH_32R2; else EFlags |= ELF::EF_MIPS_ARCH_32; - if (Subtarget.inMicroMipsMode()) + if (Subtarget->inMicroMipsMode()) EFlags |= ELF::EF_MIPS_MICROMIPS; // ABI - if (Subtarget.isABI_O32()) + if (Subtarget->isABI_O32()) EFlags |= ELF::EF_MIPS_ABI_O32; // Relocation Model - Reloc::Model RM = Subtarget.getRelocationModel(); + Reloc::Model RM = Subtarget->getRelocationModel(); if (RM == Reloc::PIC_ || RM == Reloc::Default) EFlags |= ELF::EF_MIPS_PIC; else if (RM == Reloc::Static) @@ -674,14 +677,13 @@ static void emitELFHeaderFlagsCG(MipsTargetStreamer &TargetStreamer, else llvm_unreachable("Unsupported relocation model for e_flags"); - TargetStreamer.emitMipsHackELFFlags(EFlags); + getTargetStreamer().emitMipsELFFlags(EFlags); } void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) { // Emit Mips ELF register info Subtarget->getMReginfo().emitMipsReginfoSectionCG( OutStreamer, getObjFileLowering(), *Subtarget); - emitELFHeaderFlagsCG(getTargetStreamer(), *Subtarget); } void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, diff --git a/lib/Target/Mips/MipsAsmPrinter.h b/lib/Target/Mips/MipsAsmPrinter.h index b3060ad930..9f07914396 100644 --- a/lib/Target/Mips/MipsAsmPrinter.h +++ b/lib/Target/Mips/MipsAsmPrinter.h @@ -50,6 +50,10 @@ private: /// pool entries so we can properly mark them as data regions. bool InConstantPool; + // If object output, set initial eflags. + // This includes both default and commandline flags that affect the output + // ELF header flags. + void processInitialEFlags(); public: @@ -61,6 +65,7 @@ public: : AsmPrinter(TM, Streamer), MCP(0), InConstantPool(false), MCInstLowering(*this) { Subtarget = &TM.getSubtarget<MipsSubtarget>(); + processInitialEFlags(); } virtual const char *getPassName() const { @@ -103,6 +108,7 @@ public: void EmitStartOfAsmFile(Module &M); void EmitEndOfAsmFile(Module &M); void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); + }; } diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h index d6d0bf1a8e..16591686fd 100644 --- a/lib/Target/Mips/MipsTargetStreamer.h +++ b/lib/Target/Mips/MipsTargetStreamer.h @@ -18,7 +18,7 @@ class MipsTargetStreamer : public MCTargetStreamer { virtual void anchor(); public: - virtual void emitMipsHackELFFlags(unsigned Flags) = 0; + virtual void emitMipsELFFlags(unsigned Flags) = 0; virtual void emitDirectiveSetMicroMips() = 0; virtual void emitDirectiveSetNoMicroMips() = 0; virtual void emitDirectiveSetMips16() = 0; @@ -34,7 +34,7 @@ class MipsTargetAsmStreamer : public MipsTargetStreamer { public: MipsTargetAsmStreamer(formatted_raw_ostream &OS); - virtual void emitMipsHackELFFlags(unsigned Flags); + virtual void emitMipsELFFlags(unsigned Flags); virtual void emitDirectiveSetMicroMips(); virtual void emitDirectiveSetNoMicroMips(); virtual void emitDirectiveSetMips16(); @@ -56,7 +56,7 @@ public: virtual void emitLabel(MCSymbol *Symbol) LLVM_OVERRIDE; // FIXME: emitMipsHackELFFlags() will be removed from this class. - virtual void emitMipsHackELFFlags(unsigned Flags); + virtual void emitMipsELFFlags(unsigned Flags); virtual void emitDirectiveSetMicroMips(); virtual void emitDirectiveSetNoMicroMips(); virtual void emitDirectiveSetMips16(); diff --git a/test/MC/Mips/elf_eflags.ll b/test/MC/Mips/elf_eflags.ll index 8216a90aa3..c7cb590a31 100644 --- a/test/MC/Mips/elf_eflags.ll +++ b/test/MC/Mips/elf_eflags.ll @@ -1,6 +1,5 @@ -; This tests ELF EFLAGS setting with direct object. -; When the assembler is ready a .s file for it will -; be created. +; This tests for directives that will result in +; ELF EFLAGS setting with direct object. ; Non-shared (static) is the absence of pic and or cpic. @@ -16,52 +15,105 @@ ; Note that EF_MIPS_CPIC is set by -mabicalls which is the default on Linux ; TODO need to support -mno-abicalls -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 -relocation-model=static %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE32 %s -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32_PIC %s -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -relocation-model=static %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE32R2 %s -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32R2_PIC %s -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips -relocation-model=static -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS %s -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS_PIC %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 \ +; RUN: -relocation-model=static %s -o - | \ +; RUN: FileCheck -check-prefix=CHECK-BE32 %s +; +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 %s -o - | \ +; RUN: FileCheck -check-prefix=CHECK-BE32_PIC %s +; +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 \ +; RUN: -relocation-model=static %s -o - | \ +; RUN: FileCheck -check-prefix=CHECK-BE32R2 %s +; +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 %s -o - | \ +; RUN: FileCheck -check-prefix=CHECK-BE32R2_PIC %s +; +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 \ +; RUN: -mattr=+micromips -relocation-model=static %s -o - | \ +; RUN: FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS %s +; +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 \ +; RUN: -mattr=+micromips %s -o - | \ +; RUN: FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS_PIC %s -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 -relocation-model=static %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE64 %s -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE64_PIC %s -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 -relocation-model=static -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE64R2 %s -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE64R2_PIC %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 \ +; RUN: -relocation-model=static %s -o - | \ +; RUN: FileCheck -check-prefix=CHECK-BE64 %s +; +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 %s -o - | \ +; RUN: FileCheck -check-prefix=CHECK-BE64_PIC %s +; +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 \ +; RUN: -relocation-model=static %s -o - | \ +; RUN: FileCheck -check-prefix=CHECK-BE64R2 %s +; +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 %s -o - | \ +; RUN: FileCheck -check-prefix=CHECK-BE64R2_PIC %s -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+mips16 -relocation-model=pic -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-LE32R2-MIPS16 %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 \ +; RUN: -mattr=+mips16 -relocation-model=pic %s -o - | \ +; RUN: FileCheck -check-prefix=CHECK-LE32R2-MIPS16 %s ; 32(R1) bit with NO_REORDER and static -; CHECK-BE32: .mips_hack_elf_flags 0x50001005 +; CHECK-BE32: .abicalls +; CHECK-BE32: .option pic0 +; CHECK-BE32: .set noreorder +; TODO: Need .set mips32 ; ; 32(R1) bit with NO_REORDER and PIC -; CHECK-BE32_PIC: .mips_hack_elf_flags 0x50001007 +; CHECK-BE32_PIC: .abicalls +; CHECK-BE32_PIC: .set noreorder +; TODO: Need .set mips32 and check absence of .option pic0 ; ; 32R2 bit with NO_REORDER and static -; CHECK-BE32R2: .mips_hack_elf_flags 0x70001005 +; CHECK-BE32R2: .abicalls +; CHECK-BE32R2: .option pic0 +; CHECK-BE32R2: .set noreorder +; TODO: Need .set mips32r2 ; ; 32R2 bit with NO_REORDER and PIC -; CHECK-BE32R2_PIC: .mips_hack_elf_flags 0x70001007 +; CHECK-BE32R2_PIC:.abicalls +; CHECK-BE32R2_PIC:.set noreorder +; TODO: Need .set mips32r2 and check absence of .option pic0 ; ; 32R2 bit MICROMIPS with NO_REORDER and static -; CHECK-BE32R2-MICROMIPS: .mips_hack_elf_flags 0x72001005 +; CHECK-BE32R2-MICROMIPS: .abicalls +; CHECK-BE32R2-MICROMIPS: .option pic0 +; CHECK-BE32R2-MICROMIPS: .set micromips +; CHECK-BE32R2-MICROMIPS: .set noreorder +; TODO: Need .set mips32r2 ; ; 32R2 bit MICROMIPS with NO_REORDER and PIC -; CHECK-BE32R2-MICROMIPS_PIC: .mips_hack_elf_flags 0x72001007 +; CHECK-BE32R2-MICROMIPS_PIC: .abicalls +; CHECK-BE32R2-MICROMIPS_PIC: .set micromips +; CHECK-BE32R2-MICROMIPS_PIC: .set noreorder +; TODO: Need .set mips32r2 and check absence of .option pic0 ; ; 64(R1) bit with NO_REORDER and static -; CHECK-BE64: .mips_hack_elf_flags 0x60000005 +; CHECK-BE64: .abicalls +; CHECK-BE64: .set noreorder +; TODO: Need .set mips64 and .option pic0 ; ; 64(R1) bit with NO_REORDER and PIC -; CHECK-BE64_PIC: .mips_hack_elf_flags 0x60000007 +; CHECK-BE64_PIC: .abicalls +; CHECK-BE64_PIC: .set noreorder +; TODO: Need .set mips64 and check absence of .option pic0 ; ; 64R2 bit with NO_REORDER and static -; CHECK-BE64R2: .mips_hack_elf_flags 0x80000005 +; CHECK-BE64R2: .abicalls +; CHECK-BE64R2: .set noreorder +; TODO: Need .set mips64r2 and .option pic0 ; ; 64R2 bit with NO_REORDER and PIC -; CHECK-BE64R2_PIC: .mips_hack_elf_flags 0x80000007 +; CHECK-BE64R2_PIC: .abicalls +; CHECK-BE64R2_PIC: .set noreorder +; TODO: Need .set mips64r2 and check absence of .option pic0 ; ; 32R2 bit MIPS16 with PIC -; CHECK-LE32R2-MIPS16: .mips_hack_elf_flags 0x74001006 +; CHECK-LE32R2-MIPS16: .abicalls +; CHECK-LE32R2-MIPS16: .set mips16 +; TODO: Need .set mips32r2 and check absence of .option pic0 and noreorder define i32 @main() nounwind { entry: diff --git a/test/MC/Mips/elf_eflags.s b/test/MC/Mips/elf_eflags.s index f459689bb9..c2849a5efc 100644 --- a/test/MC/Mips/elf_eflags.s +++ b/test/MC/Mips/elf_eflags.s @@ -1,15 +1,21 @@ -// RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux %s -o -| llvm-readobj -h | FileCheck %s -// The initial value will be set at 0x50001003 and -// we will override that with the negation of 0x2 (option pic0 -// the addition of 0x4 (.abicalls) +// RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux %s -o - | \ +// RUN: llvm-readobj -h | FileCheck %s - .mips_hack_elf_flags 0x50001003 +// From the commandline and defaults the following should be set: +// EF_MIPS_ARCH_32 (0x50000000) +// EF_MIPS_ABI_O32 (0x00001000) +// EF_MIPS_NOREORDER (0x00000001) +// EF_MIPS_PIC (0x00000002) + +// Inline directives should set or unset the following: +// EF_MIPS_CPIC (0x00000004) : .abicalls +// EF_MIPS_ARCH_ASE_M16 (0x04000000) : .set mips16 +// The negation of EF_MIPS_PIC : .option pic0 // CHECK: Flags [ (0x54001005) .abicalls .option pic0 - - // Set EF_MIPS_ARCH_ASE_M16 (0x04000000) + .set mips16 diff --git a/test/MC/Mips/elf_st_other.ll b/test/MC/Mips/elf_st_other.ll index 68cad48ffd..47828fe4b4 100644 --- a/test/MC/Mips/elf_st_other.ll +++ b/test/MC/Mips/elf_st_other.ll @@ -1,12 +1,13 @@ ; This tests value of ELF st_other field for function symbol table entries. ; For microMIPS value should be equal to STO_MIPS_MICROMIPS. -; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips -print-hack-directives %s -o - | FileCheck %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips %s \ +; RUN: -o - | FileCheck %s define i32 @main() nounwind { entry: ret i32 0 } -; CHECK: .set micromips +; CHECK: .set micromips ; CHECK: main: |