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,19 @@ /*MatchingInlineAsm=*/false); } +/// parseDirectiveVariantCC +/// ::= .variant_cc symbol +bool RISCVAsmParser::parseDirectiveVariantCC() { + StringRef Name; + if (getParser().parseIdentifier(Name)) + return TokError("expected symbol name"); + if (parseEOL()) + return false; + getTargetStreamer().emitDirectiveVariantCC( + *getContext().getOrCreateSymbol(Name)); + 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,11 @@ Contents.clear(); } +void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) { + getStreamer().getAssembler().registerSymbol(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,42 @@ +// RUN: llvm-mc -triple riscv64 -filetype obj -o - %s | llvm-readobj --symbols - | FileCheck %s +// RUN: llvm-mc -triple riscv64 -filetype obj -defsym=OBJ=1 -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 +.variant_cc local +local: + +// CHECK: Name: local +// CHECK: Other [ (0x80) + +.ifdef OBJ +/// Binding directive before .variant_cc. +.global def1 +.variant_cc def1 +def1: + +/// Binding directive after .variant_cc. +.variant_cc def2 +.weak def2 +def2: + +.globl alias_def1 +.set alias_def1, def1 + +.variant_cc undef + +// OBJ: NOTYPE LOCAL DEFAULT [VARIANT_CC] [[#]] local +// OBJ-NEXT: NOTYPE GLOBAL DEFAULT [VARIANT_CC] [[#]] def1 +// OBJ-NEXT: NOTYPE WEAK DEFAULT [VARIANT_CC] [[#]] def2 +// OBJ-NEXT: NOTYPE GLOBAL DEFAULT [[#]] alias_def1 +// OBJ-NEXT: NOTYPE GLOBAL DEFAULT [VARIANT_CC] UND undef +.endif + +.ifdef ERR +.variant_cc +// ERR: [[#@LINE-1]]:12: error: expected symbol name + +.global fox +.variant_cc fox bar +// ERR: [[#@LINE-1]]:17: error: expected newline +.endif