Index: lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -22,10 +22,17 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; +#define DEBUG_TYPE "asm-parser" + +// Include the auto-generated portion of the compress emitter. +#define GEN_COMPRESS_INSTR +#include "RISCVGenCompressEmitter.inc" + namespace { struct RISCVOperand; @@ -580,9 +587,17 @@ switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { default: break; - case Match_Success: + case Match_Success: { + MCInst NewInst; + bool Res = compressInst(NewInst, Inst,getSTI(), Out.getContext()); + if (Res) + DEBUG(dbgs() << "Compressed Inst: " << Inst << "to NewInst: " << + NewInst << '\n'); + else + DEBUG(dbgs() << "Compressed Inst:" << Inst << "failed:\n"); Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst, getSTI()); + Out.EmitInstruction((Res ? NewInst : Inst), getSTI()); + } return false; case Match_MissingFeature: return Error(IDLoc, "instruction use requires an option to be enabled"); Index: lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp =================================================================== --- lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp +++ lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp @@ -30,16 +30,27 @@ #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"), cl::init(false), cl::Hidden); + 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/CMakeLists.txt =================================================================== --- lib/Target/RISCV/MCTargetDesc/CMakeLists.txt +++ lib/Target/RISCV/MCTargetDesc/CMakeLists.txt @@ -1,8 +1,10 @@ add_llvm_library(LLVMRISCVDesc RISCVAsmBackend.cpp RISCVELFObjectWriter.cpp + RISCVELFStreamer.cpp RISCVMCAsmInfo.cpp RISCVMCCodeEmitter.cpp RISCVMCExpr.cpp RISCVMCTargetDesc.cpp + RISCVTargetStreamer.cpp ) Index: lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h =================================================================== --- /dev/null +++ lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h @@ -0,0 +1,29 @@ +//===-- RISCVELFStreamer.h - ELF Streamer for RISCV ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements ELF streamer information for the RISCV backend. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_AARCH64ELFSTREAMER_H +#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_AARCH64ELFSTREAMER_H + +#include "llvm/MC/MCELFStreamer.h" + +namespace llvm { + +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 =================================================================== --- /dev/null +++ lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -0,0 +1,140 @@ +//===- lib/MC/RISCVELFStreamer.cpp - ELF Object Output for RISCV ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file assembles .s files and emits RISCV ELF .o object files. Different +// from generic ELF streamer in emitting mapping symbols ($x and $d) to delimit +// regions of data and code. +// +//===----------------------------------------------------------------------===// + +#include "RISCVTargetStreamer.h" +#include "llvm/ADT/Triple.h" +#include "llvm/ADT/Twine.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSection.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbolELF.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/raw_ostream.h" +#include "MCTargetDesc/RISCVMCTargetDesc.h" + +using namespace llvm; + +#define DEBUG_TYPE "elf-streamer" + +// Include the auto-generated portion of the compress emitter. +#define GEN_COMPRESS_INSTR +#include "RISCVGenCompressEmitter.inc" + +using namespace llvm; + +namespace { + +class RISCVELFStreamer; + +class RISCVTargetAsmStreamer : public RISCVTargetStreamer { + formatted_raw_ostream &OS; + +public: + RISCVTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS); + + +}; + + +RISCVTargetAsmStreamer::RISCVTargetAsmStreamer(MCStreamer &S, + formatted_raw_ostream &OS) + : RISCVTargetStreamer(S), OS(OS) {} + + +class RISCVTargetELFStreamer : public RISCVTargetStreamer { +private: + RISCVELFStreamer &getStreamer(); + +public: + RISCVTargetELFStreamer(MCStreamer &S) : RISCVTargetStreamer(S) {} +}; + +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)) {} + + // Reset state between object emissions + void reset() override { + MCELFStreamer::reset(); + } + + /// This function is the one 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 { + MCInst NewInst; + bool Res = compressInst(NewInst, Inst, STI, getContext()); + if (Res) { + DEBUG(dbgs() << "Compressed Inst: " << Inst << "to NewInst: " << + NewInst << '\n'); + } + else + DEBUG(dbgs() << "Compressed Inst:" << Inst << "failed:\n"); + MCELFStreamer::EmitInstruction((Res ? NewInst : Inst), STI); + } +}; + +} // end anonymous namespace + +RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() { + return static_cast(Streamer); +} + + +namespace llvm { + +MCTargetStreamer *createRISCVAsmTargetStreamer(MCStreamer &S, + formatted_raw_ostream &OS, + MCInstPrinter *InstPrint, + bool isVerboseAsm) { + return new RISCVTargetAsmStreamer(S, OS); +} + +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; +} + + +MCTargetStreamer * +createRISCVObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { + const Triple &TT = STI.getTargetTriple(); + if (TT.isOSBinFormatELF()) + return new RISCVTargetELFStreamer(S); + return nullptr; +} + +} //end namespace llvm Index: lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h +++ lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h @@ -20,13 +20,18 @@ #include namespace llvm { +class formatted_raw_ostream; class MCAsmBackend; class MCCodeEmitter; class MCContext; class MCInstrInfo; +class MCInstPrinter; class MCObjectWriter; class MCRegisterInfo; +class MCStreamer; class MCSubtargetInfo; +class MCTargetOptions; +class MCTargetStreamer; class StringRef; class Target; class Triple; @@ -46,8 +51,15 @@ std::unique_ptr createRISCVELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, bool Is64Bit); -} +MCTargetStreamer *createRISCVAsmTargetStreamer(MCStreamer &S, + formatted_raw_ostream &OS, + MCInstPrinter *InstPrint, + bool isVerboseAsm); + +MCTargetStreamer *createRISCVObjectTargetStreamer(MCStreamer &S, + const MCSubtargetInfo &STI); +} // Defines symbolic names for RISC-V registers. #define GET_REGINFO_ENUM #include "RISCVGenRegisterInfo.inc" Index: lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp @@ -12,10 +12,13 @@ //===----------------------------------------------------------------------===// #include "RISCVMCTargetDesc.h" -#include "InstPrinter/RISCVInstPrinter.h" +#include "RISCVELFStreamer.h" #include "RISCVMCAsmInfo.h" +#include "InstPrinter/RISCVInstPrinter.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" @@ -67,6 +70,16 @@ return new RISCVInstPrinter(MAI, MII, MRI); } +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); @@ -76,5 +89,17 @@ TargetRegistry::RegisterMCCodeEmitter(*T, createRISCVMCCodeEmitter); TargetRegistry::RegisterMCInstPrinter(*T, createRISCVMCInstPrinter); TargetRegistry::RegisterMCSubtargetInfo(*T, createRISCVMCSubtargetInfo); + + // Register the obj streamers. + TargetRegistry::RegisterELFStreamer(*T, createELFStreamer); + + // Register the obj target streamer. + TargetRegistry::RegisterObjectTargetStreamer( + *T, createRISCVObjectTargetStreamer); + + // Register the asm streamer. + TargetRegistry::RegisterAsmTargetStreamer(*T, + createRISCVAsmTargetStreamer); + } } Index: lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h =================================================================== --- /dev/null +++ lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h @@ -0,0 +1,26 @@ +//===-- RISCVTargetStreamer.h - RISCV Target Streamer ------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64TARGETSTREAMER_H +#define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64TARGETSTREAMER_H + +#include "llvm/MC/MCStreamer.h" + +namespace llvm { + +class RISCVTargetStreamer : public MCTargetStreamer { +public: + RISCVTargetStreamer(MCStreamer &S); + ~RISCVTargetStreamer() override; +}; + +} // end namespace llvm + +#endif + Index: lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp =================================================================== --- /dev/null +++ lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp @@ -0,0 +1,25 @@ +//===- RISCVTargetStreamer.cpp - RISCVTargetStreamer class ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the RISCVTargetStreamer class. +// +//===----------------------------------------------------------------------===// + +#include "RISCVTargetStreamer.h" + +using namespace llvm; + +// +// RISCVTargetStreamer Implemenation +// +RISCVTargetStreamer::RISCVTargetStreamer(MCStreamer &S) + : MCTargetStreamer(S) {} + +RISCVTargetStreamer::~RISCVTargetStreamer() = default; +