Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -160,6 +160,7 @@ const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); bool isEvaluated(const MCExpr *Expr); + bool parseSetArchDirective(); bool parseSetFeature(uint64_t Feature); bool parseDirectiveCPLoad(SMLoc Loc); bool parseDirectiveCPSetup(); @@ -336,6 +337,27 @@ bool hasMips64r6() const { return (STI.getFeatureBits() & Mips::FeatureMips64r6); } + + bool isSupportedArch(StringRef Arch) { + bool Result; + Result = StringSwitch(Arch) + .Case("mips1", 1) + .Case("mips2", 1) + .Case("mips3", 1) + .Case("mips4", 1) + .Case("mips5", 1) + .Case("mips32", 1) + .Case("mips32r2", 1) + .Case("mips32r6", 1) + .Case("mips64", 1) + .Case("mips64r2", 1) + .Case("mips64r6", 1) + .Case("cnmips", 1) + .Case("r4000", 1) // This is an implementation of Mips3! + .Default(0); + return Result; + } + bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); } bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); } bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); } @@ -2581,6 +2603,28 @@ return false; } +bool MipsAsmParser::parseSetArchDirective() { + Parser.Lex(); + if (getLexer().isNot(AsmToken::Equal)) + return reportParseError("unexpected token in .set arch directive"); + + Parser.Lex(); + StringRef Arch; + if (Parser.parseIdentifier(Arch)) + return reportParseError("expected arch identifier"); + + if (!isSupportedArch(Arch)) + return reportParseError("unsupported architecture"); + + // FIXME: Improve this. + if (Arch == "r4000") + Arch = "mips3"; + + selectArch(Arch); + getTargetStreamer().emitDirectiveSetArch(Arch); + return false; +} + bool MipsAsmParser::parseSetFeature(uint64_t Feature) { Parser.Lex(); if (getLexer().isNot(AsmToken::EndOfStatement)) @@ -2770,6 +2814,8 @@ return parseSetNoAtDirective(); } else if (Tok.getString() == "at") { return parseSetAtDirective(); + } else if (Tok.getString() == "arch") { + return parseSetArchDirective(); } else if (Tok.getString() == "fp") { return parseSetFpDirective(); } else if (Tok.getString() == "reorder") { Index: lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -56,6 +56,9 @@ void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {} void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) { } +void MipsTargetStreamer::emitDirectiveSetArch(StringRef Arch) { + setCanHaveModuleDir(false); +} void MipsTargetStreamer::emitDirectiveSetMips1() {} void MipsTargetStreamer::emitDirectiveSetMips2() {} void MipsTargetStreamer::emitDirectiveSetMips3() {} @@ -174,6 +177,11 @@ << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n'; } +void MipsTargetAsmStreamer::emitDirectiveSetArch(StringRef Arch) { + OS << "\t.set arch=" << Arch << "\n"; + MipsTargetStreamer::emitDirectiveSetArch(Arch); +} + void MipsTargetAsmStreamer::emitDirectiveSetMips1() { OS << "\t.set\tmips1\n"; setCanHaveModuleDir(false); Index: lib/Target/Mips/MipsTargetStreamer.h =================================================================== --- lib/Target/Mips/MipsTargetStreamer.h +++ lib/Target/Mips/MipsTargetStreamer.h @@ -48,6 +48,7 @@ virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff); virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff); + virtual void emitDirectiveSetArch(StringRef Arch); virtual void emitDirectiveSetMips1(); virtual void emitDirectiveSetMips2(); virtual void emitDirectiveSetMips3(); @@ -147,6 +148,7 @@ void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) override; void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override; + void emitDirectiveSetArch(StringRef Arch) override; void emitDirectiveSetMips1() override; void emitDirectiveSetMips2() override; void emitDirectiveSetMips3() override; Index: test/MC/Mips/set-arch.s =================================================================== --- /dev/null +++ test/MC/Mips/set-arch.s @@ -0,0 +1,31 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding -mcpu=mips32 | \ +# RUN: FileCheck %s +# Note that r4000 is an implementation of mips3. +.text + .set arch=mips1 + .set arch=mips2 + .set arch=mips3 + .set arch=mips4 + .set arch=mips5 + .set arch=mips32 + .set arch=mips32r2 + .set arch=mips32r6 + .set arch=mips64 + .set arch=mips64r2 + .set arch=mips64r6 + .set arch=cnmips + .set arch=r4000 + +# CHECK: .set arch=mips1 +# CHECK: .set arch=mips2 +# CHECK: .set arch=mips3 +# CHECK: .set arch=mips4 +# CHECK: .set arch=mips5 +# CHECK: .set arch=mips32 +# CHECK: .set arch=mips32r2 +# CHECK: .set arch=mips32r6 +# CHECK: .set arch=mips64 +# CHECK: .set arch=mips64r2 +# CHECK: .set arch=mips64r6 +# CHECK: .set arch=cnmips +# CHECK: .set arch=mips3 \ No newline at end of file