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();
1104 bool hasVLOutput = RISCVInstrInfo::isFaultOnlyFirstLoad(*
MI);
1105 for (
unsigned OpNo = 0; OpNo !=
NumOps; ++OpNo) {
1108 if (hasVLOutput && OpNo == 1)
1112 if (OpNo ==
MI->getNumExplicitDefs() && MO.
isReg() && MO.
isTied()) {
1114 "Expected tied to first def.");
1134 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1135 assert(
Reg &&
"Subregister does not exist");
1138 TRI->getMatchingSuperReg(
Reg, RISCV::sub_16, &RISCV::FPR32RegClass);
1139 assert(
Reg &&
"Subregister does not exist");
1141 Reg =
TRI->getSubReg(
Reg, RISCV::sub_32);
1142 assert(
Reg &&
"Superregister does not exist");
1154 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1155 assert(
Reg &&
"Subregister does not exist");
1173 RISCV::VMV0RegClassID &&
1174 "Expected only mask operand to be missing");
1182void RISCVAsmPrinter::lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI) {
1188 for (
const MachineOperand &MO :
MI->operands()) {
1190 if (lowerOperand(MO, MCOp))
1195void RISCVAsmPrinter::emitMachineConstantPoolValue(
1196 MachineConstantPoolValue *MCPV) {
1197 auto *RCPV =
static_cast<RISCVConstantPoolValue *
>(MCPV);
1200 if (RCPV->isGlobalValue()) {
1201 auto *GV = RCPV->getGlobalValue();
1202 MCSym = getSymbol(GV);
1204 assert(RCPV->isExtSymbol() &&
"unrecognized constant pool type");
1205 auto Sym = RCPV->getSymbol();
1206 MCSym = GetExternalSymbolSymbol(Sym);
1210 uint64_t
Size = getDataLayout().getTypeAllocSize(RCPV->getType());
1214char RISCVAsmPrinter::ID = 0;
1216INITIALIZE_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)
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 isTiedPseudo(uint64_t TSFlags)
static bool hasVLOp(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.