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 @@ -180,6 +180,7 @@ bool parseDirectiveOption(); bool parseDirectiveAttribute(); bool parseDirectiveInsn(SMLoc L); + bool parseDirectiveVariantCC(); void setFeatureBits(uint64_t Feature, StringRef FeatureString) { if (!(getSTI().getFeatureBits()[Feature])) { @@ -2035,6 +2036,8 @@ return parseDirectiveAttribute(); if (IDVal == ".insn") return parseDirectiveInsn(DirectiveID.getLoc()); + if (IDVal == ".variant_cc") + return parseDirectiveVariantCC(); return true; } @@ -2297,6 +2300,28 @@ /*MatchingInlineAsm=*/false); } +/// parseDirectiveVariantCC +/// ::= .variant_cc symbol +bool RISCVAsmParser::parseDirectiveVariantCC() { + MCAsmParser &Parser = getParser(); + const AsmToken &Tok = Parser.getTok(); + if (Tok.isNot(AsmToken::Identifier)) + return TokError("expected symbol name"); + + StringRef SymbolName = Tok.getIdentifier(); + MCSymbol *Sym = getContext().lookupSymbol(SymbolName); + if (!Sym) + return TokError("unknown symbol"); + + Parser.Lex(); + if (Parser.parseEOL()) + return false; + + getTargetStreamer().emitDirectiveVariantCC(*Sym); + + return false; +} + void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { MCInst CInst; bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h @@ -106,6 +106,7 @@ void emitDirectiveOptionNoRVC() override; void emitDirectiveOptionRelax() override; void emitDirectiveOptionNoRelax() override; + void emitDirectiveVariantCC(MCSymbol &Symbol) override; void finish() override; }; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -187,6 +187,10 @@ Contents.clear(); } +void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) { + cast(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC); +} + namespace { class RISCVELFStreamer : public MCELFStreamer { static std::pair getRelocPairForSize(unsigned Size) { 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 @@ -33,6 +33,7 @@ virtual void emitDirectiveOptionNoRVC(); virtual void emitDirectiveOptionRelax(); virtual void emitDirectiveOptionNoRelax(); + virtual void emitDirectiveVariantCC(MCSymbol &Symbol); virtual void emitAttribute(unsigned Attribute, unsigned Value); virtual void finishAttributeSection(); virtual void emitTextAttribute(unsigned Attribute, StringRef String); 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 @@ -32,6 +32,7 @@ void RISCVTargetStreamer::emitDirectiveOptionNoRVC() {} void RISCVTargetStreamer::emitDirectiveOptionRelax() {} void RISCVTargetStreamer::emitDirectiveOptionNoRelax() {} +void RISCVTargetStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {} void RISCVTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {} void RISCVTargetStreamer::finishAttributeSection() {} void RISCVTargetStreamer::emitTextAttribute(unsigned Attribute, diff --git a/llvm/test/MC/RISCV/directive-variant_cc.s b/llvm/test/MC/RISCV/directive-variant_cc.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/directive-variant_cc.s @@ -0,0 +1,30 @@ +// RUN: llvm-mc -triple riscv64 -filetype obj -o - %s | llvm-readobj --symbols - | FileCheck %s +// RUN: llvm-mc -triple riscv64 -filetype obj -o - %s | llvm-readelf -s - | FileCheck %s --check-prefix=OBJ +// RUN: not llvm-mc -triple riscv64 -filetype asm -defsym=ERR=1 -o - %s 2>&1 | FileCheck %s --check-prefix=ERR + +.text +.global foo +.variant_cc foo + +// CHECK: Name: foo +// CHECK: Other [ (0x80) + +// OBJ: NOTYPE GLOBAL DEFAULT [VARIANT_CC] UND foo + +.ifdef ERR +.variant_cc +// ERR:[[#@LINE-1]]:12: error: expected symbol name +// ERR-NEXT: .variant_cc +// ERR-NEXT: ^ + +.variant_cc bar +// ERR: [[#@LINE-1]]:13: error: unknown symbol +// ERR-NEXT: .variant_cc bar +// ERR-NEXT: ^ + +.global fox +.variant_cc fox bar +// ERR: [[#@LINE-1]]:17: error: expected newline +// ERR-NEXT: .variant_cc fox bar +// ERR-NEXT: ^ +.endif