48#define DEBUG_TYPE "asm-printer" 
   51          "Number of RISC-V Compressed instructions emitted");
 
   63  const RISCVSubtarget *STI;
 
   66  explicit RISCVAsmPrinter(TargetMachine &TM,
 
   67                           std::unique_ptr<MCStreamer> Streamer)
 
   68      : AsmPrinter(
TM, std::
move(Streamer), ID) {}
 
   70  StringRef getPassName()
 const override { 
return "RISC-V Assembly Printer"; }
 
   72  void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
 
   73                     const MachineInstr &
MI);
 
   75  void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
 
   76                       const MachineInstr &
MI);
 
   78  void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
 
   79                       const MachineInstr &
MI);
 
   81  bool runOnMachineFunction(MachineFunction &MF) 
override;
 
   85  void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) 
override;
 
   87  bool PrintAsmOperand(
const MachineInstr *
MI, 
unsigned OpNo,
 
   88                       const char *ExtraCode, raw_ostream &OS) 
override;
 
   89  bool PrintAsmMemoryOperand(
const MachineInstr *
MI, 
unsigned OpNo,
 
   90                             const char *ExtraCode, raw_ostream &OS) 
override;
 
   93  bool EmitToStreamer(MCStreamer &S, 
const MCInst &Inst,
 
   94                      const MCSubtargetInfo &SubtargetInfo);
 
   95  bool EmitToStreamer(MCStreamer &S, 
const MCInst &Inst) {
 
   96    return EmitToStreamer(S, Inst, *STI);
 
   99  bool lowerPseudoInstExpansion(
const MachineInstr *
MI, MCInst &Inst);
 
  101  typedef std::tuple<unsigned, uint32_t> HwasanMemaccessTuple;
 
  102  std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
 
  103  void LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI);
 
  104  void LowerKCFI_CHECK(
const MachineInstr &
MI);
 
  105  void EmitHwasanMemaccessSymbols(
Module &M);
 
  108  bool lowerOperand(
const MachineOperand &MO, MCOperand &MCOp) 
const;
 
  110  void emitStartOfAsmFile(
Module &M) 
override;
 
  111  void emitEndOfAsmFile(
Module &M) 
override;
 
  113  void emitFunctionEntryLabel() 
override;
 
  114  bool emitDirectiveOptionArch();
 
  116  void emitNoteGnuProperty(
const Module &M);
 
  119  void emitAttributes(
const MCSubtargetInfo &SubtargetInfo);
 
  121  void emitNTLHint(
const MachineInstr *
MI);
 
  124  void LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI);
 
  125  void LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI);
 
  126  void LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI);
 
  127  void emitSled(
const MachineInstr *
MI, SledKind Kind);
 
  129  void lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI);
 
  135  unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
 
  136  unsigned NumNOPBytes = StackMapOpers(&
MI).getNumPatchBytes();
 
  139  MCSymbol *MILabel = Ctx.createTempSymbol();
 
  143  assert(NumNOPBytes % NOPBytes == 0 &&
 
  144         "Invalid number of NOP bytes requested!");
 
  147  const MachineBasicBlock &
