Index: lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -26,6 +26,10 @@ using namespace llvm; +// Include the auto-generated portion of the compress emitter. +#define GEN_COMPRESS_INSTR +#include "RISCVGenCompressEmitter.inc" + namespace { struct RISCVOperand; @@ -580,10 +584,14 @@ switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { default: break; - case Match_Success: + case Match_Success: { + MCInst CInst; + bool Res = compressInst(CInst, Inst, getSTI(), Out.getContext()); + CInst.setLoc(IDLoc); Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst, getSTI()); + Out.EmitInstruction((Res ? CInst : Inst), getSTI()); return false; + } case Match_MissingFeature: return Error(IDLoc, "instruction use requires an option to be enabled"); case Match_MnemonicFail: Index: lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp =================================================================== --- lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp +++ lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp @@ -30,6 +30,10 @@ #define PRINT_ALIAS_INSTR #include "RISCVGenAsmWriter.inc" +// Include the auto-generated portion of the compress emitter. +#define GEN_UNCOMPRESS_INSTR +#include "RISCVGenCompressEmitter.inc" + static cl::opt NoAliases("riscv-no-aliases", cl::desc("Disable the emission of assembler pseudo instructions"), @@ -38,8 +42,13 @@ void RISCVInstPrinter::printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) { - if (NoAliases || !printAliasInstr(MI, STI, O)) - printInstruction(MI, STI, O); + bool Res = false; + MCInst NewMI; + if (!NoAliases) + Res = uncompressInst(NewMI, *MI, MRI, STI); + if (NoAliases || + !printAliasInstr((Res ? (const MCInst *)&NewMI : MI), STI, O)) + printInstruction((Res ? (const MCInst *)&NewMI : MI), STI, O); printAnnotation(O, Annot); } Index: lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h +++ lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h @@ -15,10 +15,33 @@ namespace llvm { +class RISCVELFStreamer; + class RISCVTargetELFStreamer : public RISCVTargetStreamer { public: - MCELFStreamer &getStreamer(); + RISCVELFStreamer &getStreamer(); RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); }; + +class RISCVELFStreamer : public MCELFStreamer { +public: + friend class RISCVTargetELFStreamer; + + RISCVELFStreamer(MCContext &Context, std::unique_ptr TAB, + raw_pwrite_stream &OS, + std::unique_ptr Emitter) + : MCELFStreamer(Context, std::move(TAB), OS, std::move(Emitter)) {} + + /// This function is used to emit instruction data into the ELF + /// streamer. We override it to do instruction compression. + void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, + bool) override; +}; + +MCELFStreamer *createRISCVELFStreamer(MCContext &Context, + std::unique_ptr TAB, + raw_pwrite_stream &OS, + std::unique_ptr Emitter, + bool RelaxAll); } #endif Index: lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -14,10 +14,18 @@ #include "RISCVMCTargetDesc.h" #include "RISCVELFStreamer.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" using namespace llvm; +// Include the auto-generated portion of the compress emitter. +#define GEN_COMPRESS_INSTR +#include "RISCVGenCompressEmitter.inc" + // This part is for ELF object output. RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI) @@ -34,6 +42,25 @@ MCA.setELFHeaderEFlags(EFlags); } -MCELFStreamer &RISCVTargetELFStreamer::getStreamer() { - return static_cast(Streamer); +RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() { + return static_cast(Streamer); +} + +void RISCVELFStreamer::EmitInstruction(const MCInst &Inst, + const MCSubtargetInfo &STI, bool) { + MCInst CInst; + bool Res = compressInst(CInst, Inst, STI, getContext()); + MCELFStreamer::EmitInstruction((Res ? CInst : Inst), STI); +} + +namespace llvm { +MCELFStreamer *createRISCVELFStreamer(MCContext &Context, + std::unique_ptr TAB, + raw_pwrite_stream &OS, + std::unique_ptr Emitter, + bool RelaxAll) { + RISCVELFStreamer *S = + new RISCVELFStreamer(Context, std::move(TAB), OS, std::move(Emitter)); + return S; } +} // end namespace llvm Index: lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp @@ -17,7 +17,9 @@ #include "RISCVELFStreamer.h" #include "RISCVTargetStreamer.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" @@ -77,6 +79,15 @@ return new RISCVTargetStreamer(S); } +static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx, + std::unique_ptr &&TAB, + raw_pwrite_stream &OS, + std::unique_ptr &&Emitter, + bool RelaxAll) { + return createRISCVELFStreamer(Ctx, std::move(TAB), OS, std::move(Emitter), + RelaxAll); +} + extern "C" void LLVMInitializeRISCVTargetMC() { for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target()}) { TargetRegistry::RegisterMCAsmInfo(*T, createRISCVMCAsmInfo); @@ -86,6 +97,7 @@ TargetRegistry::RegisterMCCodeEmitter(*T, createRISCVMCCodeEmitter); TargetRegistry::RegisterMCInstPrinter(*T, createRISCVMCInstPrinter); TargetRegistry::RegisterMCSubtargetInfo(*T, createRISCVMCSubtargetInfo); + TargetRegistry::RegisterELFStreamer(*T, createELFStreamer); TargetRegistry::RegisterObjectTargetStreamer( *T, createRISCVObjectTargetStreamer); }