49#define DEBUG_TYPE "asm-printer"
52 "Number of RISC-V Compressed instructions emitted");
64 const RISCVSubtarget *STI;
67 explicit RISCVAsmPrinter(TargetMachine &TM,
68 std::unique_ptr<MCStreamer> Streamer)
69 : AsmPrinter(TM, std::
move(Streamer), ID) {}
71 StringRef getPassName()
const override {
return "RISC-V Assembly Printer"; }
73 RISCVTargetStreamer &getTargetStreamer()
const {
74 return static_cast<RISCVTargetStreamer &
>(
75 *OutStreamer->getTargetStreamer());
78 void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &
SM,
79 const MachineInstr &
MI);
81 void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &
SM,
82 const MachineInstr &
MI);
84 void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &
SM,
85 const MachineInstr &
MI);
87 bool runOnMachineFunction(MachineFunction &MF)
override;
91 void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV)
override;
93 bool PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
94 const char *ExtraCode, raw_ostream &OS)
override;
95 bool PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
96 const char *ExtraCode, raw_ostream &OS)
override;
99 bool EmitToStreamer(MCStreamer &S,
const MCInst &Inst,
100 const MCSubtargetInfo &SubtargetInfo);
101 bool EmitToStreamer(MCStreamer &S,
const MCInst &Inst) {
102 return EmitToStreamer(S, Inst, *STI);
105 bool lowerPseudoInstExpansion(
const MachineInstr *
MI, MCInst &Inst);
107 typedef std::tuple<unsigned, uint32_t> HwasanMemaccessTuple;
108 std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
109 void LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI);
110 void LowerKCFI_CHECK(
const MachineInstr &
MI);
111 void EmitHwasanMemaccessSymbols(
Module &M);
114 bool lowerOperand(
const MachineOperand &MO, MCOperand &MCOp)
const;
116 void emitStartOfAsmFile(
Module &M)
override;
117 void emitEndOfAsmFile(
Module &M)
override;
119 void emitFunctionEntryLabel()
override;
120 bool emitDirectiveOptionArch();
122 void emitNoteGnuProperty(
const Module &M);
125 void emitAttributes(
const MCSubtargetInfo &SubtargetInfo);
127 void emitNTLHint(
const MachineInstr *
MI);
130 void LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI);
131 void LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI);
132 void LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI);
133 void emitSled(
const MachineInstr *
MI, SledKind Kind);
135 void lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI);
141 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
142 unsigned NumNOPBytes = StackMapOpers(&
MI).getNumPatchBytes();
145 MCSymbol *MILabel = Ctx.createTempSymbol();
148 SM.recordStackMap(*MILabel,
MI);
149 assert(NumNOPBytes % NOPBytes == 0 &&
150 "Invalid number of NOP bytes requested!");
153 const MachineBasicBlock &
MBB = *
MI.getParent();
156 while (NumNOPBytes > 0) {
157 if (MII ==
MBB.
end() || MII->isCall() ||
158 MII->getOpcode() == RISCV::DBG_VALUE ||
159 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
160 MII->getOpcode() == TargetOpcode::STACKMAP)
163 NumNOPBytes -= NOPBytes;
167 emitNops(NumNOPBytes / NOPBytes);
172void RISCVAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &
SM,
173 const MachineInstr &
MI) {
174 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
177 MCSymbol *MILabel = Ctx.createTempSymbol();
179 SM.recordPatchPoint(*MILabel,
MI);
181 PatchPointOpers Opers(&
MI);
183 const MachineOperand &CalleeMO = Opers.getCallTarget();
184 unsigned EncodedBytes = 0;
186 if (CalleeMO.
isImm()) {
187 uint64_t CallTarget = CalleeMO.
getImm();
189 assert((CallTarget & 0xFFFF'FFFF'FFFF) == CallTarget &&
190 "High 16 bits of call target should be zero.");
194 for (MCInst &Inst : Seq) {
195 bool Compressed = EmitToStreamer(OutStreamer, Inst);
196 EncodedBytes += Compressed ? 2 : 4;
198 bool Compressed = EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
202 EncodedBytes += Compressed ? 2 : 4;
205 MCOperand CallTargetMCOp;
206 lowerOperand(CalleeMO, CallTargetMCOp);
207 EmitToStreamer(OutStreamer,
208 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
213 unsigned NumBytes = Opers.getNumPatchBytes();
214 assert(NumBytes >= EncodedBytes &&
215 "Patchpoint can't request size less than the length of a call.");
216 assert((NumBytes - EncodedBytes) % NOPBytes == 0 &&
217 "Invalid number of NOP bytes requested!");
218 emitNops((NumBytes - EncodedBytes) / NOPBytes);
221void RISCVAsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &
SM,
222 const MachineInstr &
MI) {
223 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
225 StatepointOpers SOpers(&
MI);
226 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
227 assert(PatchBytes % NOPBytes == 0 &&
228 "Invalid number of NOP bytes requested!");
229 emitNops(PatchBytes / NOPBytes);
232 const MachineOperand &CallTarget = SOpers.getCallTarget();
233 MCOperand CallTargetMCOp;
234 switch (CallTarget.
getType()) {
237 lowerOperand(CallTarget, CallTargetMCOp);
240 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
244 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JAL)
250 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
262 MCSymbol *MILabel = Ctx.createTempSymbol();
264 SM.recordStatepoint(*MILabel,
MI);
267bool RISCVAsmPrinter::EmitToStreamer(MCStreamer &S,
const MCInst &Inst,
268 const MCSubtargetInfo &SubtargetInfo) {
272 ++RISCVNumInstrsCompressed;
279#include "RISCVGenMCPseudoLowering.inc"
285void RISCVAsmPrinter::emitNTLHint(
const MachineInstr *
MI) {
291 MachineMemOperand *MMO = *(
MI->memoperands_begin());
295 unsigned NontemporalMode = 0;
297 NontemporalMode += 0b1;
299 NontemporalMode += 0b10;
302 if (STI->hasStdExtZca())
303 Hint.setOpcode(RISCV::C_ADD);
305 Hint.setOpcode(RISCV::ADD);
311 EmitToStreamer(*OutStreamer, Hint);
314void RISCVAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
315 RISCV_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
320 if (MCInst OutInst; lowerPseudoInstExpansion(
MI, OutInst)) {
321 EmitToStreamer(*OutStreamer, OutInst);
325 switch (
MI->getOpcode()) {
326 case RISCV::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
327 LowerHWASAN_CHECK_MEMACCESS(*
MI);
329 case RISCV::KCFI_CHECK:
330 LowerKCFI_CHECK(*
MI);
332 case TargetOpcode::STACKMAP:
333 return LowerSTACKMAP(*OutStreamer,
SM, *
MI);
334 case TargetOpcode::PATCHPOINT:
335 return LowerPATCHPOINT(*OutStreamer,
SM, *
MI);
336 case TargetOpcode::STATEPOINT:
337 return LowerSTATEPOINT(*OutStreamer,
SM, *
MI);
338 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
339 const Function &
F =
MI->getParent()->getParent()->getFunction();
340 if (
F.hasFnAttribute(
"patchable-function-entry")) {
342 [[maybe_unused]]
bool Result =
343 F.getFnAttribute(
"patchable-function-entry")
345 .getAsInteger(10, Num);
346 assert(!Result &&
"Enforced by the verifier");
350 LowerPATCHABLE_FUNCTION_ENTER(
MI);
353 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
354 LowerPATCHABLE_FUNCTION_EXIT(
MI);
356 case TargetOpcode::PATCHABLE_TAIL_CALL:
357 LowerPATCHABLE_TAIL_CALL(
MI);
362 lowerToMCInst(
MI, OutInst);
363 EmitToStreamer(*OutStreamer, OutInst);
366bool RISCVAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
367 const char *ExtraCode, raw_ostream &OS) {
372 const MachineOperand &MO =
MI->getOperand(OpNo);
373 if (ExtraCode && ExtraCode[0]) {
374 if (ExtraCode[1] != 0)
377 switch (ExtraCode[0]) {
395 OS <<
TRI->getEncodingValue(MO.
getReg());
408 PrintSymbolOperand(MO, OS);
422bool RISCVAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
424 const char *ExtraCode,
429 const MachineOperand &AddrReg =
MI->getOperand(OpNo);
430 assert(
MI->getNumOperands() > OpNo + 1 &&
"Expected additional operand");
431 const MachineOperand &
Offset =
MI->getOperand(OpNo + 1);
434 if (!AddrReg.
isReg())
441 if (!lowerOperand(
Offset, MCO))
447 MAI->printExpr(OS, *MCO.
getExpr());
450 MMI->getContext().registerInlineAsmLabel(
Offset.getMCSymbol());
451 if (
Offset.isBlockAddress()) {
453 MCSymbol *Sym = GetBlockAddressSymbol(BA);
454 MMI->getContext().registerInlineAsmLabel(Sym);
461bool RISCVAsmPrinter::emitDirectiveOptionArch() {
462 RISCVTargetStreamer &RTS = getTargetStreamer();
464 const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
466 if (STI->hasFeature(Feature.Value) == MCSTI.
hasFeature(Feature.Value))
472 auto Delta = STI->hasFeature(Feature.Value) ? RISCVOptionArchArgType::Plus
473 : RISCVOptionArchArgType::Minus;
476 if (!NeedEmitStdOptionArgs.
empty()) {
485bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
487 RISCVTargetStreamer &RTS = getTargetStreamer();
489 bool EmittedOptionArch = emitDirectiveOptionArch();
491 SetupMachineFunction(MF);
497 if (EmittedOptionArch)
498 RTS.emitDirectiveOptionPop();
502void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI) {
503 emitSled(
MI, SledKind::FUNCTION_ENTER);
506void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI) {
507 emitSled(
MI, SledKind::FUNCTION_EXIT);
510void RISCVAsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI) {
511 emitSled(
MI, SledKind::TAIL_CALL);
514void RISCVAsmPrinter::emitSled(
const MachineInstr *
MI, SledKind Kind) {
529 const uint8_t NoopsInSledCount = STI->
is64Bit() ? 33 : 21;
532 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
534 auto Target = OutContext.createTempSymbol();
542 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addExpr(TargetExpr));
545 for (int8_t
I = 0;
I < NoopsInSledCount; ++
I)
546 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
552 recordSled(CurSled, *
MI, Kind, 2);
555void RISCVAsmPrinter::emitStartOfAsmFile(
Module &M) {
557 "target streamer is uninitialized");
558 RISCVTargetStreamer &RTS = getTargetStreamer();
559 if (
const MDString *ModuleTargetABI =
563 MCSubtargetInfo SubtargetInfo = *TM.getMCSubtargetInfo();
567 for (
auto &ISA : MD->operands()) {
570 ISAString->getString(),
true,
573 auto &ISAInfo = *ParseResult;
575 if (ISAInfo->hasExtension(Feature.Key) &&
586 if (TM.getTargetTriple().isOSBinFormatELF())
587 emitAttributes(SubtargetInfo);
590void RISCVAsmPrinter::emitEndOfAsmFile(
Module &M) {
591 RISCVTargetStreamer &RTS = getTargetStreamer();
593 if (TM.getTargetTriple().isOSBinFormatELF()) {
595 emitNoteGnuProperty(M);
597 EmitHwasanMemaccessSymbols(M);
600void RISCVAsmPrinter::emitAttributes(
const MCSubtargetInfo &SubtargetInfo) {
601 RISCVTargetStreamer &RTS = getTargetStreamer();
608void RISCVAsmPrinter::emitFunctionEntryLabel() {
609 const auto *RMFI = MF->
getInfo<RISCVMachineFunctionInfo>();
610 if (RMFI->isVectorCall()) {
611 RISCVTargetStreamer &RTS = getTargetStreamer();
626void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
628 uint32_t AccessInfo =
MI.getOperand(1).getImm();
630 HwasanMemaccessSymbols[HwasanMemaccessTuple(
Reg, AccessInfo)];
633 if (!TM.getTargetTriple().isOSBinFormatELF())
636 std::string SymName =
"__hwasan_check_x" +
utostr(
Reg - RISCV::X0) +
"_" +
637 utostr(AccessInfo) +
"_short";
638 Sym = OutContext.getOrCreateSymbol(SymName);
643 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr));
646void RISCVAsmPrinter::LowerKCFI_CHECK(
const MachineInstr &
MI) {
648 assert(std::next(
MI.getIterator())->isCall() &&
649 "KCFI_CHECK not followed by a call instruction");
650 assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
651 "KCFI_CHECK call target doesn't match call operand");
658 unsigned ScratchRegs[] = {RISCV::X6, RISCV::X7};
659 unsigned NextReg = RISCV::X28;
660 auto isRegAvailable = [&](
unsigned Reg) {
663 for (
auto &
Reg : ScratchRegs) {
664 if (isRegAvailable(
Reg))
666 while (!isRegAvailable(NextReg))
669 if (
Reg > RISCV::X31)
673 if (AddrReg == RISCV::X0) {
676 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
677 .addReg(ScratchRegs[0])
683 int NopSize = STI->hasStdExtZca() ? 2 : 4;
684 int64_t PrefixNops = 0;
687 .getFnAttribute(
"patchable-function-prefix")
689 .getAsInteger(10, PrefixNops);
692 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::LW)
693 .addReg(ScratchRegs[0])
695 .addImm(-(PrefixNops * NopSize + 4)));
699 const int64_t
Type =
MI.getOperand(1).getImm();
700 const int64_t Hi20 = ((
Type + 0x800) >> 12) & 0xFFFFF;
705 MCInstBuilder(RISCV::LUI).addReg(ScratchRegs[1]).addImm(Hi20));
707 if (Lo12 || Hi20 == 0) {
708 EmitToStreamer(*OutStreamer,
709 MCInstBuilder((STI->hasFeature(RISCV::Feature64Bit) && Hi20)
712 .addReg(ScratchRegs[1])
713 .addReg(ScratchRegs[1])
719 EmitToStreamer(*OutStreamer,
720 MCInstBuilder(RISCV::BEQ)
721 .addReg(ScratchRegs[0])
722 .addReg(ScratchRegs[1])
727 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::EBREAK));
728 emitKCFITrapEntry(*
MI.getMF(),
Trap);
732void RISCVAsmPrinter::EmitHwasanMemaccessSymbols(
Module &M) {
733 if (HwasanMemaccessSymbols.empty())
736 assert(TM.getTargetTriple().isOSBinFormatELF());
740 const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
743 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
746 RISCVTargetStreamer &RTS = getTargetStreamer();
749 const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
754 for (
auto &
P : HwasanMemaccessSymbols) {
755 unsigned Reg = std::get<0>(
P.first);
756 uint32_t AccessInfo = std::get<1>(
P.first);
774 MCInstBuilder(RISCV::SLLI).addReg(RISCV::X6).addReg(
Reg).addImm(8),
776 EmitToStreamer(*OutStreamer,
777 MCInstBuilder(RISCV::SRLI)
783 EmitToStreamer(*OutStreamer,
784 MCInstBuilder(RISCV::ADD)
791 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
796 MCInstBuilder(RISCV::SRLI).addReg(RISCV::X7).addReg(
Reg).addImm(56),
798 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
800 EmitToStreamer(*OutStreamer,
801 MCInstBuilder(RISCV::BNE)
805 HandleMismatchOrPartialSym, OutContext)),
807 MCSymbol *ReturnSym = OutContext.createTempSymbol();
809 EmitToStreamer(*OutStreamer,
810 MCInstBuilder(RISCV::JALR)
815 OutStreamer->
emitLabel(HandleMismatchOrPartialSym);
817 EmitToStreamer(*OutStreamer,
818 MCInstBuilder(RISCV::ADDI)
823 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
826 MCInstBuilder(RISCV::BGEU)
834 MCInstBuilder(RISCV::ANDI).addReg(RISCV::X28).addReg(
Reg).addImm(0xF),
838 EmitToStreamer(*OutStreamer,
839 MCInstBuilder(RISCV::ADDI)
846 MCInstBuilder(RISCV::BGE)
854 MCInstBuilder(RISCV::ORI).addReg(RISCV::X6).addReg(
Reg).addImm(0xF),
858 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
860 EmitToStreamer(*OutStreamer,
861 MCInstBuilder(RISCV::BEQ)
867 OutStreamer->
emitLabel(HandleMismatchSym);
904 EmitToStreamer(*OutStreamer,
905 MCInstBuilder(RISCV::ADDI)
912 EmitToStreamer(*OutStreamer,
913 MCInstBuilder(RISCV::SD)
919 EmitToStreamer(*OutStreamer,
920 MCInstBuilder(RISCV::SD)
929 MCInstBuilder(RISCV::SD).addReg(RISCV::X8).addReg(RISCV::X2).addImm(8 *
935 MCInstBuilder(RISCV::SD).addReg(RISCV::X1).addReg(RISCV::X2).addImm(1 *
938 if (
Reg != RISCV::X10)
941 MCInstBuilder(RISCV::ADDI).addReg(RISCV::X10).addReg(
Reg).addImm(0),
943 EmitToStreamer(*OutStreamer,
944 MCInstBuilder(RISCV::ADDI)
950 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr),
955void RISCVAsmPrinter::emitNoteGnuProperty(
const Module &M) {
956 assert(TM.getTargetTriple().isOSBinFormatELF() &&
"invalid binary format");
957 if (
const Metadata *
const Flag =
M.getModuleFlag(
"cf-protection-return");
959 auto &RTS =
static_cast<RISCVTargetELFStreamer &
>(getTargetStreamer());
982 Kind = ELF::R_RISCV_HI20;
997 Kind = ELF::R_RISCV_TPREL_HI20;
1000 Kind = ELF::R_RISCV_TPREL_ADD;
1003 Kind = ELF::R_RISCV_TLS_GOT_HI20;
1006 Kind = ELF::R_RISCV_TLS_GD_HI20;
1009 Kind = ELF::R_RISCV_TLSDESC_HI20;
1012 Kind = ELF::R_RISCV_TLSDESC_LOAD_LO12;
1015 Kind = ELF::R_RISCV_TLSDESC_ADD_LO12;
1018 Kind = ELF::R_RISCV_TLSDESC_CALL;
1033bool RISCVAsmPrinter::lowerOperand(
const MachineOperand &MO,
1034 MCOperand &MCOp)
const {
1081 RISCVVPseudosTable::getPseudoInfo(
MI->getOpcode());
1089 assert(
TRI &&
"TargetRegisterInfo expected");
1093 unsigned NumOps =
MI->getNumExplicitOperands();
1112 bool hasVLOutput = RISCVInstrInfo::isFaultOnlyFirstLoad(*
MI);
1113 for (
unsigned OpNo = 0; OpNo !=
NumOps; ++OpNo) {
1116 if (hasVLOutput && OpNo == 1)
1120 if (OpNo ==
MI->getNumExplicitDefs() && MO.
isReg() && MO.
isTied()) {
1122 "Expected tied to first def.");
1142 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1143 assert(
Reg &&
"Subregister does not exist");
1146 TRI->getMatchingSuperReg(
Reg, RISCV::sub_16, &RISCV::FPR32RegClass);
1147 assert(
Reg &&
"Subregister does not exist");
1149 Reg =
TRI->getSubReg(
Reg, RISCV::sub_32);
1150 assert(
Reg &&
"Superregister does not exist");
1162 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1163 assert(
Reg &&
"Subregister does not exist");
1182 "Expected only mask operand to be missing");
1190void RISCVAsmPrinter::lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI) {
1196 for (
const MachineOperand &MO :
MI->operands()) {
1198 if (lowerOperand(MO, MCOp))
1203void RISCVAsmPrinter::emitMachineConstantPoolValue(
1204 MachineConstantPoolValue *MCPV) {
1205 auto *RCPV =
static_cast<RISCVConstantPoolValue *
>(MCPV);
1208 if (RCPV->isGlobalValue()) {
1209 auto *GV = RCPV->getGlobalValue();
1210 MCSym = getSymbol(GV);
1212 assert(RCPV->isExtSymbol() &&
"unrecognized constant pool type");
1213 auto Sym = RCPV->getSymbol();
1214 MCSym = GetExternalSymbolSymbol(Sym);
1218 uint64_t
Size = getDataLayout().getTypeAllocSize(RCPV->getType());
1222char RISCVAsmPrinter::ID = 0;
1224INITIALIZE_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
static constexpr unsigned SM(unsigned Version)
#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")
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
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 requiresNTLHint(const MachineInstr &MI) const
Return true if the instruction requires an NTL hint to be emitted.
bool isRegisterReservedByUser(Register i) const override
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
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)
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.