MBB = *
MI.getParent();
 
  150  while (NumNOPBytes > 0) {
 
  151    if (MII == 
MBB.
end() || MII->isCall() ||
 
  152        MII->getOpcode() == RISCV::DBG_VALUE ||
 
  153        MII->getOpcode() == TargetOpcode::PATCHPOINT ||
 
  154        MII->getOpcode() == TargetOpcode::STACKMAP)
 
  161  emitNops(NumNOPBytes / NOPBytes);
 
  166void RISCVAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
 
  167                                      const MachineInstr &
MI) {
 
  168  unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
 
  171  MCSymbol *MILabel = Ctx.createTempSymbol();
 
  175  PatchPointOpers Opers(&
MI);
 
  177  const MachineOperand &CalleeMO = Opers.getCallTarget();
 
  178  unsigned EncodedBytes = 0;
 
  180  if (CalleeMO.
isImm()) {
 
  181    uint64_t CallTarget = CalleeMO.
getImm();
 
  183      assert((CallTarget & 0xFFFF'FFFF'FFFF) == CallTarget &&
 
  184             "High 16 bits of call target should be zero.");
 
  188      for (MCInst &Inst : Seq) {
 
  189        bool Compressed = EmitToStreamer(OutStreamer, Inst);
 
  190        EncodedBytes += Compressed ? 2 : 4;
 
  192      bool Compressed = EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
 
  196      EncodedBytes += Compressed ? 2 : 4;
 
  199    MCOperand CallTargetMCOp;
 
  200    lowerOperand(CalleeMO, CallTargetMCOp);
 
  201    EmitToStreamer(OutStreamer,
 
  202                   MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
 
  207  unsigned NumBytes = Opers.getNumPatchBytes();
 
  208  assert(NumBytes >= EncodedBytes &&
 
  209         "Patchpoint can't request size less than the length of a call.");
 
  210  assert((NumBytes - EncodedBytes) % NOPBytes == 0 &&
 
  211         "Invalid number of NOP bytes requested!");
 
  212  emitNops((NumBytes - EncodedBytes) / NOPBytes);
 
  215void RISCVAsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
 
  216                                      const MachineInstr &
MI) {
 
  217  unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
 
  219  StatepointOpers SOpers(&
MI);
 
  220  if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
 
  221    assert(PatchBytes % NOPBytes == 0 &&
 
  222           "Invalid number of NOP bytes requested!");
 
  223    emitNops(PatchBytes / NOPBytes);
 
  226    const MachineOperand &CallTarget = SOpers.getCallTarget();
 
  227    MCOperand CallTargetMCOp;
 
  228    switch (CallTarget.
getType()) {
 
  231      lowerOperand(CallTarget, CallTargetMCOp);
 
  234          MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
 
  238      EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JAL)
 
  244      EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
 
  256  MCSymbol *MILabel = Ctx.createTempSymbol();
 
  261bool RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, 
const MCInst &Inst,
 
  262                                     const MCSubtargetInfo &SubtargetInfo) {
 
  266    ++RISCVNumInstrsCompressed;
 
  273#include "RISCVGenMCPseudoLowering.inc" 
  277void RISCVAsmPrinter::emitNTLHint(
const MachineInstr *
MI) {
 
  278  if (!STI->hasStdExtZihintntl())
 
  281  if (
MI->memoperands_empty())
 
  284  MachineMemOperand *MMO = *(
MI->memoperands_begin());
 
  288  unsigned NontemporalMode = 0;
 
  290    NontemporalMode += 0b1;
 
  292    NontemporalMode += 0b10;
 
  295  if (STI->hasStdExtZca())
 
  296    Hint.setOpcode(RISCV::C_ADD);
 
  298    Hint.setOpcode(RISCV::ADD);
 
  304  EmitToStreamer(*OutStreamer, Hint);
 
  307void RISCVAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
 
  308  RISCV_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
 
  313  if (MCInst OutInst; lowerPseudoInstExpansion(
MI, OutInst)) {
 
  314    EmitToStreamer(*OutStreamer, OutInst);
 
  318  switch (
MI->getOpcode()) {
 
  319  case RISCV::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
 
  320    LowerHWASAN_CHECK_MEMACCESS(*
MI);
 
  322  case RISCV::KCFI_CHECK:
 
  323    LowerKCFI_CHECK(*
MI);
 
  325  case TargetOpcode::STACKMAP:
 
  326    return LowerSTACKMAP(*OutStreamer, SM, *
MI);
 
  327  case TargetOpcode::PATCHPOINT:
 
  328    return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
 
  329  case TargetOpcode::STATEPOINT:
 
  330    return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
 
  331  case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
 
  332    const Function &
F = 
MI->getParent()->getParent()->getFunction();
 
  333    if (
F.hasFnAttribute(
"patchable-function-entry")) {
 
  335      [[maybe_unused]] 
bool Result =
 
  336          F.getFnAttribute(
"patchable-function-entry")
 
  338              .getAsInteger(10, Num);
 
  339      assert(!Result && 
"Enforced by the verifier");
 
  343    LowerPATCHABLE_FUNCTION_ENTER(
MI);
 
  346  case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
 
  347    LowerPATCHABLE_FUNCTION_EXIT(
MI);
 
  349  case TargetOpcode::PATCHABLE_TAIL_CALL:
 
  350    LowerPATCHABLE_TAIL_CALL(
MI);
 
  355  lowerToMCInst(
MI, OutInst);
 
  356  EmitToStreamer(*OutStreamer, OutInst);
 
  359bool RISCVAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI, 
unsigned OpNo,
 
  360                                      const char *ExtraCode, raw_ostream &OS) {
 
  365  const MachineOperand &MO = 
MI->getOperand(OpNo);
 
  366  if (ExtraCode && ExtraCode[0]) {
 
  367    if (ExtraCode[1] != 0)
 
  370    switch (ExtraCode[0]) {
 
  388      OS << 
TRI->getEncodingValue(MO.
getReg());
 
  401    PrintSymbolOperand(MO, OS);
 
  415bool RISCVAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
 
  417                                            const char *ExtraCode,
 
  422  const MachineOperand &AddrReg = 
MI->getOperand(OpNo);
 
  423  assert(
MI->getNumOperands() > OpNo + 1 && 
"Expected additional operand");
 
  424  const MachineOperand &
Offset = 
MI->getOperand(OpNo + 1);
 
  427  if (!AddrReg.
isReg())
 
  434  if (!lowerOperand(
Offset, MCO))
 
  440    MAI->printExpr(OS, *MCO.
getExpr());
 
  443    MMI->getContext().registerInlineAsmLabel(
Offset.getMCSymbol());
 
  444  if (
Offset.isBlockAddress()) {
 
  446    MCSymbol *Sym = GetBlockAddressSymbol(BA);
 
  447    MMI->getContext().registerInlineAsmLabel(Sym);
 
  454bool RISCVAsmPrinter::emitDirectiveOptionArch() {
 
  455  RISCVTargetStreamer &RTS =
 
  458  const MCSubtargetInfo &MCSTI = *
TM.getMCSubtargetInfo();
 
  460    if (STI->hasFeature(Feature.Value) == MCSTI.
hasFeature(Feature.Value))
 
  466    auto Delta = STI->hasFeature(Feature.Value) ? RISCVOptionArchArgType::Plus
 
  467                                                : RISCVOptionArchArgType::Minus;
 
  470  if (!NeedEmitStdOptionArgs.
empty()) {
 
  479bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
  481  RISCVTargetStreamer &RTS =
 
  484  bool EmittedOptionArch = emitDirectiveOptionArch();
 
  486  SetupMachineFunction(MF);
 
  492  if (EmittedOptionArch)
 
  493    RTS.emitDirectiveOptionPop();
 
  497void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI) {
 
  498  emitSled(
MI, SledKind::FUNCTION_ENTER);
 
  501void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI) {
 
  502  emitSled(
MI, SledKind::FUNCTION_EXIT);
 
  505void RISCVAsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI) {
 
  506  emitSled(
MI, SledKind::TAIL_CALL);
 
  509void RISCVAsmPrinter::emitSled(
const MachineInstr *
MI, SledKind Kind) {
 
  524  const uint8_t NoopsInSledCount = STI->
is64Bit() ? 33 : 21;
 
  527  auto CurSled = OutContext.createTempSymbol(
"xray_sled_", 
true);
 
  529  auto Target = OutContext.createTempSymbol();
 
  537      MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addExpr(TargetExpr));
 
  540  for (int8_t 
I = 0; 
I < NoopsInSledCount; ++
I)
 
  541    EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
 
  547  recordSled(CurSled, *
MI, Kind, 2);
 
  550void RISCVAsmPrinter::emitStartOfAsmFile(
Module &M) {
 
  551  RISCVTargetStreamer &RTS =
 
  553  if (
const MDString *ModuleTargetABI =
 
  557  MCSubtargetInfo SubtargetInfo = *
TM.getMCSubtargetInfo();
 
  561    for (
auto &ISA : MD->operands()) {
 
  564            ISAString->getString(), 
true,
 
  567          auto &ISAInfo = *ParseResult;
 
  569            if (ISAInfo->hasExtension(Feature.Key) &&
 
  580  if (
TM.getTargetTriple().isOSBinFormatELF())
 
  581    emitAttributes(SubtargetInfo);
 
  584void RISCVAsmPrinter::emitEndOfAsmFile(
Module &M) {
 
  585  RISCVTargetStreamer &RTS =
 
  588  if (
TM.getTargetTriple().isOSBinFormatELF()) {
 
  590    emitNoteGnuProperty(M);
 
  592  EmitHwasanMemaccessSymbols(M);
 
  595void RISCVAsmPrinter::emitAttributes(
const MCSubtargetInfo &SubtargetInfo) {
 
  596  RISCVTargetStreamer &RTS =
 
  604void RISCVAsmPrinter::emitFunctionEntryLabel() {
 
  605  const auto *RMFI = MF->
getInfo<RISCVMachineFunctionInfo>();
 
  606  if (RMFI->isVectorCall()) {
 
  623void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
 
  625  uint32_t AccessInfo = 
MI.getOperand(1).getImm();
 
  627      HwasanMemaccessSymbols[HwasanMemaccessTuple(
Reg, AccessInfo)];
 
  630    if (!
TM.getTargetTriple().isOSBinFormatELF())
 
  633    std::string SymName = 
"__hwasan_check_x" + 
utostr(
Reg - RISCV::X0) + 
"_" +
 
  634                          utostr(AccessInfo) + 
"_short";
 
  635    Sym = OutContext.getOrCreateSymbol(SymName);
 
  640  EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr));
 
  643void RISCVAsmPrinter::LowerKCFI_CHECK(
const MachineInstr &
MI) {
 
  645  assert(std::next(
MI.getIterator())->isCall() &&
 
  646         "KCFI_CHECK not followed by a call instruction");
 
  647  assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
 
  648         "KCFI_CHECK call target doesn't match call operand");
 
  655  unsigned ScratchRegs[] = {RISCV::X6, RISCV::X7};
 
  656  unsigned NextReg = RISCV::X28;
 
  657  auto isRegAvailable = [&](
unsigned Reg) {
 
  660  for (
auto &
Reg : ScratchRegs) {
 
  661    if (isRegAvailable(
Reg))
 
  663    while (!isRegAvailable(NextReg))
 
  666    if (
Reg > RISCV::X31)
 
  670  if (AddrReg == RISCV::X0) {
 
  673    EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
 
  674                                     .addReg(ScratchRegs[0])
 
  680    int NopSize = STI->hasStdExtZca() ? 2 : 4;
 
  681    int64_t PrefixNops = 0;
 
  684        .getFnAttribute(
"patchable-function-prefix")
 
  686        .getAsInteger(10, PrefixNops);
 
  689    EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::LW)
 
  690                                     .addReg(ScratchRegs[0])
 
  692                                     .addImm(-(PrefixNops * NopSize + 4)));
 
  696  const int64_t 
Type = 
MI.getOperand(1).getImm();
 
  697  const int64_t Hi20 = ((
Type + 0x800) >> 12) & 0xFFFFF;
 
  702        MCInstBuilder(RISCV::LUI).addReg(ScratchRegs[1]).addImm(Hi20));
 
  704  if (Lo12 || Hi20 == 0) {
 
  705    EmitToStreamer(*OutStreamer,
 
  706                   MCInstBuilder((STI->hasFeature(RISCV::Feature64Bit) && Hi20)
 
  709                       .addReg(ScratchRegs[1])
 
  710                       .addReg(ScratchRegs[1])
 
  716  EmitToStreamer(*OutStreamer,
 
  717                 MCInstBuilder(RISCV::BEQ)
 
  718                     .addReg(ScratchRegs[0])
 
  719                     .addReg(ScratchRegs[1])
 
  724  EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::EBREAK));
 
  725  emitKCFITrapEntry(*
MI.getMF(), 
Trap);
 
  729void RISCVAsmPrinter::EmitHwasanMemaccessSymbols(
Module &M) {
 
  730  if (HwasanMemaccessSymbols.empty())
 
  733  assert(
TM.getTargetTriple().isOSBinFormatELF());
 
  737  const MCSubtargetInfo &MCSTI = *
TM.getMCSubtargetInfo();
 
  740      OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
 
  747  const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
 
  750                                      ELF::R_RISCV_CALL_PLT, OutContext);
 
  752  for (
auto &
P : HwasanMemaccessSymbols) {
 
  753    unsigned Reg = std::get<0>(
P.first);
 
  754    uint32_t AccessInfo = std::get<1>(
P.first);
 
  772        MCInstBuilder(RISCV::SLLI).addReg(RISCV::X6).addReg(
Reg).addImm(8),
 
  774    EmitToStreamer(*OutStreamer,
 
  775                   MCInstBuilder(RISCV::SRLI)
 
  781    EmitToStreamer(*OutStreamer,
 
  782                   MCInstBuilder(RISCV::ADD)
 
  789        MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
 
  794        MCInstBuilder(RISCV::SRLI).addReg(RISCV::X7).addReg(
Reg).addImm(56),
 
  796    MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
 
  798    EmitToStreamer(*OutStreamer,
 
  799                   MCInstBuilder(RISCV::BNE)
 
  803                           HandleMismatchOrPartialSym, OutContext)),
 
  805    MCSymbol *ReturnSym = OutContext.createTempSymbol();
 
  807    EmitToStreamer(*OutStreamer,
 
  808                   MCInstBuilder(RISCV::JALR)
 
  813    OutStreamer->
emitLabel(HandleMismatchOrPartialSym);
 
  815    EmitToStreamer(*OutStreamer,
 
  816                   MCInstBuilder(RISCV::ADDI)
 
  821    MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
 
  824        MCInstBuilder(RISCV::BGEU)
 
  832        MCInstBuilder(RISCV::ANDI).addReg(RISCV::X28).addReg(
Reg).addImm(0xF),
 
  836      EmitToStreamer(*OutStreamer,
 
  837                     MCInstBuilder(RISCV::ADDI)
 
  844        MCInstBuilder(RISCV::BGE)
 
  852        MCInstBuilder(RISCV::ORI).addReg(RISCV::X6).addReg(
Reg).addImm(0xF),
 
  856        MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
 
  858    EmitToStreamer(*OutStreamer,
 
  859                   MCInstBuilder(RISCV::BEQ)
 
  865    OutStreamer->
emitLabel(HandleMismatchSym);
 
  902    EmitToStreamer(*OutStreamer,
 
  903                   MCInstBuilder(RISCV::ADDI)
 
  910    EmitToStreamer(*OutStreamer,
 
  911                   MCInstBuilder(RISCV::SD)
 
  917    EmitToStreamer(*OutStreamer,
 
  918                   MCInstBuilder(RISCV::SD)
 
  927        MCInstBuilder(RISCV::SD).addReg(RISCV::X8).addReg(RISCV::X2).addImm(8 *
 
  933        MCInstBuilder(RISCV::SD).addReg(RISCV::X1).addReg(RISCV::X2).addImm(1 *
 
  936    if (
Reg != RISCV::X10)
 
  939          MCInstBuilder(RISCV::ADDI).addReg(RISCV::X10).addReg(
Reg).addImm(0),
 
  941    EmitToStreamer(*OutStreamer,
 
  942                   MCInstBuilder(RISCV::ADDI)
 
  948    EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr),
 
  953void RISCVAsmPrinter::emitNoteGnuProperty(
const Module &M) {
 
  954  if (
const Metadata *
const Flag = 
M.getModuleFlag(
"cf-protection-return");
 
  956    RISCVTargetStreamer &RTS =
 
  974    Kind = ELF::R_RISCV_CALL_PLT;
 
  980    Kind = ELF::R_RISCV_HI20;
 
  986    Kind = ELF::R_RISCV_PCREL_HI20;
 
  989    Kind = ELF::R_RISCV_GOT_HI20;
 
  995    Kind = ELF::R_RISCV_TPREL_HI20;
 
  998    Kind = ELF::R_RISCV_TPREL_ADD;
 
 1001    Kind = ELF::R_RISCV_TLS_GOT_HI20;
 
 1004    Kind = ELF::R_RISCV_TLS_GD_HI20;
 
 1007    Kind = ELF::R_RISCV_TLSDESC_HI20;
 
 1010    Kind = ELF::R_RISCV_TLSDESC_LOAD_LO12;
 
 1013    Kind = ELF::R_RISCV_TLSDESC_ADD_LO12;
 
 1016    Kind = ELF::R_RISCV_TLSDESC_CALL;
 
 
 1031bool RISCVAsmPrinter::lowerOperand(
const MachineOperand &MO,
 
 1032                                   MCOperand &MCOp)
 const {
 
 1079      RISCVVPseudosTable::getPseudoInfo(
MI->getOpcode());
 
 1087  assert(
TRI && 
"TargetRegisterInfo expected");
 
 1091  unsigned NumOps = 
MI->getNumExplicitOperands();
 
 1110  bool hasVLOutput = RISCVInstrInfo::isFaultOnlyFirstLoad(*
MI);
 
 1111  for (
unsigned OpNo = 0; OpNo != 
NumOps; ++OpNo) {
 
 1114    if (hasVLOutput && OpNo == 1)
 
 1118    if (OpNo == 
MI->getNumExplicitDefs() && MO.
isReg() && MO.
isTied()) {
 
 1120             "Expected tied to first def.");
 
 1140        Reg = 
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
 
 1141        assert(
Reg && 
"Subregister does not exist");
 
 1144            TRI->getMatchingSuperReg(
Reg, RISCV::sub_16, &RISCV::FPR32RegClass);
 
 1145        assert(
Reg && 
"Subregister does not exist");
 
 1147        Reg = 
TRI->getSubReg(
Reg, RISCV::sub_32);
 
 1148        assert(
Reg && 
"Superregister does not exist");
 
 1160        Reg = 
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
 
 1161        assert(
Reg && 
"Subregister does not exist");
 
 1179               RISCV::VMV0RegClassID &&
 
 1180           "Expected only mask operand to be missing");
 
 
 1188void RISCVAsmPrinter::lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI) {
 
 1194  for (
const MachineOperand &MO : 
MI->operands()) {
 
 1196    if (lowerOperand(MO, MCOp))
 
 1201void RISCVAsmPrinter::emitMachineConstantPoolValue(
 
 1202    MachineConstantPoolValue *MCPV) {
 
 1203  auto *RCPV = 
static_cast<RISCVConstantPoolValue *
>(MCPV);
 
 1206  if (RCPV->isGlobalValue()) {
 
 1207    auto *GV = RCPV->getGlobalValue();
 
 1208    MCSym = getSymbol(GV);
 
 1210    assert(RCPV->isExtSymbol() && 
"unrecognized constant pool type");
 
 1211    auto Sym = RCPV->getSymbol();
 
 1212    MCSym = GetExternalSymbolSymbol(Sym);
 
 1216  uint64_t 
Size = getDataLayout().getTypeAllocSize(RCPV->getType());
 
 1220char RISCVAsmPrinter::ID = 0;
 
 1222INITIALIZE_PASS(RISCVAsmPrinter, 
"riscv-asm-printer", 
"RISC-V Assembly Printer",
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym, const AsmPrinter &AP)
print mir2vec MIR2Vec Vocabulary Printer Pass
Machine Check Debug Module
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool lowerRISCVVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, const RISCVSubtarget *STI)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmPrinter()
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This class is intended to be used as a driving class for all asm writers.
MCContext & OutContext
This is the context for the output file that we are streaming.
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
const MCExpr * getExpr() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
MCContext & getContext() const
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
bool hasFeature(unsigned Feature) const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
StringRef getName() const
getName - Get the symbol name.
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
bool isNonTemporal() const
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
const BlockAddress * getBlockAddress() const
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
MCSymbol * getMCSymbol() const
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_MCSymbol
MCSymbol reference (for debug/eh info)
@ MO_GlobalAddress
Address of a global value.
@ MO_RegisterMask
Mask of preserved registers.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
int64_t getOffset() const
Return the offset from the symbol in this operand.
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
static LLVM_ABI bool isSupportedExtensionFeature(StringRef Ext)
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
static const char * getRegisterName(MCRegister Reg)
bool isRegisterReservedByUser(Register i) const override
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
void emitNoteGnuPropertySection(const uint32_t Feature1And)
virtual void emitDirectiveVariantCC(MCSymbol &Symbol)
void emitTargetAttributes(const MCSubtargetInfo &STI, bool EmitStackAlign)
void setFlagsFromFeatures(const MCSubtargetInfo &STI)
void setTargetABI(RISCVABI::ABI ABI)
virtual void emitDirectiveOptionArch(ArrayRef< RISCVOptionArchArg > Args)
virtual void finishAttributeSection()
virtual void emitDirectiveOptionPush()
Wrapper class representing virtual and physical registers.
reference emplace_back(ArgTypes &&... Args)
LLVM_ABI void recordStatepoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a statepoint instruction.
LLVM_ABI void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
LLVM_ABI void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS
ABI getTargetABI(StringRef ABIName)
static bool hasRoundModeOp(uint64_t TSFlags)
static bool hasTWidenOp(uint64_t TSFlags)
static bool isTiedPseudo(uint64_t TSFlags)
static bool hasTKOp(uint64_t TSFlags)
static bool hasVLOp(uint64_t TSFlags)
static bool hasTMOp(uint64_t TSFlags)
static bool hasVecPolicyOp(uint64_t TSFlags)
static bool hasSEWOp(uint64_t TSFlags)
void generateMCInstSeq(int64_t Val, const MCSubtargetInfo &STI, MCRegister DestReg, SmallVectorImpl< MCInst > &Insts)
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
static const MachineMemOperand::Flags MONontemporalBit1
Target & getTheRISCV32Target()
static const MachineMemOperand::Flags MONontemporalBit0
std::string utostr(uint64_t X, bool isNeg=false)
Target & getTheRISCV64beTarget()
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
Target & getTheRISCV64Target()
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
@ MCSA_Hidden
.hidden (ELF)
Target & getTheRISCV32beTarget()
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
Used to provide key value pairs for feature and CPU bit flags.