diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -36,6 +36,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/RISCVISAInfo.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h" @@ -46,6 +47,10 @@ STATISTIC(RISCVNumInstrsCompressed, "Number of RISC-V Compressed instructions emitted"); +namespace llvm { +extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]; +} // namespace llvm + namespace { class RISCVAsmPrinter : public AsmPrinter { const RISCVSubtarget *STI; @@ -83,6 +88,8 @@ void emitEndOfAsmFile(Module &M) override; void emitFunctionEntryLabel() override; + void emitDirectiveOptionArch(); + bool isSameAttribute(); private: void emitAttributes(); @@ -238,11 +245,43 @@ return false; } +void RISCVAsmPrinter::emitDirectiveOptionArch() { + RISCVTargetStreamer &RTS = + static_cast(*OutStreamer->getTargetStreamer()); + SmallVector NeedEmitStdOptionArgs; + const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo(); + for (const auto &Feature : RISCVFeatureKV) { + if (!llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key)) + continue; + if (STI->hasFeature(Feature.Value) && !MCSTI.hasFeature(Feature.Value)) + NeedEmitStdOptionArgs.emplace_back(RISCVOptionArchArgType::Plus, + Feature.Key); + if (!STI->hasFeature(Feature.Value) && MCSTI.hasFeature(Feature.Value)) + NeedEmitStdOptionArgs.emplace_back(RISCVOptionArchArgType::Minus, + Feature.Key); + } + RTS.emitDirectiveOptionArch(NeedEmitStdOptionArgs); +} + +bool RISCVAsmPrinter::isSameAttribute() { + const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo(); + return MCSTI.getFeatureBits() == STI->getFeatureBits(); +} + bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) { STI = &MF.getSubtarget(); + RISCVTargetStreamer &RTS = + static_cast(*OutStreamer->getTargetStreamer()); + if (!isSameAttribute()) { + RTS.emitDirectiveOptionPush(); + emitDirectiveOptionArch(); + } SetupMachineFunction(MF); emitFunctionBody(); + + if (!isSameAttribute()) + RTS.emitDirectiveOptionPop(); return false; }