diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 71121fce35d4..2c51a592eeeb 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1900,6 +1900,11 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, return true; } + // We know we emitted an instruction on the MER_NotAMacro or MER_Success path. + // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS. + if (inMicroMipsMode()) + TOut.setUsesMicroMips(); + // If this instruction has a delay slot and .set reorder is active, // emit a NOP after it. if (FillDelaySlot) { @@ -5288,6 +5293,7 @@ bool MipsAsmParser::parseSetFeature(uint64_t Feature) { getTargetStreamer().emitDirectiveSetDsp(); break; case Mips::FeatureMicroMips: + setFeatureBits(Mips::FeatureMicroMips, "micromips"); getTargetStreamer().emitDirectiveSetMicroMips(); break; case Mips::FeatureMips1: @@ -5586,6 +5592,7 @@ bool MipsAsmParser::parseDirectiveSet() { } else if (Tok.getString() == "nomips16") { return parseSetNoMips16Directive(); } else if (Tok.getString() == "nomicromips") { + clearFeatureBits(Mips::FeatureMicroMips, "micromips"); getTargetStreamer().emitDirectiveSetNoMicroMips(); Parser.eatToEndOfStatement(); return false; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index c6bb84d3b02e..b24d7ae596f1 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -40,6 +40,7 @@ MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) } void MipsTargetStreamer::emitDirectiveSetMicroMips() {} void MipsTargetStreamer::emitDirectiveSetNoMicroMips() {} +void MipsTargetStreamer::setUsesMicroMips() {} void MipsTargetStreamer::emitDirectiveSetMips16() {} void MipsTargetStreamer::emitDirectiveSetNoMips16() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetReorder() { forbidModuleDirective(); } @@ -830,11 +831,6 @@ MCELFStreamer &MipsTargetELFStreamer::getStreamer() { void MipsTargetELFStreamer::emitDirectiveSetMicroMips() { MicroMipsEnabled = true; - - MCAssembler &MCA = getStreamer().getAssembler(); - unsigned Flags = MCA.getELFHeaderEFlags(); - Flags |= ELF::EF_MIPS_MICROMIPS; - MCA.setELFHeaderEFlags(Flags); forbidModuleDirective(); } @@ -843,6 +839,13 @@ void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() { forbidModuleDirective(); } +void MipsTargetELFStreamer::setUsesMicroMips() { + MCAssembler &MCA = getStreamer().getAssembler(); + unsigned Flags = MCA.getELFHeaderEFlags(); + Flags |= ELF::EF_MIPS_MICROMIPS; + MCA.setELFHeaderEFlags(Flags); +} + void MipsTargetELFStreamer::emitDirectiveSetMips16() { MCAssembler &MCA = getStreamer().getAssembler(); unsigned Flags = MCA.getELFHeaderEFlags(); diff --git a/llvm/lib/Target/Mips/MipsTargetStreamer.h b/llvm/lib/Target/Mips/MipsTargetStreamer.h index d418f80916ba..01eee489c702 100644 --- a/llvm/lib/Target/Mips/MipsTargetStreamer.h +++ b/llvm/lib/Target/Mips/MipsTargetStreamer.h @@ -30,6 +30,7 @@ public: virtual void emitDirectiveSetMicroMips(); virtual void emitDirectiveSetNoMicroMips(); + virtual void setUsesMicroMips(); virtual void emitDirectiveSetMips16(); virtual void emitDirectiveSetNoMips16(); @@ -290,6 +291,7 @@ public: void emitDirectiveSetMicroMips() override; void emitDirectiveSetNoMicroMips() override; + void setUsesMicroMips() override; void emitDirectiveSetMips16() override; void emitDirectiveSetNoReorder() override; diff --git a/llvm/test/MC/Mips/elf_eflags_micromips.s b/llvm/test/MC/Mips/elf_eflags_micromips.s index 9b7de12d6e79..623f5a732911 100644 --- a/llvm/test/MC/Mips/elf_eflags_micromips.s +++ b/llvm/test/MC/Mips/elf_eflags_micromips.s @@ -1,7 +1,12 @@ -# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32 %s -o -| llvm-readobj -h | FileCheck %s +# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32 \ +# RUN: -mattr=+micromips < /dev/null -o -| llvm-readobj -h | FileCheck \ +# RUN: -check-prefix=NO-MM %s +# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32 %s -o - \ +# RUN: | llvm-readobj -h | FileCheck %s # This *MUST* match the output of 'gcc -c' compiled with the same triple. # CHECK: Flags [ (0x52001004) +# NO-MM: Flags [ (0x50001004) .set micromips f: diff --git a/llvm/test/MC/Mips/elf_eflags_micromips2.s b/llvm/test/MC/Mips/elf_eflags_micromips2.s new file mode 100644 index 000000000000..d44cf7f37a72 --- /dev/null +++ b/llvm/test/MC/Mips/elf_eflags_micromips2.s @@ -0,0 +1,11 @@ +# RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux -mcpu=mips32 %s -o - \ +# RUN: | llvm-readobj -h | FileCheck %s + +# This *MUST* match the output of 'gcc -c' compiled with the same triple. +# The microMIPS flag is not set if no microMIPS code was emitted. +# CHECK: Flags [ (0x50001004) + + nop + .set micromips + .set nomicromips + nop