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 void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
74 const MachineInstr &
MI);
76 void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
77 const MachineInstr &
MI);
79 void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
80 const MachineInstr &
MI);
82 bool runOnMachineFunction(MachineFunction &MF)
override;
86 void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV)
override;
88 bool PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
89 const char *ExtraCode, raw_ostream &OS)
override;
90 bool PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
91 const char *ExtraCode, raw_ostream &OS)
override;
94 bool EmitToStreamer(MCStreamer &S,
const MCInst &Inst,
95 const MCSubtargetInfo &SubtargetInfo);
96 bool EmitToStreamer(MCStreamer &S,
const MCInst &Inst) {
97 return EmitToStreamer(S, Inst, *STI);
100 bool lowerPseudoInstExpansion(
const MachineInstr *
MI, MCInst &Inst);
102 typedef std::tuple<unsigned, uint32_t> HwasanMemaccessTuple;
103 std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
104 void LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI);
105 void LowerKCFI_CHECK(
const MachineInstr &
MI);
106 void EmitHwasanMemaccessSymbols(
Module &M);
109 bool lowerOperand(
const MachineOperand &MO, MCOperand &MCOp)
const;
111 void emitStartOfAsmFile(
Module &M)
override;
112 void emitEndOfAsmFile(
Module &M)
override;
114 void emitFunctionEntryLabel()
override;
115 bool emitDirectiveOptionArch();
117 void emitNoteGnuProperty(
const Module &M);
120 void emitAttributes(
const MCSubtargetInfo &SubtargetInfo);
122 void emitNTLHint(
const MachineInstr *
MI);
125 void LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI);
126 void LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI);
127 void LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI);
128 void emitSled(
const MachineInstr *
MI, SledKind Kind);
130 void lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI);
136 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
137 unsigned NumNOPBytes = StackMapOpers(&
MI).getNumPatchBytes();
140 MCSymbol *MILabel = Ctx.createTempSymbol();
144 assert(NumNOPBytes % NOPBytes == 0 &&
145 "Invalid number of NOP bytes requested!");
148 const MachineBasicBlock &
MBB = *
MI.getParent();
151 while (NumNOPBytes > 0) {
152 if (MII ==
MBB.
end() || MII->isCall() ||
153 MII->getOpcode() == RISCV::DBG_VALUE ||
154 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
155 MII->getOpcode() == TargetOpcode::STACKMAP)
162 emitNops(NumNOPBytes / NOPBytes);
167void RISCVAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
168 const MachineInstr &
MI) {
169 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
172 MCSymbol *MILabel = Ctx.createTempSymbol();
176 PatchPointOpers Opers(&
MI);
178 const MachineOperand &CalleeMO = Opers.getCallTarget();
179 unsigned EncodedBytes = 0;
181 if (CalleeMO.
isImm()) {
182 uint64_t CallTarget = CalleeMO.
getImm();
184 assert((CallTarget & 0xFFFF'FFFF'FFFF) == CallTarget &&
185 "High 16 bits of call target should be zero.");
189 for (MCInst &Inst : Seq) {
190 bool Compressed = EmitToStreamer(OutStreamer, Inst);
191 EncodedBytes += Compressed ? 2 : 4;
193 bool Compressed = EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
197 EncodedBytes += Compressed ? 2 : 4;
200 MCOperand CallTargetMCOp;
201 lowerOperand(CalleeMO, CallTargetMCOp);
202 EmitToStreamer(OutStreamer,
203 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
208 unsigned NumBytes = Opers.getNumPatchBytes();
209 assert(NumBytes >= EncodedBytes &&
210 "Patchpoint can't request size less than the length of a call.");
211 assert((NumBytes - EncodedBytes) % NOPBytes == 0 &&
212 "Invalid number of NOP bytes requested!");
213 emitNops((NumBytes - EncodedBytes) / NOPBytes);
216void RISCVAsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
217 const MachineInstr &
MI) {
218 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
220 StatepointOpers SOpers(&
MI);
221 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
222 assert(PatchBytes % NOPBytes == 0 &&
223 "Invalid number of NOP bytes requested!");
224 emitNops(PatchBytes / NOPBytes);
227 const MachineOperand &CallTarget = SOpers.getCallTarget();
228 MCOperand CallTargetMCOp;
229 switch (CallTarget.
getType()) {
232 lowerOperand(CallTarget, CallTargetMCOp);
235 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
239 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JAL)
245 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
257 MCSymbol *MILabel = Ctx.createTempSymbol();
262bool RISCVAsmPrinter::EmitToStreamer(MCStreamer &S,
const MCInst &Inst,
263 const MCSubtargetInfo &SubtargetInfo) {
267 ++RISCVNumInstrsCompressed;
274#include "RISCVGenMCPseudoLowering.inc"
278void RISCVAsmPrinter::emitNTLHint(
const MachineInstr *
MI) {
279 if (!STI->hasStdExtZihintntl())
282 if (
MI->memoperands_empty())
285 MachineMemOperand *MMO = *(
MI->memoperands_begin());
289 unsigned NontemporalMode = 0;
291 NontemporalMode += 0b1;
293 NontemporalMode += 0b10;
296 if (STI->hasStdExtZca())
297 Hint.setOpcode(RISCV::C_ADD);
299 Hint.setOpcode(RISCV::ADD);
305 EmitToStreamer(*OutStreamer, Hint);
308void RISCVAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
309 RISCV_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
314 if (MCInst OutInst; lowerPseudoInstExpansion(
MI, OutInst)) {
315 EmitToStreamer(*OutStreamer, OutInst);
319 switch (
MI->getOpcode()) {
320 case RISCV::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
321 LowerHWASAN_CHECK_MEMACCESS(*
MI);
323 case RISCV::KCFI_CHECK:
324 LowerKCFI_CHECK(*
MI);
326 case TargetOpcode::STACKMAP:
327 return LowerSTACKMAP(*OutStreamer, SM, *
MI);
328 case TargetOpcode::PATCHPOINT:
329 return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
330 case TargetOpcode::STATEPOINT:
331 return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
332 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
333 const Function &
F =
MI->getParent()->getParent()->getFunction();
334 if (
F.hasFnAttribute(
"patchable-function-entry")) {
336 [[maybe_unused]]
bool Result =
337 F.getFnAttribute(
"patchable-function-entry")
339 .getAsInteger(10, Num);
340 assert(!Result &&
"Enforced by the verifier");
344 LowerPATCHABLE_FUNCTION_ENTER(
MI);
347 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
348 LowerPATCHABLE_FUNCTION_EXIT(
MI);
350 case TargetOpcode::PATCHABLE_TAIL_CALL:
351 LowerPATCHABLE_TAIL_CALL(
MI);
356 lowerToMCInst(
MI, OutInst);
357 EmitToStreamer(*OutStreamer, OutInst);
360bool RISCVAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
361 const char *ExtraCode, raw_ostream &OS) {
366 const MachineOperand &MO =
MI->getOperand(OpNo);
367 if (ExtraCode && ExtraCode[0]) {
368 if (ExtraCode[1] != 0)
371 switch (ExtraCode[0]) {
389 OS <<
TRI->getEncodingValue(MO.
getReg());
402 PrintSymbolOperand(MO, OS);
416bool RISCVAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
418 const char *ExtraCode,
423 const MachineOperand &AddrReg =
MI->getOperand(OpNo);
424 assert(
MI->getNumOperands() > OpNo + 1 &&
"Expected additional operand");
425 const MachineOperand &
Offset =
MI->getOperand(OpNo + 1);
428 if (!AddrReg.
isReg())
435 if (!lowerOperand(
Offset, MCO))
441 MAI->printExpr(OS, *MCO.
getExpr());
444 MMI->getContext().registerInlineAsmLabel(
Offset.getMCSymbol());
445 if (
Offset.isBlockAddress()) {
447 MCSymbol *Sym = GetBlockAddressSymbol(BA);
448 MMI->getContext().registerInlineAsmLabel(Sym);
455bool RISCVAsmPrinter::emitDirectiveOptionArch() {
456 RISCVTargetStreamer &RTS =
459 const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
461 if (STI->hasFeature(Feature.Value) == MCSTI.
hasFeature(Feature.Value))
467 auto Delta = STI->hasFeature(Feature.Value) ? RISCVOptionArchArgType::Plus
468 : RISCVOptionArchArgType::Minus;
471 if (!NeedEmitStdOptionArgs.
empty()) {
480bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
482 RISCVTargetStreamer &RTS =
485 bool EmittedOptionArch = emitDirectiveOptionArch();
487 SetupMachineFunction(MF);
493 if (EmittedOptionArch)
494 RTS.emitDirectiveOptionPop();
498void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI) {
499 emitSled(
MI, SledKind::FUNCTION_ENTER);
502void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI) {
503 emitSled(
MI, SledKind::FUNCTION_EXIT);
506void RISCVAsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI) {
507 emitSled(
MI, SledKind::TAIL_CALL);
510void RISCVAsmPrinter::emitSled(
const MachineInstr *
MI, SledKind Kind) {
525 const uint8_t NoopsInSledCount = STI->
is64Bit() ? 33 : 21;
528 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
530 auto Target = OutContext.createTempSymbol();
538 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addExpr(TargetExpr));
541 for (int8_t
I = 0;
I < NoopsInSledCount; ++
I)
542 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
548 recordSled(CurSled, *
MI, Kind, 2);
551void RISCVAsmPrinter::emitStartOfAsmFile(
Module &M) {
553 "target streamer is uninitialized");
554 RISCVTargetStreamer &RTS =
556 if (
const MDString *ModuleTargetABI =
560 MCSubtargetInfo SubtargetInfo = *TM.getMCSubtargetInfo();
564 for (
auto &ISA : MD->operands()) {
567 ISAString->getString(),
true,
570 auto &ISAInfo = *ParseResult;
572 if (ISAInfo->hasExtension(Feature.Key) &&
583 if (TM.getTargetTriple().isOSBinFormatELF())
584 emitAttributes(SubtargetInfo);
587void RISCVAsmPrinter::emitEndOfAsmFile(
Module &M) {
588 RISCVTargetStreamer &RTS =
591 if (TM.getTargetTriple().isOSBinFormatELF()) {
593 emitNoteGnuProperty(M);
595 EmitHwasanMemaccessSymbols(M);
598void RISCVAsmPrinter::emitAttributes(
const MCSubtargetInfo &SubtargetInfo) {
599 RISCVTargetStreamer &RTS =
607void RISCVAsmPrinter::emitFunctionEntryLabel() {
608 const auto *RMFI = MF->
getInfo<RISCVMachineFunctionInfo>();
609 if (RMFI->isVectorCall()) {
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");
750 const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
753 ELF::R_RISCV_CALL_PLT, OutContext);
755 for (
auto &
P : HwasanMemaccessSymbols) {
756 unsigned Reg = std::get<0>(
P.first);
757 uint32_t AccessInfo = std::get<1>(
P.first);
775 MCInstBuilder(RISCV::SLLI).addReg(RISCV::X6).addReg(
Reg).addImm(8),
777 EmitToStreamer(*OutStreamer,
778 MCInstBuilder(RISCV::SRLI)
784 EmitToStreamer(*OutStreamer,
785 MCInstBuilder(RISCV::ADD)
792 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
797 MCInstBuilder(RISCV::SRLI).addReg(RISCV::X7).addReg(
Reg).addImm(56),
799 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
801 EmitToStreamer(*OutStreamer,
802 MCInstBuilder(RISCV::BNE)
806 HandleMismatchOrPartialSym, OutContext)),
808 MCSymbol *ReturnSym = OutContext.createTempSymbol();
810 EmitToStreamer(*OutStreamer,
811 MCInstBuilder(RISCV::JALR)
816 OutStreamer->
emitLabel(HandleMismatchOrPartialSym);
818 EmitToStreamer(*OutStreamer,
819 MCInstBuilder(RISCV::ADDI)
824 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
827 MCInstBuilder(RISCV::BGEU)
835 MCInstBuilder(RISCV::ANDI).addReg(RISCV::X28).addReg(
Reg).addImm(0xF),
839 EmitToStreamer(*OutStreamer,
840 MCInstBuilder(RISCV::ADDI)
847 MCInstBuilder(RISCV::BGE)
855 MCInstBuilder(RISCV::ORI).addReg(RISCV::X6).addReg(
Reg).addImm(0xF),
859 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
861 EmitToStreamer(*OutStreamer,
862 MCInstBuilder(RISCV::BEQ)
868 OutStreamer->
emitLabel(HandleMismatchSym);
905 EmitToStreamer(*OutStreamer,
906 MCInstBuilder(RISCV::ADDI)
913 EmitToStreamer(*OutStreamer,
914 MCInstBuilder(RISCV::SD)
920 EmitToStreamer(*OutStreamer,
921 MCInstBuilder(RISCV::SD)
930 MCInstBuilder(RISCV::SD).addReg(RISCV::X8).addReg(RISCV::X2).addImm(8 *
936 MCInstBuilder(RISCV::SD).addReg(RISCV::X1).addReg(RISCV::X2).addImm(1 *
939 if (
Reg != RISCV::X10)
942 MCInstBuilder(RISCV::ADDI).addReg(RISCV::X10).addReg(
Reg).addImm(0),
944 EmitToStreamer(*OutStreamer,
945 MCInstBuilder(RISCV::ADDI)
951 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr),
956void RISCVAsmPrinter::emitNoteGnuProperty(
const Module &M) {
957 assert(TM.getTargetTriple().isOSBinFormatELF() &&
"invalid binary format");
958 if (
const Metadata *
const Flag =
M.getModuleFlag(
"cf-protection-return");
960 RISCVTargetELFStreamer &RTS =
static_cast<RISCVTargetELFStreamer &
>(
978 Kind = ELF::R_RISCV_CALL_PLT;
984 Kind = ELF::R_RISCV_HI20;
990 Kind = ELF::R_RISCV_PCREL_HI20;
993 Kind = ELF::R_RISCV_GOT_HI20;
999 Kind = ELF::R_RISCV_TPREL_HI20;
1002 Kind = ELF::R_RISCV_TPREL_ADD;
1005 Kind = ELF::R_RISCV_TLS_GOT_HI20;
1008 Kind = ELF::R_RISCV_TLS_GD_HI20;
1011 Kind = ELF::R_RISCV_TLSDESC_HI20;
1014 Kind = ELF::R_RISCV_TLSDESC_LOAD_LO12;
1017 Kind = ELF::R_RISCV_TLSDESC_ADD_LO12;
1020 Kind = ELF::R_RISCV_TLSDESC_CALL;
1035bool RISCVAsmPrinter::lowerOperand(
const MachineOperand &MO,
1036 MCOperand &MCOp)
const {
1083 RISCVVPseudosTable::getPseudoInfo(
MI->getOpcode());
1091 assert(
TRI &&
"TargetRegisterInfo expected");
1095 unsigned NumOps =
MI->getNumExplicitOperands();
1114 bool hasVLOutput = RISCVInstrInfo::isFaultOnlyFirstLoad(*
MI);
1115 for (
unsigned OpNo = 0; OpNo !=
NumOps; ++OpNo) {
1118 if (hasVLOutput && OpNo == 1)
1122 if (OpNo ==
MI->getNumExplicitDefs() && MO.
isReg() && MO.
isTied()) {
1124 "Expected tied to first def.");
1144 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1145 assert(
Reg &&
"Subregister does not exist");
1148 TRI->getMatchingSuperReg(
Reg, RISCV::sub_16, &RISCV::FPR32RegClass);
1149 assert(
Reg &&
"Subregister does not exist");
1151 Reg =
TRI->getSubReg(
Reg, RISCV::sub_32);
1152 assert(
Reg &&
"Superregister does not exist");
1164 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1165 assert(
Reg &&
"Subregister does not exist");
1184 "Expected only mask operand to be missing");
1192void RISCVAsmPrinter::lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI) {
1198 for (
const MachineOperand &MO :
MI->operands()) {
1200 if (lowerOperand(MO, MCOp))
1205void RISCVAsmPrinter::emitMachineConstantPoolValue(
1206 MachineConstantPoolValue *MCPV) {
1207 auto *RCPV =
static_cast<RISCVConstantPoolValue *
>(MCPV);
1210 if (RCPV->isGlobalValue()) {
1211 auto *GV = RCPV->getGlobalValue();
1212 MCSym = getSymbol(GV);
1214 assert(RCPV->isExtSymbol() &&
"unrecognized constant pool type");
1215 auto Sym = RCPV->getSymbol();
1216 MCSym = GetExternalSymbolSymbol(Sym);
1220 uint64_t
Size = getDataLayout().getTypeAllocSize(RCPV->getType());
1224char RISCVAsmPrinter::ID = 0;
1226INITIALIZE_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.