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 emitNTLHint(
const MachineInstr *
MI);
128 void emitLpadAlignedCall(
const MachineInstr &
MI);
131 void LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI);
132 void LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI);
133 void LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI);
134 void emitSled(
const MachineInstr *
MI, SledKind Kind);
136 void lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI);
139 getRequiredGlobalAlignmentGranule(
const GlobalVariable &GV)
override;
145 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
146 unsigned NumNOPBytes = StackMapOpers(&
MI).getNumPatchBytes();
149 MCSymbol *MILabel = Ctx.createTempSymbol();
153 assert(NumNOPBytes % NOPBytes == 0 &&
154 "Invalid number of NOP bytes requested!");
160 while (NumNOPBytes > 0) {
161 if (MII ==
MBB.
end() || MII->isCall() ||
162 MII->getOpcode() == RISCV::DBG_VALUE ||
163 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
164 MII->getOpcode() == TargetOpcode::STACKMAP)
167 NumNOPBytes -= NOPBytes;
171 emitNops(NumNOPBytes / NOPBytes);
176void RISCVAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
177 const MachineInstr &
MI) {
178 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
181 MCSymbol *MILabel = Ctx.createTempSymbol();
185 PatchPointOpers Opers(&
MI);
187 const MachineOperand &CalleeMO = Opers.getCallTarget();
188 unsigned EncodedBytes = 0;
190 if (CalleeMO.
isImm()) {
193 assert((CallTarget & 0xFFFF'FFFF'FFFF) == CallTarget &&
194 "High 16 bits of call target should be zero.");
198 for (MCInst &Inst : Seq) {
199 bool Compressed = EmitToStreamer(OutStreamer, Inst);
200 EncodedBytes += Compressed ? 2 : 4;
202 bool Compressed = EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
206 EncodedBytes += Compressed ? 2 : 4;
209 MCOperand CallTargetMCOp;
210 lowerOperand(CalleeMO, CallTargetMCOp);
211 EmitToStreamer(OutStreamer,
212 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
217 unsigned NumBytes = Opers.getNumPatchBytes();
218 assert(NumBytes >= EncodedBytes &&
219 "Patchpoint can't request size less than the length of a call.");
220 assert((NumBytes - EncodedBytes) % NOPBytes == 0 &&
221 "Invalid number of NOP bytes requested!");
222 emitNops((NumBytes - EncodedBytes) / NOPBytes);
225void RISCVAsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
226 const MachineInstr &
MI) {
227 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
229 StatepointOpers SOpers(&
MI);
230 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
231 assert(PatchBytes % NOPBytes == 0 &&
232 "Invalid number of NOP bytes requested!");
233 emitNops(PatchBytes / NOPBytes);
236 const MachineOperand &CallTarget = SOpers.getCallTarget();
237 MCOperand CallTargetMCOp;
238 switch (CallTarget.
getType()) {
241 lowerOperand(CallTarget, CallTargetMCOp);
244 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
248 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JAL)
254 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
266 MCSymbol *MILabel = Ctx.createTempSymbol();
271bool RISCVAsmPrinter::EmitToStreamer(MCStreamer &S,
const MCInst &Inst,
272 const MCSubtargetInfo &SubtargetInfo) {
276 ++RISCVNumInstrsCompressed;
283#include "RISCVGenMCPseudoLowering.inc"
290void RISCVAsmPrinter::emitLpadAlignedCall(
const MachineInstr &
MI) {
291 const MCSubtargetInfo &MCSTI = getSubtargetInfo();
292 const bool IsIndirect =
MI.getOpcode() == RISCV::PseudoCALLIndirectLpadAlign,
293 HasZca = MCSTI.
hasFeature(RISCV::FeatureStdExtZca),
294 HasRelax = MCSTI.
hasFeature(RISCV::FeatureRelax);
302 RISCVTargetStreamer &RTS = getTargetStreamer();
303 if (HasZca && HasRelax) {
311 lowerOperand(
MI.getOperand(0), MCOp);
312 CallInst = MCInstBuilder(RISCV::PseudoCALL).
addOperand(MCOp);
314 CallInst = MCInstBuilder(RISCV::JALR)
316 .addReg(
MI.getOperand(0).getReg())
320 if (HasZca && HasRelax) {
321 MCSubtargetInfo NoRelaxSTI(MCSTI);
322 NoRelaxSTI.ToggleFeature(RISCV::FeatureRelax);
323 EmitToStreamer(*OutStreamer, CallInst, NoRelaxSTI);
326 EmitToStreamer(*OutStreamer, CallInst, MCSTI);
330 MCInst LpadInst = MCInstBuilder(RISCV::AUIPC)
332 .addImm(
MI.getOperand(1).getImm());
333 EmitToStreamer(*OutStreamer, LpadInst, MCSTI);
342 lowerOperand(
MI.getOperand(0), MCOp);
348 EmitToStreamer(*OutStreamer, TmpInst, MCSTI);
356void RISCVAsmPrinter::emitNTLHint(
const MachineInstr *
MI) {
362 MachineMemOperand *MMO = *(
MI->memoperands_begin());
366 unsigned NontemporalMode = 0;
368 NontemporalMode += 0b1;
370 NontemporalMode += 0b10;
373 if (STI->hasStdExtZca())
374 Hint.setOpcode(RISCV::C_ADD);
376 Hint.setOpcode(RISCV::ADD);
382 EmitToStreamer(*OutStreamer, Hint);
385void RISCVAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
386 RISCV_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
391 if (MCInst OutInst; lowerPseudoInstExpansion(
MI, OutInst)) {
392 EmitToStreamer(*OutStreamer, OutInst);
396 switch (
MI->getOpcode()) {
397 case RISCV::PseudoTAILX7: {
400 lowerOperand(
MI->getOperand(0), SymOp);
405 EmitToStreamer(*OutStreamer, TmpInst);
408 case RISCV::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
409 LowerHWASAN_CHECK_MEMACCESS(*
MI);
411 case RISCV::KCFI_CHECK:
412 LowerKCFI_CHECK(*
MI);
414 case TargetOpcode::STACKMAP:
415 return LowerSTACKMAP(*OutStreamer, SM, *
MI);
416 case TargetOpcode::PATCHPOINT:
417 return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
418 case TargetOpcode::STATEPOINT:
419 return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
420 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
421 const Function &
F =
MI->getParent()->getParent()->getFunction();
422 if (
F.hasFnAttribute(
"patchable-function-entry")) {
424 F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
428 LowerPATCHABLE_FUNCTION_ENTER(
MI);
431 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
432 LowerPATCHABLE_FUNCTION_EXIT(
MI);
434 case TargetOpcode::PATCHABLE_TAIL_CALL:
435 LowerPATCHABLE_TAIL_CALL(
MI);
437 case RISCV::PseudoCALLLpadAlign:
438 case RISCV::PseudoCALLIndirectLpadAlign:
439 emitLpadAlignedCall(*
MI);
444 lowerToMCInst(
MI, OutInst);
445 EmitToStreamer(*OutStreamer, OutInst);
448bool RISCVAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
449 const char *ExtraCode, raw_ostream &OS) {
454 const MachineOperand &MO =
MI->getOperand(OpNo);
455 if (ExtraCode && ExtraCode[0]) {
456 if (ExtraCode[1] != 0)
459 switch (ExtraCode[0]) {
477 OS <<
TRI->getEncodingValue(MO.
getReg());
490 PrintSymbolOperand(MO, OS);
504bool RISCVAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
506 const char *ExtraCode,
511 const MachineOperand &AddrReg =
MI->getOperand(OpNo);
512 assert(
MI->getNumOperands() > OpNo + 1 &&
"Expected additional operand");
513 const MachineOperand &
Offset =
MI->getOperand(OpNo + 1);
516 if (!AddrReg.
isReg())
523 if (!lowerOperand(
Offset, MCO))
529 MAI.printExpr(OS, *MCO.
getExpr());
532 MMI->getContext().registerInlineAsmLabel(
Offset.getMCSymbol());
533 if (
Offset.isBlockAddress()) {
535 MCSymbol *Sym = GetBlockAddressSymbol(BA);
536 MMI->getContext().registerInlineAsmLabel(Sym);
543bool RISCVAsmPrinter::emitTargetFeaturePush(
const MCSubtargetInfo &STI) {
544 RISCVTargetStreamer &RTS = getTargetStreamer();
546 const MCSubtargetInfo &MCSTI = TM.getMCSubtargetInfo();
554 auto Delta = STI.
hasFeature(Feature.Value) ? RISCVOptionArchArgType::Plus
555 : RISCVOptionArchArgType::Minus;
556 StringRef ExtName = Feature.key();
560 if (!NeedEmitStdOptionArgs.
empty()) {
571void RISCVAsmPrinter::emitTargetFeaturePop(
const MCSubtargetInfo &STI,
574 getTargetStreamer().emitDirectiveOptionPop();
580 bool EmittedOptionArch = emitTargetFeaturePush(*STI);
582 SetupMachineFunction(MF);
588 emitTargetFeaturePop(*STI, EmittedOptionArch);
592void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI) {
593 emitSled(
MI, SledKind::FUNCTION_ENTER);
596void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI) {
597 emitSled(
MI, SledKind::FUNCTION_EXIT);
600void RISCVAsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI) {
601 emitSled(
MI, SledKind::TAIL_CALL);
604void RISCVAsmPrinter::emitSled(
const MachineInstr *
MI, SledKind Kind) {
619 const uint8_t NoopsInSledCount = STI->is64Bit() ? 33 : 21;
622 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
624 auto Target = OutContext.createTempSymbol();
632 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addExpr(TargetExpr));
635 for (int8_t
I = 0;
I < NoopsInSledCount; ++
I)
636 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
642 recordSled(CurSled, *
MI, Kind, 2);
645void RISCVAsmPrinter::emitStartOfAsmFile(
Module &M) {
647 "target streamer is uninitialized");
648 RISCVTargetStreamer &RTS = getTargetStreamer();
649 StringRef ABIName =
M.getTargetABIFromMD();
650 if (!ABIName.
empty()) {
653 M.getContext().emitError(Twine(
'\'') + ABIName +
654 "' is not a recognized ABI for this target");
663 MCSubtargetInfo SubtargetInfo = TM.getMCSubtargetInfo();
667 for (
auto &ISA : MD->operands()) {
670 ISAString->getString(),
true,
673 auto &ISAInfo = *ParseResult;
675 if (ISAInfo->hasExtension(Feature.key()) &&
686 if (
M.getTargetTriple().isOSBinFormatELF())
690void RISCVAsmPrinter::emitEndOfAsmFile(
Module &M) {
691 RISCVTargetStreamer &RTS = getTargetStreamer();
693 if (
M.getTargetTriple().isOSBinFormatELF()) {
695 emitNoteGnuProperty(M);
697 EmitHwasanMemaccessSymbols(M);
700void RISCVAsmPrinter::emitFunctionEntryLabel() {
701 const auto *RMFI = MF->getInfo<RISCVMachineFunctionInfo>();
702 if (RMFI->isVectorCall()) {
703 RISCVTargetStreamer &RTS = getTargetStreamer();
718void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
720 uint32_t AccessInfo =
MI.getOperand(1).getImm();
722 HwasanMemaccessSymbols[HwasanMemaccessTuple(
Reg, AccessInfo)];
725 if (!TM.getTargetTriple().isOSBinFormatELF())
728 std::string SymName =
"__hwasan_check_x" +
utostr(
Reg - RISCV::X0) +
"_" +
729 utostr(AccessInfo) +
"_short";
730 Sym = OutContext.getOrCreateSymbol(SymName);
735 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr));
738void RISCVAsmPrinter::LowerKCFI_CHECK(
const MachineInstr &
MI) {
740 assert(std::next(
MI.getIterator())->isCall() &&
741 "KCFI_CHECK not followed by a call instruction");
742 assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
743 "KCFI_CHECK call target doesn't match call operand");
750 unsigned ScratchRegs[] = {RISCV::X6, RISCV::X7};
751 unsigned NextReg = RISCV::X28;
752 auto isRegAvailable = [&](
unsigned Reg) {
753 return Reg != AddrReg && !STI->isRegisterReservedByUser(
Reg);
755 for (
auto &
Reg : ScratchRegs) {
756 if (isRegAvailable(
Reg))
758 while (!isRegAvailable(NextReg))
761 if (
Reg > RISCV::X31)
765 if (AddrReg == RISCV::X0) {
768 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
769 .addReg(ScratchRegs[0])
775 int NopSize = STI->hasStdExtZca() ? 2 : 4;
777 MI.getMF()->getFunction().getFnAttributeAsParsedInteger(
778 "patchable-function-prefix");
781 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::LW)
782 .addReg(ScratchRegs[0])
784 .addImm(-(PrefixNops * NopSize + 4)));
788 const int64_t
Type =
MI.getOperand(1).getImm();
789 const int64_t Hi20 = ((
Type + 0x800) >> 12) & 0xFFFFF;
794 MCInstBuilder(RISCV::LUI).addReg(ScratchRegs[1]).addImm(Hi20));
796 if (Lo12 || Hi20 == 0) {
797 EmitToStreamer(*OutStreamer,
798 MCInstBuilder((STI->
hasFeature(RISCV::Feature64Bit) && Hi20)
801 .addReg(ScratchRegs[1])
802 .addReg(ScratchRegs[1])
808 EmitToStreamer(*OutStreamer,
809 MCInstBuilder(RISCV::BEQ)
810 .addReg(ScratchRegs[0])
811 .addReg(ScratchRegs[1])
816 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::EBREAK));
817 emitKCFITrapEntry(*
MI.getMF(),
Trap);
821void RISCVAsmPrinter::EmitHwasanMemaccessSymbols(
Module &M) {
822 if (HwasanMemaccessSymbols.empty())
825 assert(
M.getTargetTriple().isOSBinFormatELF());
829 const MCSubtargetInfo &MCSTI = TM.getMCSubtargetInfo();
832 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
835 RISCVTargetStreamer &RTS = getTargetStreamer();
838 const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
843 for (
auto &
P : HwasanMemaccessSymbols) {
844 unsigned Reg = std::get<0>(
P.first);
845 uint32_t AccessInfo = std::get<1>(
P.first);
863 MCInstBuilder(RISCV::SLLI).addReg(RISCV::X6).addReg(
Reg).addImm(8),
865 EmitToStreamer(*OutStreamer,
866 MCInstBuilder(RISCV::SRLI)
872 EmitToStreamer(*OutStreamer,
873 MCInstBuilder(RISCV::ADD)
880 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
885 MCInstBuilder(RISCV::SRLI).addReg(RISCV::X7).addReg(
Reg).addImm(56),
887 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
889 EmitToStreamer(*OutStreamer,
890 MCInstBuilder(RISCV::BNE)
894 HandleMismatchOrPartialSym, OutContext)),
896 MCSymbol *ReturnSym = OutContext.createTempSymbol();
898 EmitToStreamer(*OutStreamer,
899 MCInstBuilder(RISCV::JALR)
904 OutStreamer->
emitLabel(HandleMismatchOrPartialSym);
906 EmitToStreamer(*OutStreamer,
907 MCInstBuilder(RISCV::ADDI)
912 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
915 MCInstBuilder(RISCV::BGEU)
923 MCInstBuilder(RISCV::ANDI).addReg(RISCV::X28).addReg(
Reg).addImm(0xF),
927 EmitToStreamer(*OutStreamer,
928 MCInstBuilder(RISCV::ADDI)
935 MCInstBuilder(RISCV::BGE)
943 MCInstBuilder(RISCV::ORI).addReg(RISCV::X6).addReg(
Reg).addImm(0xF),
947 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
949 EmitToStreamer(*OutStreamer,
950 MCInstBuilder(RISCV::BEQ)
956 OutStreamer->
emitLabel(HandleMismatchSym);
993 EmitToStreamer(*OutStreamer,
994 MCInstBuilder(RISCV::ADDI)
1001 EmitToStreamer(*OutStreamer,
1002 MCInstBuilder(RISCV::SD)
1008 EmitToStreamer(*OutStreamer,
1009 MCInstBuilder(RISCV::SD)
1018 MCInstBuilder(RISCV::SD).addReg(RISCV::X8).addReg(RISCV::X2).addImm(8 *
1024 MCInstBuilder(RISCV::SD).addReg(RISCV::X1).addReg(RISCV::X2).addImm(1 *
1027 if (
Reg != RISCV::X10)
1030 MCInstBuilder(RISCV::ADDI).addReg(RISCV::X10).addReg(
Reg).addImm(0),
1032 EmitToStreamer(*OutStreamer,
1033 MCInstBuilder(RISCV::ADDI)
1039 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr),
1044void RISCVAsmPrinter::emitNoteGnuProperty(
const Module &M) {
1045 assert(
M.getTargetTriple().isOSBinFormatELF() &&
"invalid binary format");
1046 uint32_t GnuProps = 0;
1047 if (
const Metadata *
const Flag =
M.getModuleFlag(
"cf-protection-return");
1051 if (
const Metadata *
const Flag =
M.getModuleFlag(
"cf-protection-branch");
1053 using namespace llvm::RISCVISAUtils;
1054 const Metadata *
const CFBranchLabelSchemeFlag =
1055 M.getModuleFlag(
"cf-branch-label-scheme");
1056 assert(CFBranchLabelSchemeFlag &&
1057 "cf-protection=branch should come with cf-branch-label-scheme=... "
1058 "on RISC-V targets");
1059 const StringRef CFBranchLabelScheme =
1078 auto &RTS =
static_cast<RISCVTargetELFStreamer &
>(getTargetStreamer());
1079 RTS.emitNoteGnuPropertySection(GnuProps);
1100 Kind = ELF::R_RISCV_HI20;
1115 Kind = ELF::R_RISCV_TPREL_HI20;
1118 Kind = ELF::R_RISCV_TPREL_ADD;
1121 Kind = ELF::R_RISCV_TLS_GOT_HI20;
1124 Kind = ELF::R_RISCV_TLS_GD_HI20;
1127 Kind = ELF::R_RISCV_TLSDESC_HI20;
1130 Kind = ELF::R_RISCV_TLSDESC_LOAD_LO12;
1133 Kind = ELF::R_RISCV_TLSDESC_ADD_LO12;
1136 Kind = ELF::R_RISCV_TLSDESC_CALL;
1154bool RISCVAsmPrinter::lowerOperand(
const MachineOperand &MO,
1155 MCOperand &MCOp)
const {
1202 RISCVVPseudosTable::getPseudoInfo(
MI->getOpcode());
1210 assert(
TRI &&
"TargetRegisterInfo expected");
1214 unsigned NumOps =
MI->getNumExplicitOperands();
1233 bool hasVLOutput = RISCVInstrInfo::isFaultOnlyFirstLoad(*
MI);
1234 for (
unsigned OpNo = 0; OpNo !=
NumOps; ++OpNo) {
1237 if (hasVLOutput && OpNo == 1)
1241 if (OpNo ==
MI->getNumExplicitDefs() && MO.
isReg() && MO.
isTied()) {
1243 "Expected tied to first def.");
1263 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1264 assert(
Reg &&
"Subregister does not exist");
1267 TRI->getMatchingSuperReg(
Reg, RISCV::sub_16, &RISCV::FPR32RegClass);
1268 assert(
Reg &&
"Subregister does not exist");
1270 Reg =
TRI->getSubReg(
Reg, RISCV::sub_32);
1271 assert(
Reg &&
"Superregister does not exist");
1283 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1284 assert(
Reg &&
"Subregister does not exist");
1303 "Expected only mask operand to be missing");
1311void RISCVAsmPrinter::lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI) {
1317 for (
const MachineOperand &MO :
MI->operands()) {
1319 if (lowerOperand(MO, MCOp))
1324void RISCVAsmPrinter::emitMachineConstantPoolValue(
1325 MachineConstantPoolValue *MCPV) {
1326 auto *RCPV =
static_cast<RISCVConstantPoolValue *
>(MCPV);
1329 if (RCPV->isGlobalValue()) {
1330 auto *GV = RCPV->getGlobalValue();
1331 MCSym = getSymbol(GV);
1333 assert(RCPV->isExtSymbol() &&
"unrecognized constant pool type");
1334 auto Sym = RCPV->getSymbol();
1335 MCSym = GetExternalSymbolSymbol(Sym);
1339 uint64_t Size = getDataLayout().getTypeAllocSize(RCPV->getType());
1344RISCVAsmPrinter::getRequiredGlobalAlignmentGranule(
const GlobalVariable &GV) {
1345 const MCSubtargetInfo &MCSTI = TM.getMCSubtargetInfo();
1347 return std::nullopt;
1354 return std::nullopt;
1357 if (MCSTI.
hasFeature(RISCV::FeatureVendorXCheriot))
1358 return CHERIoTCapabilityFormat::getRequiredAlignment(
Size);
1360 if (MCSTI.
hasFeature(RISCV::FeatureStdExtY)) {
1367 return std::nullopt;
1370char RISCVAsmPrinter::ID = 0;
1377 RISCVAsmPrinter &
AsmPrinter =
static_cast<RISCVAsmPrinter &
>(
1387 RISCVAsmPrinter &
AsmPrinter =
static_cast<RISCVAsmPrinter &
>(
1398 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)
std::unique_ptr< MCStreamer > && Streamer
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.
bool hasSection() const
Check if this global has a custom object file section.
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 setArchString(StringRef Arch)
virtual void emitDirectiveVariantCC(MCSymbol &Symbol)
void emitTargetAttributes(const MCSubtargetInfo &STI, bool EmitStackAlign)
virtual 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()
bool hasTargetABI() const
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.
constexpr bool empty() const
Check if the string is empty.
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() 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)
Expected< ABI > computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName)
ZicfilpLabelSchemeKind getZicfilpLabelScheme(const StringRef CFBranchLabelScheme)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(const MCSubtargetInfo &STI)
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...
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Target & getTheRISCV64Target()
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
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,...