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 @@ -255,6 +255,11 @@ "target-abi)\n"; } + // Use computeTargetABI to check if ABIName is valid. If invalid, output + // error message. + RISCVABI::computeTargetABI(STI.getTargetTriple(), STI.getFeatureBits(), + ABIName); + const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo(); ParserOptions.IsPicEnabled = MOFI->isPositionIndependent(); } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -27,15 +27,12 @@ bool Is64Bit; bool ForceRelocs = false; const MCTargetOptions &TargetOptions; - RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown; public: RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit, const MCTargetOptions &Options) : MCAsmBackend(support::little), STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) { - TargetABI = RISCVABI::computeTargetABI( - STI.getTargetTriple(), STI.getFeatureBits(), Options.getABIName()); RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits()); } ~RISCVAsmBackend() override = default; @@ -103,7 +100,6 @@ const MCSubtargetInfo *STI) const override; const MCTargetOptions &getTargetOptions() const { return TargetOptions; } - RISCVABI::ABI getTargetABI() const { return TargetABI; } }; } 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 @@ -29,6 +29,7 @@ SmallVector Contents; MCSection *AttributeSection = nullptr; + const MCSubtargetInfo &STI; AttributeItem *getAttributeItem(unsigned Attribute) { for (size_t i = 0; i < Contents.size(); ++i) @@ -103,6 +104,8 @@ void emitDirectiveOptionNoRVC() override; void emitDirectiveOptionRelax() override; void emitDirectiveOptionNoRelax() override; + + void finish() override; }; MCELFStreamer *createRISCVELFStreamer(MCContext &C, 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 @@ -23,7 +23,6 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCValue.h" -#include "llvm/Support/Casting.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/RISCVAttributes.h" @@ -32,38 +31,12 @@ // This part is for ELF object output. RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI) - : RISCVTargetStreamer(S), CurrentVendor("riscv") { + : RISCVTargetStreamer(S), CurrentVendor("riscv"), STI(STI) { MCAssembler &MCA = getStreamer().getAssembler(); const FeatureBitset &Features = STI.getFeatureBits(); auto &MAB = static_cast(MCA.getBackend()); - RISCVABI::ABI ABI = MAB.getTargetABI(); - assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI"); - - unsigned EFlags = MCA.getELFHeaderEFlags(); - - if (Features[RISCV::FeatureStdExtC]) - EFlags |= ELF::EF_RISCV_RVC; - - switch (ABI) { - case RISCVABI::ABI_ILP32: - case RISCVABI::ABI_LP64: - break; - case RISCVABI::ABI_ILP32F: - case RISCVABI::ABI_LP64F: - EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE; - break; - case RISCVABI::ABI_ILP32D: - case RISCVABI::ABI_LP64D: - EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE; - break; - case RISCVABI::ABI_ILP32E: - EFlags |= ELF::EF_RISCV_RVE; - break; - case RISCVABI::ABI_Unknown: - llvm_unreachable("Improperly initialised target ABI"); - } - - MCA.setELFHeaderEFlags(EFlags); + setTargetABI(RISCVABI::computeTargetABI(STI.getTargetTriple(), Features, + MAB.getTargetOptions().getABIName())); } MCELFStreamer &RISCVTargetELFStreamer::getStreamer() { @@ -174,6 +147,39 @@ return Result; } +void RISCVTargetELFStreamer::finish() { + RISCVTargetStreamer::finish(); + MCAssembler &MCA = getStreamer().getAssembler(); + const FeatureBitset &Features = STI.getFeatureBits(); + RISCVABI::ABI ABI = getTargetABI(); + + unsigned EFlags = MCA.getELFHeaderEFlags(); + + if (Features[RISCV::FeatureStdExtC]) + EFlags |= ELF::EF_RISCV_RVC; + + switch (ABI) { + case RISCVABI::ABI_ILP32: + case RISCVABI::ABI_LP64: + break; + case RISCVABI::ABI_ILP32F: + case RISCVABI::ABI_LP64F: + EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE; + break; + case RISCVABI::ABI_ILP32D: + case RISCVABI::ABI_LP64D: + EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE; + break; + case RISCVABI::ABI_ILP32E: + EFlags |= ELF::EF_RISCV_RVE; + break; + case RISCVABI::ABI_Unknown: + llvm_unreachable("Improperly initialised target ABI"); + } + + MCA.setELFHeaderEFlags(EFlags); +} + namespace { class RISCVELFStreamer : public MCELFStreamer { static std::pair getRelocPairForSize(unsigned Size) { diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp @@ -82,7 +82,17 @@ if (CPU == "generic") report_fatal_error(Twine("CPU 'generic' is not supported. Use ") + (TT.isArch64Bit() ? "generic-rv64" : "generic-rv32")); - return createRISCVMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS); + + MCSubtargetInfo *STI = + createRISCVMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS); + + // Check if Feature string is valid + auto ISAInfo = + RISCVFeatures::parseFeatureBits(TT.isArch64Bit(), STI->getFeatureBits()); + if (!ISAInfo) + report_fatal_error(ISAInfo.takeError()); + else + return STI; } static MCInstPrinter *createRISCVMCInstPrinter(const Triple &T, 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 @@ -9,6 +9,7 @@ #ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVTARGETSTREAMER_H #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVTARGETSTREAMER_H +#include "RISCV.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -17,6 +18,8 @@ class formatted_raw_ostream; class RISCVTargetStreamer : public MCTargetStreamer { + RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown; + public: RISCVTargetStreamer(MCStreamer &S); void finish() override; @@ -36,6 +39,8 @@ StringRef StringValue); void emitTargetAttributes(const MCSubtargetInfo &STI); + void setTargetABI(RISCVABI::ABI ABI); + RISCVABI::ABI getTargetABI() const { return TargetABI; } }; // This part is for ascii assembly output 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 @@ -38,6 +38,10 @@ void RISCVTargetStreamer::emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue) {} +void RISCVTargetStreamer::setTargetABI(RISCVABI::ABI ABI) { + assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialized target ABI"); + TargetABI = ABI; +} void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) { if (STI.hasFeature(RISCV::FeatureRV32E)) 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 @@ -38,12 +38,14 @@ namespace { class RISCVAsmPrinter : public AsmPrinter { - const MCSubtargetInfo *STI; + const MCSubtargetInfo *MCSTI; + const RISCVSubtarget *STI; + RISCVABI::ABI ABI = RISCVABI::ABI_Unknown; public: explicit RISCVAsmPrinter(TargetMachine &TM, std::unique_ptr Streamer) - : AsmPrinter(TM, std::move(Streamer)), STI(TM.getMCSubtargetInfo()) {} + : AsmPrinter(TM, std::move(Streamer)), MCSTI(TM.getMCSubtargetInfo()) {} StringRef getPassName() const override { return "RISCV Assembly Printer"; } @@ -68,6 +70,8 @@ void emitStartOfAsmFile(Module &M) override; void emitEndOfAsmFile(Module &M) override; + void emitFunctionEntryLabel() override; + private: void emitAttributes(); }; @@ -170,7 +174,8 @@ MCSubtargetInfo &NewSTI = OutStreamer->getContext().getSubtargetCopy(*TM.getMCSubtargetInfo()); NewSTI.setFeatureBits(MF.getSubtarget().getFeatureBits()); - STI = &NewSTI; + MCSTI = &NewSTI; + STI = &MF.getSubtarget(); SetupMachineFunction(MF); emitFunctionBody(); @@ -193,7 +198,14 @@ void RISCVAsmPrinter::emitAttributes() { RISCVTargetStreamer &RTS = static_cast(*OutStreamer->getTargetStreamer()); - RTS.emitTargetAttributes(*STI); + RTS.emitTargetAttributes(*MCSTI); +} + +void RISCVAsmPrinter::emitFunctionEntryLabel() { + AsmPrinter::emitFunctionEntryLabel(); + RISCVTargetStreamer &RTS = + static_cast(*OutStreamer->getTargetStreamer()); + RTS.setTargetABI(STI->getTargetABI()); } // Force static initialization. diff --git a/llvm/test/CodeGen/RISCV/module-target-abi2.ll b/llvm/test/CodeGen/RISCV/module-target-abi2.ll --- a/llvm/test/CodeGen/RISCV/module-target-abi2.ll +++ b/llvm/test/CodeGen/RISCV/module-target-abi2.ll @@ -8,8 +8,7 @@ ; RV32IF-ILP32: -target-abi option != target-abi module flag -; FLAGS: Flags: 0x0 -; // this should be "Flags :0x2, single-float ABI", it will be fixed later. +; FLAGS: Flags: 0x2, single-float ABI define float @foo(i32 %a) nounwind #0 { ; DEFAULT: # %bb.0: