diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -2711,28 +2711,21 @@ } if (Option == "arch") { - bool PrefixEmitted = false; - bool IsExtensionList = false; + SmallVector Args; do { if (Parser.parseComma()) return true; - bool IsAdd, IsFull; - if (parseOptionalToken(AsmToken::Plus)) { - IsAdd = true; - IsFull = false; - IsExtensionList = true; - } else if (parseOptionalToken(AsmToken::Minus)) { - IsAdd = false; - IsFull = false; - IsExtensionList = true; - } else { - if (IsExtensionList) - return Error(Parser.getTok().getLoc(), - "unexpected token, expected + or -"); - - IsFull = true; - } + RISCVOptionArchArgType Type; + if (parseOptionalToken(AsmToken::Plus)) + Type = RISCVOptionArchArgType::Plus; + else if (parseOptionalToken(AsmToken::Minus)) + Type = RISCVOptionArchArgType::Minus; + else if (!Args.empty()) + return Error(Parser.getTok().getLoc(), + "unexpected token, expected + or -"); + else + Type = RISCVOptionArchArgType::Full; if (Parser.getTok().isNot(AsmToken::Identifier)) return Error(Parser.getTok().getLoc(), @@ -2742,14 +2735,12 @@ SMLoc Loc = Parser.getTok().getLoc(); Parser.Lex(); - if (IsFull) { + if (Type == RISCVOptionArchArgType::Full) { std::string Result; if (resetToArch(Arch, Loc, Result, true)) return true; - getTargetStreamer().emitDirectiveOptionArchFullArch(Result, - PrefixEmitted); - + Args.emplace_back(Type, Result); break; } @@ -2764,8 +2755,9 @@ return Error(Loc, "unknown extension feature"); } - bool HasComma = getTok().is(AsmToken::Comma); - if (IsAdd) { + Args.emplace_back(Type, Ext->Key); + + if (Type == RISCVOptionArchArgType::Plus) { setFeatureBits(Ext->Value, Ext->Key); auto ParseResult = RISCVFeatures::parseFeatureBits(isRV64(), STI->getFeatureBits()); if (!ParseResult) { @@ -2777,9 +2769,8 @@ return Error(Loc, OutputErrMsg.str()); } - getTargetStreamer().emitDirectiveOptionArchPlusOrMinus( - Ext->Key, /*Enable*/ true, PrefixEmitted, HasComma); } else { + assert(Type == RISCVOptionArchArgType::Minus); // It is invalid to disable an extension that there are other enabled // extensions depend on it. // TODO: Make use of RISCVISAInfo to handle this @@ -2793,14 +2784,13 @@ } clearFeatureBits(Ext->Value, Ext->Key); - getTargetStreamer().emitDirectiveOptionArchPlusOrMinus( - Ext->Key, /*Enable*/ false, PrefixEmitted, HasComma); } } while (Parser.getTok().isNot(AsmToken::EndOfStatement)); if (Parser.parseEOL()) return true; + getTargetStreamer().emitDirectiveOptionArch(Args); return false; } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h @@ -17,6 +17,20 @@ class formatted_raw_ostream; +enum class RISCVOptionArchArgType { + Full, + Plus, + Minus, +}; + +struct RISCVOptionArchArg { + RISCVOptionArchArgType Type; + std::string Value; + + RISCVOptionArchArg(RISCVOptionArchArgType Type, std::string Value) + : Type(Type), Value(Value) {} +}; + class RISCVTargetStreamer : public MCTargetStreamer { RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown; @@ -33,12 +47,8 @@ virtual void emitDirectiveOptionNoRVC(); virtual void emitDirectiveOptionRelax(); virtual void emitDirectiveOptionNoRelax(); + virtual void emitDirectiveOptionArch(ArrayRef Args); virtual void emitDirectiveVariantCC(MCSymbol &Symbol); - virtual void emitDirectiveOptionArchFullArch(StringRef Value, - bool &PrefixEmitted); - virtual void emitDirectiveOptionArchPlusOrMinus(StringRef Value, bool Enable, - bool &PrefixEmitted, - bool EmitComma); virtual void emitAttribute(unsigned Attribute, unsigned Value); virtual void finishAttributeSection(); virtual void emitTextAttribute(unsigned Attribute, StringRef String); @@ -71,12 +81,8 @@ void emitDirectiveOptionNoRVC() override; void emitDirectiveOptionRelax() override; void emitDirectiveOptionNoRelax() override; + void emitDirectiveOptionArch(ArrayRef Args) override; void emitDirectiveVariantCC(MCSymbol &Symbol) override; - void emitDirectiveOptionArchFullArch(StringRef Value, - bool &PrefixEmitted) override; - void emitDirectiveOptionArchPlusOrMinus(StringRef Value, bool Enable, - bool &PrefixEmitted, - bool EmitComma) override; }; } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp @@ -33,12 +33,9 @@ void RISCVTargetStreamer::emitDirectiveOptionNoRVC() {} void RISCVTargetStreamer::emitDirectiveOptionRelax() {} void RISCVTargetStreamer::emitDirectiveOptionNoRelax() {} +void RISCVTargetStreamer::emitDirectiveOptionArch( + ArrayRef Args) {} void RISCVTargetStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {} -void RISCVTargetStreamer::emitDirectiveOptionArchFullArch(StringRef Value, - bool &PrefixEmitted) { -} -void RISCVTargetStreamer::emitDirectiveOptionArchPlusOrMinus( - StringRef Value, bool Enable, bool &PrefixEmitted, bool EmitComma) {} void RISCVTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {} void RISCVTargetStreamer::finishAttributeSection() {} void RISCVTargetStreamer::emitTextAttribute(unsigned Attribute, @@ -106,6 +103,26 @@ OS << "\t.option\tnorelax\n"; } +void RISCVTargetAsmStreamer::emitDirectiveOptionArch( + ArrayRef Args) { + OS << "\t.option\tarch"; + for (const auto &Arg : Args) { + OS << ", "; + switch (Arg.Type) { + case RISCVOptionArchArgType::Full: + break; + case RISCVOptionArchArgType::Plus: + OS << "+"; + break; + case RISCVOptionArchArgType::Minus: + OS << "-"; + break; + } + OS << Arg.Value; + } + OS << "\n"; +} + void RISCVTargetAsmStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) { OS << "\t.variant_cc\t" << Symbol.getName() << "\n"; } @@ -123,33 +140,4 @@ unsigned IntValue, StringRef StringValue) {} -static void emitDirectiveOptionArchPrefix(formatted_raw_ostream &OS, - bool &PrefixEmitted) { - if (!PrefixEmitted) { - OS << "\t .option\tarch,\t"; - PrefixEmitted = true; - } -} - -static void emitCommaOrNextLine(formatted_raw_ostream &OS, bool EmitComma) { - if (EmitComma) - OS << ", "; - else - OS << "\n"; -} - -void RISCVTargetAsmStreamer::emitDirectiveOptionArchFullArch( - StringRef Value, bool &PrefixEmitted) { - emitDirectiveOptionArchPrefix(OS, PrefixEmitted); - OS << Value; - emitCommaOrNextLine(OS, false); -} - -void RISCVTargetAsmStreamer::emitDirectiveOptionArchPlusOrMinus( - StringRef Value, bool Enable, bool &PrefixEmitted, bool EmitComma) { - emitDirectiveOptionArchPrefix(OS, PrefixEmitted); - OS << (Enable ? "+" : "-") << Value; - emitCommaOrNextLine(OS, EmitComma); -} - void RISCVTargetAsmStreamer::finishAttributeSection() {}