text: //===-- RISCVMCCodeEmitter.cpp - Convert RISCV code to machine code -------===//
  //
  //                     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 RISCVMCCodeEmitter class.
  //
  //===----------------------------------------------------------------------===//
  
  #include "MCTargetDesc/RISCVMCTargetDesc.h"
  #include "llvm/ADT/Statistic.h"
  #include "llvm/MC/MCAsmInfo.h"
  #include "llvm/MC/MCCodeEmitter.h"
  #include "llvm/MC/MCContext.h"
  #include "llvm/MC/MCExpr.h"
  #include "llvm/MC/MCInst.h"
  #include "llvm/MC/MCRegisterInfo.h"
  #include "llvm/MC/MCSymbol.h"
  #include "llvm/Support/EndianStream.h"
  #include "llvm/Support/raw_ostream.h"
  
  using namespace llvm;
  
  #define DEBUG_TYPE "mccodeemitter"
  
  STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
  
  namespace {
  class RISCVMCCodeEmitter : public MCCodeEmitter {
    RISCVMCCodeEmitter(const RISCVMCCodeEmitter &) = delete;
    void operator=(const RISCVMCCodeEmitter &) = delete;
    MCContext &Ctx;
  
  public:
    RISCVMCCodeEmitter(MCContext &ctx) : Ctx(ctx) {}
  
    ~RISCVMCCodeEmitter() override {}
  
    void encodeInstruction(const MCInst &MI, raw_ostream &OS,
                           SmallVectorImpl<MCFixup> &Fixups,
                           const MCSubtargetInfo &STI) const override;
  
    /// TableGen'erated function for getting the binary encoding for an
    /// instruction.
    uint64_t getBinaryCodeForInstr(const MCInst &MI,
                                   SmallVectorImpl<MCFixup> &Fixups,
                                   const MCSubtargetInfo &STI) const;
  
    /// Return binary encoding of operand. If the machine operand requires
    /// relocation, record the relocation and return zero.
    unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                               SmallVectorImpl<MCFixup> &Fixups,
                               const MCSubtargetInfo &STI) const;
  };
  } // end anonymous namespace
  
  MCCodeEmitter *llvm::createRISCVMCCodeEmitter(const MCInstrInfo &MCII,
                                                const MCRegisterInfo &MRI,
                                                MCContext &Ctx) {
    return new RISCVMCCodeEmitter(Ctx);
  }
  
  void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
                                             SmallVectorImpl<MCFixup> &Fixups,
                                             const MCSubtargetInfo &STI) const {
    // For now, we only support RISC-V instructions with 32-bit length
    uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
    support::endian::Writer<support::little>(OS).write(Bits);
    ++MCNumEmitted; // Keep track of the # of mi's emitted.
  }
  
  unsigned
  RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                                        SmallVectorImpl<MCFixup> &Fixups,
                                        const MCSubtargetInfo &STI) const {
  
    if (MO.isReg())
      return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
  
    if (MO.isImm())
      return static_cast<unsigned>(MO.getImm());
  
    llvm_unreachable("Unhandled expression!");
    return 0;
  }
  
  #include "RISCVGenMCCodeEmitter.inc"
  