49#define DEBUG_TYPE "asm-printer"
52 "Number of RISC-V Compressed instructions emitted");
64 std::unique_ptr<MCStreamer> Streamer)
67 StringRef getPassName()
const override {
return "RISC-V Assembly Printer"; }
69 RISCVTargetStreamer &getTargetStreamer()
const {
70 return static_cast<RISCVTargetStreamer &
>(
71 *OutStreamer->getTargetStreamer());
74 void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &
SM,
75 const MachineInstr &
MI);
77 void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &
SM,
78 const MachineInstr &
MI);
80 void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &
SM,
81 const MachineInstr &
MI);
83 bool runOnMachineFunction(MachineFunction &MF)
override;
87 void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV)
override;
89 bool PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
90 const char *ExtraCode, raw_ostream &OS)
override;
91 bool PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
92 const char *ExtraCode, raw_ostream &OS)
override;
95 bool EmitToStreamer(MCStreamer &S,
const MCInst &Inst,
96 const MCSubtargetInfo &SubtargetInfo);
97 bool EmitToStreamer(MCStreamer &S,
const MCInst &Inst) {
98 return EmitToStreamer(S, Inst, *STI);
101 bool lowerPseudoInstExpansion(
const MachineInstr *
MI, MCInst &Inst);
103 typedef std::tuple<unsigned, uint32_t> HwasanMemaccessTuple;
104 std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
105 void LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI);
106 void LowerKCFI_CHECK(
const MachineInstr &
MI);
107 void EmitHwasanMemaccessSymbols(
Module &M);
110 bool lowerOperand(
const MachineOperand &MO, MCOperand &MCOp)
const;
112 void emitStartOfAsmFile(
Module &M)
override;
113 void emitEndOfAsmFile(
Module &M)
override;
115 void emitFunctionEntryLabel()
override;
116 bool emitDirectiveOptionArch();
118 void emitNoteGnuProperty(
const Module &M);
121 void emitAttributes(
const MCSubtargetInfo &SubtargetInfo);
123 void emitNTLHint(
const MachineInstr *
MI);
125 void emitLpadAlignedCall(
const MachineInstr &
MI);
128 void LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI);
129 void LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI);
130 void LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI);
131 void emitSled(
const MachineInstr *
MI, SledKind Kind);
133 void lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI);
139 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
140 unsigned NumNOPBytes = StackMapOpers(&
MI).getNumPatchBytes();
143 MCSymbol *MILabel = Ctx.createTempSymbol();
146 SM.recordStackMap(*MILabel,
MI);
147 assert(NumNOPBytes % NOPBytes == 0 &&
148 "Invalid number of NOP bytes requested!");
151 const MachineBasicBlock &
MBB = *
MI.getParent();
154 while (NumNOPBytes > 0) {
155 if (MII ==
MBB.
end() || MII->isCall() ||
156 MII->getOpcode() == RISCV::DBG_VALUE ||
157 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
158 MII->getOpcode() == TargetOpcode::STACKMAP)
161 NumNOPBytes -= NOPBytes;
165 emitNops(NumNOPBytes / NOPBytes);
170void RISCVAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &
SM,
171 const MachineInstr &
MI) {
172 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
175 MCSymbol *MILabel = Ctx.createTempSymbol();
177 SM.recordPatchPoint(*MILabel,
MI);
179 PatchPointOpers Opers(&
MI);
181 const MachineOperand &CalleeMO = Opers.getCallTarget();
182 unsigned EncodedBytes = 0;
184 if (CalleeMO.
isImm()) {
185 uint64_t CallTarget = CalleeMO.
getImm();
187 assert((CallTarget & 0xFFFF'FFFF'FFFF) == CallTarget &&
188 "High 16 bits of call target should be zero.");
192 for (MCInst &Inst : Seq) {
193 bool Compressed = EmitToStreamer(OutStreamer, Inst);
194 EncodedBytes += Compressed ? 2 : 4;
196 bool Compressed = EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
200 EncodedBytes += Compressed ? 2 : 4;
203 MCOperand CallTargetMCOp;
204 lowerOperand(CalleeMO, CallTargetMCOp);
205 EmitToStreamer(OutStreamer,
206 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
211 unsigned NumBytes = Opers.getNumPatchBytes();
212 assert(NumBytes >= EncodedBytes &&
213 "Patchpoint can't request size less than the length of a call.");
214 assert((NumBytes - EncodedBytes) % NOPBytes == 0 &&
215 "Invalid number of NOP bytes requested!");
216 emitNops((NumBytes - EncodedBytes) / NOPBytes);
219void RISCVAsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &
SM,
220 const MachineInstr &
MI) {
221 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
223 StatepointOpers SOpers(&
MI);
224 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
225 assert(PatchBytes % NOPBytes == 0 &&
226 "Invalid number of NOP bytes requested!");
227 emitNops(PatchBytes / NOPBytes);
230 const MachineOperand &CallTarget = SOpers.getCallTarget();
231 MCOperand CallTargetMCOp;
232 switch (CallTarget.
getType()) {
235 lowerOperand(CallTarget, CallTargetMCOp);
238 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
242 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JAL)
248 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
260 MCSymbol *MILabel = Ctx.createTempSymbol();
262 SM.recordStatepoint(*MILabel,
MI);
265bool RISCVAsmPrinter::EmitToStreamer(MCStreamer &S,
const MCInst &Inst,
266 const MCSubtargetInfo &SubtargetInfo) {
270 ++RISCVNumInstrsCompressed;
277#include "RISCVGenMCPseudoLowering.inc"
284void RISCVAsmPrinter::emitLpadAlignedCall(
const MachineInstr &
MI) {
285 const MCSubtargetInfo &MCSTI = getSubtargetInfo();
286 const bool IsIndirect =
MI.getOpcode() == RISCV::PseudoCALLIndirectLpadAlign,
287 HasZca = MCSTI.
hasFeature(RISCV::FeatureStdExtZca),
288 HasRelax = MCSTI.
hasFeature(RISCV::FeatureRelax);
296 RISCVTargetStreamer &RTS = getTargetStreamer();
297 if (HasZca && HasRelax) {
305 lowerOperand(
MI.getOperand(0), MCOp);
306 CallInst = MCInstBuilder(RISCV::PseudoCALL).
addOperand(MCOp);
308 CallInst = MCInstBuilder(RISCV::JALR)
310 .addReg(
MI.getOperand(0).getReg())
314 if (HasZca && HasRelax) {
315 MCSubtargetInfo NoRelaxSTI(MCSTI);
316 NoRelaxSTI.ToggleFeature(RISCV::FeatureRelax);
317 EmitToStreamer(*OutStreamer, CallInst, NoRelaxSTI);
320 EmitToStreamer(*OutStreamer, CallInst, MCSTI);
324 MCInst LpadInst = MCInstBuilder(RISCV::AUIPC)
326 .addImm(
MI.getOperand(1).getImm());
327 EmitToStreamer(*OutStreamer, LpadInst, MCSTI);
336 lowerOperand(
MI.getOperand(0), MCOp);
342 EmitToStreamer(*OutStreamer, TmpInst, MCSTI);
350void RISCVAsmPrinter::emitNTLHint(
const MachineInstr *
MI) {
356 MachineMemOperand *MMO = *(
MI->memoperands_begin());
360 unsigned NontemporalMode = 0;
362 NontemporalMode += 0b1;
364 NontemporalMode += 0b10;
367 if (STI->hasStdExtZca())
368 Hint.setOpcode(RISCV::C_ADD);
370 Hint.setOpcode(RISCV::ADD);
376 EmitToStreamer(*OutStreamer, Hint);
379void RISCVAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
380 RISCV_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
385 if (MCInst OutInst; lowerPseudoInstExpansion(
MI, OutInst)) {
386 EmitToStreamer(*OutStreamer, OutInst);
390 switch (
MI->getOpcode()) {
391 case RISCV::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
392 LowerHWASAN_CHECK_MEMACCESS(*
MI);
394 case RISCV::KCFI_CHECK:
395 LowerKCFI_CHECK(*
MI);
397 case TargetOpcode::STACKMAP:
398 return LowerSTACKMAP(*OutStreamer,
SM, *
MI);
399 case TargetOpcode::PATCHPOINT:
400 return LowerPATCHPOINT(*OutStreamer,
SM, *
MI);
401 case TargetOpcode::STATEPOINT:
402 return LowerSTATEPOINT(*OutStreamer,
SM, *
MI);
403 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
404 const Function &
F =
MI->getParent()->getParent()->getFunction();
405 if (
F.hasFnAttribute(
"patchable-function-entry")) {
407 F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
411 LowerPATCHABLE_FUNCTION_ENTER(
MI);
414 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
415 LowerPATCHABLE_FUNCTION_EXIT(
MI);
417 case TargetOpcode::PATCHABLE_TAIL_CALL:
418 LowerPATCHABLE_TAIL_CALL(
MI);
420 case RISCV::PseudoCALLLpadAlign:
421 case RISCV::PseudoCALLIndirectLpadAlign:
422 emitLpadAlignedCall(*
MI);
427 lowerToMCInst(
MI, OutInst);
428 EmitToStreamer(*OutStreamer, OutInst);
431bool RISCVAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
432 const char *ExtraCode, raw_ostream &OS) {
437 const MachineOperand &MO =
MI->getOperand(OpNo);
438 if (ExtraCode && ExtraCode[0]) {
439 if (ExtraCode[1] != 0)
442 switch (ExtraCode[0]) {
460 OS <<
TRI->getEncodingValue(MO.
getReg());
473 PrintSymbolOperand(MO, OS);
487bool RISCVAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
489 const char *ExtraCode,
494 const MachineOperand &AddrReg =
MI->getOperand(OpNo);
495 assert(
MI->getNumOperands() > OpNo + 1 &&
"Expected additional operand");
496 const MachineOperand &
Offset =
MI->getOperand(OpNo + 1);
499 if (!AddrReg.
isReg())
506 if (!lowerOperand(
Offset, MCO))
512 MAI.printExpr(OS, *MCO.
getExpr());
515 MMI->getContext().registerInlineAsmLabel(
Offset.getMCSymbol());
516 if (
Offset.isBlockAddress()) {
518 MCSymbol *Sym = GetBlockAddressSymbol(BA);
519 MMI->getContext().registerInlineAsmLabel(Sym);
526bool RISCVAsmPrinter::emitDirectiveOptionArch() {
527 RISCVTargetStreamer &RTS = getTargetStreamer();
529 const MCSubtargetInfo &MCSTI = TM.getMCSubtargetInfo();
531 if (STI->hasFeature(Feature.Value) == MCSTI.
hasFeature(Feature.Value))
537 auto Delta = STI->hasFeature(Feature.Value) ? RISCVOptionArchArgType::Plus
538 : RISCVOptionArchArgType::Minus;
539 StringRef ExtName = Feature.key();
543 if (!NeedEmitStdOptionArgs.
empty()) {
552bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
554 RISCVTargetStreamer &RTS = getTargetStreamer();
556 bool EmittedOptionArch = emitDirectiveOptionArch();
558 SetupMachineFunction(MF);
564 if (EmittedOptionArch)
565 RTS.emitDirectiveOptionPop();
569void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI) {
570 emitSled(
MI, SledKind::FUNCTION_ENTER);
573void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI) {
574 emitSled(
MI, SledKind::FUNCTION_EXIT);
577void RISCVAsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI) {
578 emitSled(
MI, SledKind::TAIL_CALL);
581void RISCVAsmPrinter::emitSled(
const MachineInstr *
MI, SledKind Kind) {
596 const uint8_t NoopsInSledCount = STI->
is64Bit() ? 33 : 21;
599 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
601 auto Target = OutContext.createTempSymbol();
609 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addExpr(TargetExpr));
612 for (int8_t
I = 0;
I < NoopsInSledCount; ++
I)
613 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
619 recordSled(CurSled, *
MI, Kind, 2);
622void RISCVAsmPrinter::emitStartOfAsmFile(
Module &M) {
624 "target streamer is uninitialized");
625 RISCVTargetStreamer &RTS = getTargetStreamer();
626 if (
const MDString *ModuleTargetABI =
630 MCSubtargetInfo SubtargetInfo = TM.getMCSubtargetInfo();
634 for (
auto &ISA : MD->operands()) {
637 ISAString->getString(),
true,
640 auto &ISAInfo = *ParseResult;
642 if (ISAInfo->hasExtension(Feature.key()) &&
653 if (TM.getTargetTriple().isOSBinFormatELF())
654 emitAttributes(SubtargetInfo);
657void RISCVAsmPrinter::emitEndOfAsmFile(
Module &M) {
658 RISCVTargetStreamer &RTS = getTargetStreamer();
660 if (TM.getTargetTriple().isOSBinFormatELF()) {
662 emitNoteGnuProperty(M);
664 EmitHwasanMemaccessSymbols(M);
667void RISCVAsmPrinter::emitAttributes(
const MCSubtargetInfo &SubtargetInfo) {
668 RISCVTargetStreamer &RTS = getTargetStreamer();
675void RISCVAsmPrinter::emitFunctionEntryLabel() {
676 const auto *RMFI = MF->
getInfo<RISCVMachineFunctionInfo>();
677 if (RMFI->isVectorCall()) {
678 RISCVTargetStreamer &RTS = getTargetStreamer();
693void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
695 uint32_t AccessInfo =
MI.getOperand(1).getImm();
697 HwasanMemaccessSymbols[HwasanMemaccessTuple(
Reg, AccessInfo)];
700 if (!TM.getTargetTriple().isOSBinFormatELF())
703 std::string SymName =
"__hwasan_check_x" +
utostr(
Reg - RISCV::X0) +
"_" +
704 utostr(AccessInfo) +
"_short";
705 Sym = OutContext.getOrCreateSymbol(SymName);
710 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr));
713void RISCVAsmPrinter::LowerKCFI_CHECK(
const MachineInstr &
MI) {
715 assert(std::next(
MI.getIterator())->isCall() &&
716 "KCFI_CHECK not followed by a call instruction");
717 assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
718 "KCFI_CHECK call target doesn't match call operand");
725 unsigned ScratchRegs[] = {RISCV::X6, RISCV::X7};
726 unsigned NextReg = RISCV::X28;
727 auto isRegAvailable = [&](
unsigned Reg) {
730 for (
auto &
Reg : ScratchRegs) {
731 if (isRegAvailable(
Reg))
733 while (!isRegAvailable(NextReg))
736 if (
Reg > RISCV::X31)
740 if (AddrReg == RISCV::X0) {
743 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
744 .addReg(ScratchRegs[0])
750 int NopSize = STI->hasStdExtZca() ? 2 : 4;
752 MI.getMF()->getFunction().getFnAttributeAsParsedInteger(
753 "patchable-function-prefix");
756 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::LW)
757 .addReg(ScratchRegs[0])
759 .addImm(-(PrefixNops * NopSize + 4)));
763 const int64_t
Type =
MI.getOperand(1).getImm();
764 const int64_t Hi20 = ((
Type + 0x800) >> 12) & 0xFFFFF;
769 MCInstBuilder(RISCV::LUI).addReg(ScratchRegs[1]).addImm(Hi20));
771 if (Lo12 || Hi20 == 0) {
772 EmitToStreamer(*OutStreamer,
773 MCInstBuilder((STI->hasFeature(RISCV::Feature64Bit) && Hi20)
776 .addReg(ScratchRegs[1])
777 .addReg(ScratchRegs[1])
783 EmitToStreamer(*OutStreamer,
784 MCInstBuilder(RISCV::BEQ)
785 .addReg(ScratchRegs[0])
786 .addReg(ScratchRegs[1])
791 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::EBREAK));
792 emitKCFITrapEntry(*
MI.getMF(),
Trap);
796void RISCVAsmPrinter::EmitHwasanMemaccessSymbols(
Module &M) {
797 if (HwasanMemaccessSymbols.empty())
800 assert(TM.getTargetTriple().isOSBinFormatELF());
804 const MCSubtargetInfo &MCSTI = TM.getMCSubtargetInfo();
807 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
810 RISCVTargetStreamer &RTS = getTargetStreamer();
813 const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
818 for (
auto &
P : HwasanMemaccessSymbols) {
819 unsigned Reg = std::get<0>(
P.first);
820 uint32_t AccessInfo = std::get<1>(
P.first);
838 MCInstBuilder(RISCV::SLLI).addReg(RISCV::X6).addReg(
Reg).addImm(8),
840 EmitToStreamer(*OutStreamer,
841 MCInstBuilder(RISCV::SRLI)
847 EmitToStreamer(*OutStreamer,
848 MCInstBuilder(RISCV::ADD)
855 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
860 MCInstBuilder(RISCV::SRLI).addReg(RISCV::X7).addReg(
Reg).addImm(56),
862 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
864 EmitToStreamer(*OutStreamer,
865 MCInstBuilder(RISCV::BNE)
869 HandleMismatchOrPartialSym, OutContext)),
871 MCSymbol *ReturnSym = OutContext.createTempSymbol();
873 EmitToStreamer(*OutStreamer,
874 MCInstBuilder(RISCV::JALR)
879 OutStreamer->
emitLabel(HandleMismatchOrPartialSym);
881 EmitToStreamer(*OutStreamer,
882 MCInstBuilder(RISCV::ADDI)
887 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
890 MCInstBuilder(RISCV::BGEU)
898 MCInstBuilder(RISCV::ANDI).addReg(RISCV::X28).addReg(
Reg).addImm(0xF),
902 EmitToStreamer(*OutStreamer,
903 MCInstBuilder(RISCV::ADDI)
910 MCInstBuilder(RISCV::BGE)
918 MCInstBuilder(RISCV::ORI).addReg(RISCV::X6).addReg(
Reg).addImm(0xF),
922 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
924 EmitToStreamer(*OutStreamer,
925 MCInstBuilder(RISCV::BEQ)
931 OutStreamer->
emitLabel(HandleMismatchSym);
968 EmitToStreamer(*OutStreamer,
969 MCInstBuilder(RISCV::ADDI)
976 EmitToStreamer(*OutStreamer,
977 MCInstBuilder(RISCV::SD)
983 EmitToStreamer(*OutStreamer,
984 MCInstBuilder(RISCV::SD)
993 MCInstBuilder(RISCV::SD).addReg(RISCV::X8).addReg(RISCV::X2).addImm(8 *
999 MCInstBuilder(RISCV::SD).addReg(RISCV::X1).addReg(RISCV::X2).addImm(1 *
1002 if (
Reg != RISCV::X10)
1005 MCInstBuilder(RISCV::ADDI).addReg(RISCV::X10).addReg(
Reg).addImm(0),
1007 EmitToStreamer(*OutStreamer,
1008 MCInstBuilder(RISCV::ADDI)
1014 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr),
1019void RISCVAsmPrinter::emitNoteGnuProperty(
const Module &M) {
1020 assert(TM.getTargetTriple().isOSBinFormatELF() &&
"invalid binary format");
1021 uint32_t GnuProps = 0;
1022 if (
const Metadata *
const Flag =
M.getModuleFlag(
"cf-protection-return");
1026 if (
const Metadata *
const Flag =
M.getModuleFlag(
"cf-protection-branch");
1028 using namespace llvm::RISCVISAUtils;
1029 const Metadata *
const CFBranchLabelSchemeFlag =
1030 M.getModuleFlag(
"cf-branch-label-scheme");
1031 assert(CFBranchLabelSchemeFlag &&
1032 "cf-protection=branch should come with cf-branch-label-scheme=... "
1033 "on RISC-V targets");
1034 const StringRef CFBranchLabelScheme =
1053 auto &RTS =
static_cast<RISCVTargetELFStreamer &
>(getTargetStreamer());
1054 RTS.emitNoteGnuPropertySection(GnuProps);
1075 Kind = ELF::R_RISCV_HI20;
1090 Kind = ELF::R_RISCV_TPREL_HI20;
1093 Kind = ELF::R_RISCV_TPREL_ADD;
1096 Kind = ELF::R_RISCV_TLS_GOT_HI20;
1099 Kind = ELF::R_RISCV_TLS_GD_HI20;
1102 Kind = ELF::R_RISCV_TLSDESC_HI20;
1105 Kind = ELF::R_RISCV_TLSDESC_LOAD_LO12;
1108 Kind = ELF::R_RISCV_TLSDESC_ADD_LO12;
1111 Kind = ELF::R_RISCV_TLSDESC_CALL;
1129bool RISCVAsmPrinter::lowerOperand(
const MachineOperand &MO,
1130 MCOperand &MCOp)
const {
1177 RISCVVPseudosTable::getPseudoInfo(
MI->getOpcode());
1185 assert(
TRI &&
"TargetRegisterInfo expected");
1189 unsigned NumOps =
MI->getNumExplicitOperands();
1208 bool hasVLOutput = RISCVInstrInfo::isFaultOnlyFirstLoad(*
MI);
1209 for (
unsigned OpNo = 0; OpNo !=
NumOps; ++OpNo) {
1212 if (hasVLOutput && OpNo == 1)
1216 if (OpNo ==
MI->getNumExplicitDefs() && MO.
isReg() && MO.
isTied()) {
1218 "Expected tied to first def.");
1238 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1239 assert(
Reg &&
"Subregister does not exist");
1242 TRI->getMatchingSuperReg(
Reg, RISCV::sub_16, &RISCV::FPR32RegClass);
1243 assert(
Reg &&
"Subregister does not exist");
1245 Reg =
TRI->getSubReg(
Reg, RISCV::sub_32);
1246 assert(
Reg &&
"Superregister does not exist");
1258 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1259 assert(
Reg &&
"Subregister does not exist");
1278 "Expected only mask operand to be missing");
1286void RISCVAsmPrinter::lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI) {
1292 for (
const MachineOperand &MO :
MI->operands()) {
1294 if (lowerOperand(MO, MCOp))
1299void RISCVAsmPrinter::emitMachineConstantPoolValue(
1300 MachineConstantPoolValue *MCPV) {
1301 auto *RCPV =
static_cast<RISCVConstantPoolValue *
>(MCPV);
1304 if (RCPV->isGlobalValue()) {
1305 auto *GV = RCPV->getGlobalValue();
1306 MCSym = getSymbol(GV);
1308 assert(RCPV->isExtSymbol() &&
"unrecognized constant pool type");
1309 auto Sym = RCPV->getSymbol();
1310 MCSym = GetExternalSymbolSymbol(Sym);
1314 uint64_t
Size = getDataLayout().getTypeAllocSize(RCPV->getType());
1318char RISCVAsmPrinter::ID = 0;
1320INITIALIZE_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.
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 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)
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)
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...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ 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
Target & getTheRISCV32Target()
static const MachineMemOperand::Flags MONontemporalBit0
std::string utostr(uint64_t X, bool isNeg=false)
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 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.
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()
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,...