53#define DEBUG_TYPE "asm-printer"
56 "Number of RISC-V Compressed instructions emitted");
68 std::unique_ptr<MCStreamer> Streamer)
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);
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 emitTargetFeaturePush(
const MCSubtargetInfo &STI)
override;
121 void emitTargetFeaturePop(
const MCSubtargetInfo &STI,
bool DidPush)
override;
123 void emitNoteGnuProperty(
const Module &M);
126 void emitAttributes(
const MCSubtargetInfo &SubtargetInfo);
128 void emitNTLHint(
const MachineInstr *
MI);
130 void emitLpadAlignedCall(
const MachineInstr &
MI);
133 void LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI);
134 void LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI);
135 void LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI);
136 void emitSled(
const MachineInstr *
MI, SledKind Kind);
138 void lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI);
141 getRequiredGlobalAlignmentGranule(
const GlobalVariable &GV)
override;
147 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
148 unsigned NumNOPBytes = StackMapOpers(&
MI).getNumPatchBytes();
151 MCSymbol *MILabel = Ctx.createTempSymbol();
155 assert(NumNOPBytes % NOPBytes == 0 &&
156 "Invalid number of NOP bytes requested!");
162 while (NumNOPBytes > 0) {
163 if (MII ==
MBB.
end() || MII->isCall() ||
164 MII->getOpcode() == RISCV::DBG_VALUE ||
165 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
166 MII->getOpcode() == TargetOpcode::STACKMAP)
169 NumNOPBytes -= NOPBytes;
173 emitNops(NumNOPBytes / NOPBytes);
178void RISCVAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
179 const MachineInstr &
MI) {
180 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
183 MCSymbol *MILabel = Ctx.createTempSymbol();
187 PatchPointOpers Opers(&
MI);
189 const MachineOperand &CalleeMO = Opers.getCallTarget();
190 unsigned EncodedBytes = 0;
192 if (CalleeMO.
isImm()) {
195 assert((CallTarget & 0xFFFF'FFFF'FFFF) == CallTarget &&
196 "High 16 bits of call target should be zero.");
200 for (MCInst &Inst : Seq) {
201 bool Compressed = EmitToStreamer(OutStreamer, Inst);
202 EncodedBytes += Compressed ? 2 : 4;
204 bool Compressed = EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
208 EncodedBytes += Compressed ? 2 : 4;
211 MCOperand CallTargetMCOp;
212 lowerOperand(CalleeMO, CallTargetMCOp);
213 EmitToStreamer(OutStreamer,
214 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
219 unsigned NumBytes = Opers.getNumPatchBytes();
220 assert(NumBytes >= EncodedBytes &&
221 "Patchpoint can't request size less than the length of a call.");
222 assert((NumBytes - EncodedBytes) % NOPBytes == 0 &&
223 "Invalid number of NOP bytes requested!");
224 emitNops((NumBytes - EncodedBytes) / NOPBytes);
227void RISCVAsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
228 const MachineInstr &
MI) {
229 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
231 StatepointOpers SOpers(&
MI);
232 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
233 assert(PatchBytes % NOPBytes == 0 &&
234 "Invalid number of NOP bytes requested!");
235 emitNops(PatchBytes / NOPBytes);
238 const MachineOperand &CallTarget = SOpers.getCallTarget();
239 MCOperand CallTargetMCOp;
240 switch (CallTarget.
getType()) {
243 lowerOperand(CallTarget, CallTargetMCOp);
246 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
250 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JAL)
256 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
268 MCSymbol *MILabel = Ctx.createTempSymbol();
273bool RISCVAsmPrinter::EmitToStreamer(MCStreamer &S,
const MCInst &Inst,
274 const MCSubtargetInfo &SubtargetInfo) {
278 ++RISCVNumInstrsCompressed;
285#include "RISCVGenMCPseudoLowering.inc"
292void RISCVAsmPrinter::emitLpadAlignedCall(
const MachineInstr &
MI) {
293 const MCSubtargetInfo &MCSTI = getSubtargetInfo();
294 const bool IsIndirect =
MI.getOpcode() == RISCV::PseudoCALLIndirectLpadAlign,
295 HasZca = MCSTI.
hasFeature(RISCV::FeatureStdExtZca),
296 HasRelax = MCSTI.
hasFeature(RISCV::FeatureRelax);
304 RISCVTargetStreamer &RTS = getTargetStreamer();
305 if (HasZca && HasRelax) {
313 lowerOperand(
MI.getOperand(0), MCOp);
314 CallInst = MCInstBuilder(RISCV::PseudoCALL).
addOperand(MCOp);
316 CallInst = MCInstBuilder(RISCV::JALR)
318 .addReg(
MI.getOperand(0).getReg())
322 if (HasZca && HasRelax) {
323 MCSubtargetInfo NoRelaxSTI(MCSTI);
324 NoRelaxSTI.ToggleFeature(RISCV::FeatureRelax);
325 EmitToStreamer(*OutStreamer, CallInst, NoRelaxSTI);
328 EmitToStreamer(*OutStreamer, CallInst, MCSTI);
332 MCInst LpadInst = MCInstBuilder(RISCV::AUIPC)
334 .addImm(
MI.getOperand(1).getImm());
335 EmitToStreamer(*OutStreamer, LpadInst, MCSTI);
344 lowerOperand(
MI.getOperand(0), MCOp);
350 EmitToStreamer(*OutStreamer, TmpInst, MCSTI);
358void RISCVAsmPrinter::emitNTLHint(
const MachineInstr *
MI) {
364 MachineMemOperand *MMO = *(
MI->memoperands_begin());
368 unsigned NontemporalMode = 0;
370 NontemporalMode += 0b1;
372 NontemporalMode += 0b10;
375 if (STI->hasStdExtZca())
376 Hint.setOpcode(RISCV::C_ADD);
378 Hint.setOpcode(RISCV::ADD);
384 EmitToStreamer(*OutStreamer, Hint);
387void RISCVAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
388 RISCV_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
393 if (MCInst OutInst; lowerPseudoInstExpansion(
MI, OutInst)) {
394 EmitToStreamer(*OutStreamer, OutInst);
398 switch (
MI->getOpcode()) {
399 case RISCV::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
400 LowerHWASAN_CHECK_MEMACCESS(*
MI);
402 case RISCV::KCFI_CHECK:
403 LowerKCFI_CHECK(*
MI);
405 case TargetOpcode::STACKMAP:
406 return LowerSTACKMAP(*OutStreamer, SM, *
MI);
407 case TargetOpcode::PATCHPOINT:
408 return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
409 case TargetOpcode::STATEPOINT:
410 return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
411 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
412 const Function &
F =
MI->getParent()->getParent()->getFunction();
413 if (
F.hasFnAttribute(
"patchable-function-entry")) {
415 F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
419 LowerPATCHABLE_FUNCTION_ENTER(
MI);
422 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
423 LowerPATCHABLE_FUNCTION_EXIT(
MI);
425 case TargetOpcode::PATCHABLE_TAIL_CALL:
426 LowerPATCHABLE_TAIL_CALL(
MI);
428 case RISCV::PseudoCALLLpadAlign:
429 case RISCV::PseudoCALLIndirectLpadAlign:
430 emitLpadAlignedCall(*
MI);
435 lowerToMCInst(
MI, OutInst);
436 EmitToStreamer(*OutStreamer, OutInst);
439bool RISCVAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
440 const char *ExtraCode, raw_ostream &OS) {
445 const MachineOperand &MO =
MI->getOperand(OpNo);
446 if (ExtraCode && ExtraCode[0]) {
447 if (ExtraCode[1] != 0)
450 switch (ExtraCode[0]) {
468 OS <<
TRI->getEncodingValue(MO.
getReg());
481 PrintSymbolOperand(MO, OS);
495bool RISCVAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
497 const char *ExtraCode,
502 const MachineOperand &AddrReg =
MI->getOperand(OpNo);
503 assert(
MI->getNumOperands() > OpNo + 1 &&
"Expected additional operand");
504 const MachineOperand &
Offset =
MI->getOperand(OpNo + 1);
507 if (!AddrReg.
isReg())
514 if (!lowerOperand(
Offset, MCO))
520 MAI.printExpr(OS, *MCO.
getExpr());
523 MMI->getContext().registerInlineAsmLabel(
Offset.getMCSymbol());
524 if (
Offset.isBlockAddress()) {
526 MCSymbol *Sym = GetBlockAddressSymbol(BA);
527 MMI->getContext().registerInlineAsmLabel(Sym);
534bool RISCVAsmPrinter::emitTargetFeaturePush(
const MCSubtargetInfo &STI) {
535 RISCVTargetStreamer &RTS = getTargetStreamer();
537 const MCSubtargetInfo &MCSTI = TM.getMCSubtargetInfo();
545 auto Delta = STI.
hasFeature(Feature.Value) ? RISCVOptionArchArgType::Plus
546 : RISCVOptionArchArgType::Minus;
547 StringRef ExtName = Feature.key();
551 if (!NeedEmitStdOptionArgs.
empty()) {
560void RISCVAsmPrinter::emitTargetFeaturePop(
const MCSubtargetInfo &STI,
563 getTargetStreamer().emitDirectiveOptionPop();
569 bool EmittedOptionArch = emitTargetFeaturePush(*STI);
571 SetupMachineFunction(MF);
577 emitTargetFeaturePop(*STI, EmittedOptionArch);
581void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI) {
582 emitSled(
MI, SledKind::FUNCTION_ENTER);
585void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI) {
586 emitSled(
MI, SledKind::FUNCTION_EXIT);
589void RISCVAsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI) {
590 emitSled(
MI, SledKind::TAIL_CALL);
593void RISCVAsmPrinter::emitSled(
const MachineInstr *
MI, SledKind Kind) {
608 const uint8_t NoopsInSledCount = STI->is64Bit() ? 33 : 21;
611 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
613 auto Target = OutContext.createTempSymbol();
621 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addExpr(TargetExpr));
624 for (int8_t
I = 0;
I < NoopsInSledCount; ++
I)
625 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
631 recordSled(CurSled, *
MI, Kind, 2);
634void RISCVAsmPrinter::emitStartOfAsmFile(
Module &M) {
636 "target streamer is uninitialized");
637 RISCVTargetStreamer &RTS = getTargetStreamer();
638 if (
const MDString *ModuleTargetABI =
642 MCSubtargetInfo SubtargetInfo = TM.getMCSubtargetInfo();
646 for (
auto &ISA : MD->operands()) {
649 ISAString->getString(),
true,
652 auto &ISAInfo = *ParseResult;
654 if (ISAInfo->hasExtension(Feature.key()) &&
665 if (TM.getTargetTriple().isOSBinFormatELF())
666 emitAttributes(SubtargetInfo);
669void RISCVAsmPrinter::emitEndOfAsmFile(
Module &M) {
670 RISCVTargetStreamer &RTS = getTargetStreamer();
672 if (TM.getTargetTriple().isOSBinFormatELF()) {
674 emitNoteGnuProperty(M);
676 EmitHwasanMemaccessSymbols(M);
679void RISCVAsmPrinter::emitAttributes(
const MCSubtargetInfo &SubtargetInfo) {
680 RISCVTargetStreamer &RTS = getTargetStreamer();
687void RISCVAsmPrinter::emitFunctionEntryLabel() {
688 const auto *RMFI = MF->getInfo<RISCVMachineFunctionInfo>();
689 if (RMFI->isVectorCall()) {
690 RISCVTargetStreamer &RTS = getTargetStreamer();
705void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
707 uint32_t AccessInfo =
MI.getOperand(1).getImm();
709 HwasanMemaccessSymbols[HwasanMemaccessTuple(
Reg, AccessInfo)];
712 if (!TM.getTargetTriple().isOSBinFormatELF())
715 std::string SymName =
"__hwasan_check_x" +
utostr(
Reg - RISCV::X0) +
"_" +
716 utostr(AccessInfo) +
"_short";
717 Sym = OutContext.getOrCreateSymbol(SymName);
722 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr));
725void RISCVAsmPrinter::LowerKCFI_CHECK(
const MachineInstr &
MI) {
727 assert(std::next(
MI.getIterator())->isCall() &&
728 "KCFI_CHECK not followed by a call instruction");
729 assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
730 "KCFI_CHECK call target doesn't match call operand");
737 unsigned ScratchRegs[] = {RISCV::X6, RISCV::X7};
738 unsigned NextReg = RISCV::X28;
739 auto isRegAvailable = [&](
unsigned Reg) {
740 return Reg != AddrReg && !STI->isRegisterReservedByUser(
Reg);
742 for (
auto &
Reg : ScratchRegs) {
743 if (isRegAvailable(
Reg))
745 while (!isRegAvailable(NextReg))
748 if (
Reg > RISCV::X31)
752 if (AddrReg == RISCV::X0) {
755 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
756 .addReg(ScratchRegs[0])
762 int NopSize = STI->hasStdExtZca() ? 2 : 4;
764 MI.getMF()->getFunction().getFnAttributeAsParsedInteger(
765 "patchable-function-prefix");
768 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::LW)
769 .addReg(ScratchRegs[0])
771 .addImm(-(PrefixNops * NopSize + 4)));
775 const int64_t
Type =
MI.getOperand(1).getImm();
776 const int64_t Hi20 = ((
Type + 0x800) >> 12) & 0xFFFFF;
781 MCInstBuilder(RISCV::LUI).addReg(ScratchRegs[1]).addImm(Hi20));
783 if (Lo12 || Hi20 == 0) {
784 EmitToStreamer(*OutStreamer,
785 MCInstBuilder((STI->
hasFeature(RISCV::Feature64Bit) && Hi20)
788 .addReg(ScratchRegs[1])
789 .addReg(ScratchRegs[1])
795 EmitToStreamer(*OutStreamer,
796 MCInstBuilder(RISCV::BEQ)
797 .addReg(ScratchRegs[0])
798 .addReg(ScratchRegs[1])
803 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::EBREAK));
804 emitKCFITrapEntry(*
MI.getMF(),
Trap);
808void RISCVAsmPrinter::EmitHwasanMemaccessSymbols(
Module &M) {
809 if (HwasanMemaccessSymbols.empty())
812 assert(TM.getTargetTriple().isOSBinFormatELF());
816 const MCSubtargetInfo &MCSTI = TM.getMCSubtargetInfo();
819 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
822 RISCVTargetStreamer &RTS = getTargetStreamer();
825 const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
830 for (
auto &
P : HwasanMemaccessSymbols) {
831 unsigned Reg = std::get<0>(
P.first);
832 uint32_t AccessInfo = std::get<1>(
P.first);
850 MCInstBuilder(RISCV::SLLI).addReg(RISCV::X6).addReg(
Reg).addImm(8),
852 EmitToStreamer(*OutStreamer,
853 MCInstBuilder(RISCV::SRLI)
859 EmitToStreamer(*OutStreamer,
860 MCInstBuilder(RISCV::ADD)
867 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
872 MCInstBuilder(RISCV::SRLI).addReg(RISCV::X7).addReg(
Reg).addImm(56),
874 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
876 EmitToStreamer(*OutStreamer,
877 MCInstBuilder(RISCV::BNE)
881 HandleMismatchOrPartialSym, OutContext)),
883 MCSymbol *ReturnSym = OutContext.createTempSymbol();
885 EmitToStreamer(*OutStreamer,
886 MCInstBuilder(RISCV::JALR)
891 OutStreamer->
emitLabel(HandleMismatchOrPartialSym);
893 EmitToStreamer(*OutStreamer,
894 MCInstBuilder(RISCV::ADDI)
899 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
902 MCInstBuilder(RISCV::BGEU)
910 MCInstBuilder(RISCV::ANDI).addReg(RISCV::X28).addReg(
Reg).addImm(0xF),
914 EmitToStreamer(*OutStreamer,
915 MCInstBuilder(RISCV::ADDI)
922 MCInstBuilder(RISCV::BGE)
930 MCInstBuilder(RISCV::ORI).addReg(RISCV::X6).addReg(
Reg).addImm(0xF),
934 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
936 EmitToStreamer(*OutStreamer,
937 MCInstBuilder(RISCV::BEQ)
943 OutStreamer->
emitLabel(HandleMismatchSym);
980 EmitToStreamer(*OutStreamer,
981 MCInstBuilder(RISCV::ADDI)
988 EmitToStreamer(*OutStreamer,
989 MCInstBuilder(RISCV::SD)
995 EmitToStreamer(*OutStreamer,
996 MCInstBuilder(RISCV::SD)
1005 MCInstBuilder(RISCV::SD).addReg(RISCV::X8).addReg(RISCV::X2).addImm(8 *
1011 MCInstBuilder(RISCV::SD).addReg(RISCV::X1).addReg(RISCV::X2).addImm(1 *
1014 if (
Reg != RISCV::X10)
1017 MCInstBuilder(RISCV::ADDI).addReg(RISCV::X10).addReg(
Reg).addImm(0),
1019 EmitToStreamer(*OutStreamer,
1020 MCInstBuilder(RISCV::ADDI)
1026 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr),
1031void RISCVAsmPrinter::emitNoteGnuProperty(
const Module &M) {
1032 assert(TM.getTargetTriple().isOSBinFormatELF() &&
"invalid binary format");
1033 uint32_t GnuProps = 0;
1034 if (
const Metadata *
const Flag =
M.getModuleFlag(
"cf-protection-return");
1038 if (
const Metadata *
const Flag =
M.getModuleFlag(
"cf-protection-branch");
1040 using namespace llvm::RISCVISAUtils;
1041 const Metadata *
const CFBranchLabelSchemeFlag =
1042 M.getModuleFlag(
"cf-branch-label-scheme");
1043 assert(CFBranchLabelSchemeFlag &&
1044 "cf-protection=branch should come with cf-branch-label-scheme=... "
1045 "on RISC-V targets");
1046 const StringRef CFBranchLabelScheme =
1065 auto &RTS =
static_cast<RISCVTargetELFStreamer &
>(getTargetStreamer());
1066 RTS.emitNoteGnuPropertySection(GnuProps);
1087 Kind = ELF::R_RISCV_HI20;
1102 Kind = ELF::R_RISCV_TPREL_HI20;
1105 Kind = ELF::R_RISCV_TPREL_ADD;
1108 Kind = ELF::R_RISCV_TLS_GOT_HI20;
1111 Kind = ELF::R_RISCV_TLS_GD_HI20;
1114 Kind = ELF::R_RISCV_TLSDESC_HI20;
1117 Kind = ELF::R_RISCV_TLSDESC_LOAD_LO12;
1120 Kind = ELF::R_RISCV_TLSDESC_ADD_LO12;
1123 Kind = ELF::R_RISCV_TLSDESC_CALL;
1141bool RISCVAsmPrinter::lowerOperand(
const MachineOperand &MO,
1142 MCOperand &MCOp)
const {
1189 RISCVVPseudosTable::getPseudoInfo(
MI->getOpcode());
1197 assert(
TRI &&
"TargetRegisterInfo expected");
1201 unsigned NumOps =
MI->getNumExplicitOperands();
1220 bool hasVLOutput = RISCVInstrInfo::isFaultOnlyFirstLoad(*
MI);
1221 for (
unsigned OpNo = 0; OpNo !=
NumOps; ++OpNo) {
1224 if (hasVLOutput && OpNo == 1)
1228 if (OpNo ==
MI->getNumExplicitDefs() && MO.
isReg() && MO.
isTied()) {
1230 "Expected tied to first def.");
1250 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1251 assert(
Reg &&
"Subregister does not exist");
1254 TRI->getMatchingSuperReg(
Reg, RISCV::sub_16, &RISCV::FPR32RegClass);
1255 assert(
Reg &&
"Subregister does not exist");
1257 Reg =
TRI->getSubReg(
Reg, RISCV::sub_32);
1258 assert(
Reg &&
"Superregister does not exist");
1270 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1271 assert(
Reg &&
"Subregister does not exist");
1290 "Expected only mask operand to be missing");
1298void RISCVAsmPrinter::lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI) {
1304 for (
const MachineOperand &MO :
MI->operands()) {
1306 if (lowerOperand(MO, MCOp))
1311void RISCVAsmPrinter::emitMachineConstantPoolValue(
1312 MachineConstantPoolValue *MCPV) {
1313 auto *RCPV =
static_cast<RISCVConstantPoolValue *
>(MCPV);
1316 if (RCPV->isGlobalValue()) {
1317 auto *GV = RCPV->getGlobalValue();
1318 MCSym = getSymbol(GV);
1320 assert(RCPV->isExtSymbol() &&
"unrecognized constant pool type");
1321 auto Sym = RCPV->getSymbol();
1322 MCSym = GetExternalSymbolSymbol(Sym);
1326 uint64_t Size = getDataLayout().getTypeAllocSize(RCPV->getType());
1331RISCVAsmPrinter::getRequiredGlobalAlignmentGranule(
const GlobalVariable &GV) {
1332 const MCSubtargetInfo &MCSTI = TM.getMCSubtargetInfo();
1334 return std::nullopt;
1337 if (MCSTI.
hasFeature(RISCV::FeatureVendorXCheriot))
1338 return CHERIoTCapabilityFormat::getRequiredAlignment(
Size);
1340 if (MCSTI.
hasFeature(RISCV::FeatureStdExtY)) {
1347 return std::nullopt;
1350char RISCVAsmPrinter::ID = 0;
1357 RISCVAsmPrinter &
AsmPrinter =
static_cast<RISCVAsmPrinter &
>(
1367 RISCVAsmPrinter &
AsmPrinter =
static_cast<RISCVAsmPrinter &
>(
1378 RISCVAsmPrinter &
AsmPrinter =
static_cast<RISCVAsmPrinter &
>(
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 const Function * getParent(const Value *V)
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
ModuleAnalysisManager MAM
#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")
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class is intended to be used as a driving class for all asm writers.
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
MCContext & OutContext
This is the context for the output file that we are streaming.
bool doFinalization(Module &M) override
Shut down the asmprinter.
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
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.
Type * getValueType() const
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
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.
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo &STI, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText.
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 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.
ArrayRef< SubtargetFeatureKV > getAllProcessorFeatures() const
Return processor features.
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 MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
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.
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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.
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)
virtual void emitDirectiveOptionExact()
virtual void emitDirectiveOptionPop()
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.
std::string str() const
Get the contents as an std::string.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
TargetInstrInfo - Interface to description of machine instruction set.
Primary interface to the complete machine description for the target machine.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
#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_LP_UNLABELED
@ GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS
ABI getTargetABI(StringRef ABIName)
ZicfilpLabelSchemeKind getZicfilpLabelScheme(const StringRef CFBranchLabelScheme)
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
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
Target & getTheRISCV32Target()
static const MachineMemOperand::Flags MONontemporalBit0
std::string utostr(uint64_t X, bool isNeg=false)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
Target & getTheRISCV64beTarget()
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI void setupModuleAsmPrinter(Module &M, ModuleAnalysisManager &MAM, AsmPrinter &AsmPrinter)
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.
LLVM_ABI void setupMachineFunctionAsmPrinter(MachineFunctionAnalysisManager &MFAM, MachineFunction &MF, AsmPrinter &AsmPrinter)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
@ MCSA_Hidden
.hidden (ELF)
Target & getTheRISCV32beTarget()
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Implement std::hash so that hash_code can be used in STL containers.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...