53#define DEBUG_TYPE "asm-printer"
56 "Number of RISC-V Compressed instructions emitted");
64 const RISCVMCOptions &CLOpts;
69 std::unique_ptr<MCStreamer>
Streamer)
73 StringRef getPassName()
const override {
return "RISC-V Assembly Printer"; }
75 RISCVTargetStreamer &getTargetStreamer()
const {
76 return static_cast<RISCVTargetStreamer &
>(
77 *OutStreamer->getTargetStreamer());
80 void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
81 const MachineInstr &
MI);
83 void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
84 const MachineInstr &
MI);
86 void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
87 const MachineInstr &
MI);
93 void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV)
override;
95 bool PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
96 const char *ExtraCode, raw_ostream &OS)
override;
97 bool PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
98 const char *ExtraCode, raw_ostream &OS)
override;
101 bool EmitToStreamer(MCStreamer &S,
const MCInst &Inst,
102 const MCSubtargetInfo &SubtargetInfo);
103 bool EmitToStreamer(MCStreamer &S,
const MCInst &Inst) {
104 return EmitToStreamer(S, Inst, *STI);
107 bool lowerPseudoInstExpansion(
const MachineInstr *
MI, MCInst &Inst);
109 typedef std::tuple<unsigned, uint32_t> HwasanMemaccessTuple;
110 std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
111 void LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI);
112 void LowerKCFI_CHECK(
const MachineInstr &
MI);
113 void EmitHwasanMemaccessSymbols(
Module &M);
116 bool lowerOperand(
const MachineOperand &MO, MCOperand &MCOp)
const;
118 void emitStartOfAsmFile(
Module &M)
override;
119 void emitEndOfAsmFile(
Module &M)
override;
121 void emitFunctionEntryLabel()
override;
122 bool emitTargetFeaturePush(
const MCSubtargetInfo &STI)
override;
123 void emitTargetFeaturePop(
const MCSubtargetInfo &STI,
bool DidPush)
override;
125 void emitNoteGnuProperty(
const Module &M);
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->isDebugInstr()) {
167 if (MII ==
MBB.
end() || MII->isCall() ||
168 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
169 MII->getOpcode() == TargetOpcode::STACKMAP)
172 NumNOPBytes -= NOPBytes;
176 emitNops(NumNOPBytes / NOPBytes);
181void RISCVAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
182 const MachineInstr &
MI) {
183 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
186 MCSymbol *MILabel = Ctx.createTempSymbol();
190 PatchPointOpers Opers(&
MI);
192 const MachineOperand &CalleeMO = Opers.getCallTarget();
193 unsigned EncodedBytes = 0;
195 if (CalleeMO.
isImm()) {
198 assert((CallTarget & 0xFFFF'FFFF'FFFF) == CallTarget &&
199 "High 16 bits of call target should be zero.");
203 for (MCInst &Inst : Seq) {
204 bool Compressed = EmitToStreamer(OutStreamer, Inst);
205 EncodedBytes += Compressed ? 2 : 4;
207 bool Compressed = EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
211 EncodedBytes += Compressed ? 2 : 4;
214 MCOperand CallTargetMCOp;
215 lowerOperand(CalleeMO, CallTargetMCOp);
216 EmitToStreamer(OutStreamer,
217 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
222 unsigned NumBytes = Opers.getNumPatchBytes();
223 assert(NumBytes >= EncodedBytes &&
224 "Patchpoint can't request size less than the length of a call.");
225 assert((NumBytes - EncodedBytes) % NOPBytes == 0 &&
226 "Invalid number of NOP bytes requested!");
227 emitNops((NumBytes - EncodedBytes) / NOPBytes);
230void RISCVAsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
231 const MachineInstr &
MI) {
232 unsigned NOPBytes = STI->hasStdExtZca() ? 2 : 4;
234 StatepointOpers SOpers(&
MI);
235 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
236 assert(PatchBytes % NOPBytes == 0 &&
237 "Invalid number of NOP bytes requested!");
238 emitNops(PatchBytes / NOPBytes);
241 const MachineOperand &CallTarget = SOpers.getCallTarget();
242 MCOperand CallTargetMCOp;
243 switch (CallTarget.
getType()) {
246 lowerOperand(CallTarget, CallTargetMCOp);
249 MCInstBuilder(RISCV::PseudoCALL).
addOperand(CallTargetMCOp));
253 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JAL)
259 EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
271 MCSymbol *MILabel = Ctx.createTempSymbol();
276bool RISCVAsmPrinter::EmitToStreamer(MCStreamer &S,
const MCInst &Inst,
277 const MCSubtargetInfo &SubtargetInfo) {
281 ++RISCVNumInstrsCompressed;
288#include "RISCVGenMCPseudoLowering.inc"
295void RISCVAsmPrinter::emitLpadAlignedCall(
const MachineInstr &
MI) {
296 const MCSubtargetInfo &MCSTI = getSubtargetInfo();
297 const bool IsIndirect =
MI.getOpcode() == RISCV::PseudoCALLIndirectLpadAlign,
298 HasZca = MCSTI.
hasFeature(RISCV::FeatureStdExtZca),
299 HasRelax = MCSTI.
hasFeature(RISCV::FeatureRelax);
307 RISCVTargetStreamer &RTS = getTargetStreamer();
308 if (HasZca && HasRelax) {
316 lowerOperand(
MI.getOperand(0), MCOp);
317 CallInst = MCInstBuilder(RISCV::PseudoCALL).
addOperand(MCOp);
319 CallInst = MCInstBuilder(RISCV::JALR)
321 .addReg(
MI.getOperand(0).getReg())
325 if (HasZca && HasRelax) {
326 MCSubtargetInfo NoRelaxSTI(MCSTI);
327 NoRelaxSTI.ToggleFeature(RISCV::FeatureRelax);
328 EmitToStreamer(*OutStreamer, CallInst, NoRelaxSTI);
331 EmitToStreamer(*OutStreamer, CallInst, MCSTI);
335 MCInst LpadInst = MCInstBuilder(RISCV::AUIPC)
337 .addImm(
MI.getOperand(1).getImm());
338 EmitToStreamer(*OutStreamer, LpadInst, MCSTI);
347 lowerOperand(
MI.getOperand(0), MCOp);
353 EmitToStreamer(*OutStreamer, TmpInst, MCSTI);
361void RISCVAsmPrinter::emitNTLHint(
const MachineInstr *
MI) {
367 MachineMemOperand *MMO = *(
MI->memoperands_begin());
371 unsigned NontemporalMode = 0;
373 NontemporalMode += 0b1;
375 NontemporalMode += 0b10;
378 if (STI->hasStdExtZca())
379 Hint.setOpcode(RISCV::C_ADD);
381 Hint.setOpcode(RISCV::ADD);
387 EmitToStreamer(*OutStreamer, Hint);
390void RISCVAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
391 RISCV_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
396 if (MCInst OutInst; lowerPseudoInstExpansion(
MI, OutInst)) {
397 EmitToStreamer(*OutStreamer, OutInst);
401 switch (
MI->getOpcode()) {
402 case RISCV::PseudoTAILX7: {
405 lowerOperand(
MI->getOperand(0), SymOp);
410 EmitToStreamer(*OutStreamer, TmpInst);
413 case RISCV::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
414 LowerHWASAN_CHECK_MEMACCESS(*
MI);
416 case RISCV::KCFI_CHECK:
417 LowerKCFI_CHECK(*
MI);
419 case TargetOpcode::STACKMAP:
420 return LowerSTACKMAP(*OutStreamer, SM, *
MI);
421 case TargetOpcode::PATCHPOINT:
422 return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
423 case TargetOpcode::STATEPOINT:
424 return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
425 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
426 const Function &
F =
MI->getParent()->getParent()->getFunction();
427 if (
F.hasFnAttribute(
"patchable-function-entry")) {
429 F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
433 LowerPATCHABLE_FUNCTION_ENTER(
MI);
436 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
437 LowerPATCHABLE_FUNCTION_EXIT(
MI);
439 case TargetOpcode::PATCHABLE_TAIL_CALL:
440 LowerPATCHABLE_TAIL_CALL(
MI);
442 case RISCV::PseudoCALLLpadAlign:
443 case RISCV::PseudoCALLIndirectLpadAlign:
444 emitLpadAlignedCall(*
MI);
449 lowerToMCInst(
MI, OutInst);
450 EmitToStreamer(*OutStreamer, OutInst);
453bool RISCVAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
454 const char *ExtraCode, raw_ostream &OS) {
459 const MachineOperand &MO =
MI->getOperand(OpNo);
460 if (ExtraCode && ExtraCode[0]) {
461 if (ExtraCode[1] != 0)
464 switch (ExtraCode[0]) {
482 OS <<
TRI->getEncodingValue(MO.
getReg());
495 PrintSymbolOperand(MO, OS);
509bool RISCVAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
511 const char *ExtraCode,
516 const MachineOperand &AddrReg =
MI->getOperand(OpNo);
517 assert(
MI->getNumOperands() > OpNo + 1 &&
"Expected additional operand");
518 const MachineOperand &
Offset =
MI->getOperand(OpNo + 1);
521 if (!AddrReg.
isReg())
528 if (!lowerOperand(
Offset, MCO))
534 MAI.printExpr(OS, *MCO.
getExpr());
537 MMI->getContext().registerInlineAsmLabel(
Offset.getMCSymbol());
538 if (
Offset.isBlockAddress()) {
540 MCSymbol *Sym = GetBlockAddressSymbol(BA);
541 MMI->getContext().registerInlineAsmLabel(Sym);
549bool RISCVAsmPrinter::emitTargetFeaturePush(
const MCSubtargetInfo &STI) {
550 RISCVTargetStreamer &RTS = getTargetStreamer();
552 const MCSubtargetInfo &MCSTI = TM.getMCSubtargetInfo();
560 auto Delta = STI.
hasFeature(Feature.Value) ? RISCVOptionArchArgType::Plus
561 : RISCVOptionArchArgType::Minus;
562 StringRef ExtName = Feature.key();
566 if (!NeedEmitStdOptionArgs.
empty()) {
577void RISCVAsmPrinter::emitTargetFeaturePop(
const MCSubtargetInfo &STI,
580 getTargetStreamer().emitDirectiveOptionPop();
586 bool EmittedOptionArch = emitTargetFeaturePush(*STI);
588 SetupMachineFunction(MF);
594 emitTargetFeaturePop(*STI, EmittedOptionArch);
598void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr *
MI) {
599 emitSled(
MI, SledKind::FUNCTION_ENTER);
602void RISCVAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr *
MI) {
603 emitSled(
MI, SledKind::FUNCTION_EXIT);
606void RISCVAsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr *
MI) {
607 emitSled(
MI, SledKind::TAIL_CALL);
610void RISCVAsmPrinter::emitSled(
const MachineInstr *
MI, SledKind Kind) {
625 const uint8_t NoopsInSledCount = STI->is64Bit() ? 33 : 21;
628 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
630 auto Target = OutContext.createTempSymbol();
638 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addExpr(TargetExpr));
641 for (int8_t
I = 0;
I < NoopsInSledCount; ++
I)
642 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
648 recordSled(CurSled, *
MI, Kind, 2);
651void RISCVAsmPrinter::emitStartOfAsmFile(
Module &M) {
653 "target streamer is uninitialized");
654 RISCVTargetStreamer &RTS = getTargetStreamer();
655 StringRef ABIName =
M.getTargetABIFromMD();
656 if (!ABIName.
empty()) {
659 M.getContext().emitError(Twine(
'\'') + ABIName +
660 "' is not a recognized ABI for this target");
669 MCSubtargetInfo SubtargetInfo = TM.getMCSubtargetInfo();
673 for (
auto &ISA : MD->operands()) {
676 ISAString->getString(),
true,
679 auto &ISAInfo = *ParseResult;
681 if (ISAInfo->hasExtension(Feature.key()) &&
692 if (
M.getTargetTriple().isOSBinFormatELF())
696void RISCVAsmPrinter::emitEndOfAsmFile(
Module &M) {
697 RISCVTargetStreamer &RTS = getTargetStreamer();
699 if (
M.getTargetTriple().isOSBinFormatELF()) {
701 emitNoteGnuProperty(M);
703 EmitHwasanMemaccessSymbols(M);
706void RISCVAsmPrinter::emitFunctionEntryLabel() {
707 const auto *RMFI = MF->getInfo<RISCVMachineFunctionInfo>();
708 if (RMFI->isVectorCall()) {
709 RISCVTargetStreamer &RTS = getTargetStreamer();
724void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
726 uint32_t AccessInfo =
MI.getOperand(1).getImm();
728 HwasanMemaccessSymbols[HwasanMemaccessTuple(
Reg, AccessInfo)];
731 if (!TM.getTargetTriple().isOSBinFormatELF())
734 std::string SymName =
"__hwasan_check_x" +
utostr(
Reg - RISCV::X0) +
"_" +
735 utostr(AccessInfo) +
"_short";
736 Sym = OutContext.getOrCreateSymbol(SymName);
741 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr));
744void RISCVAsmPrinter::LowerKCFI_CHECK(
const MachineInstr &
MI) {
746 assert(std::next(
MI.getIterator())->isCall() &&
747 "KCFI_CHECK not followed by a call instruction");
748 assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
749 "KCFI_CHECK call target doesn't match call operand");
756 unsigned ScratchRegs[] = {RISCV::X6, RISCV::X7};
757 unsigned NextReg = RISCV::X28;
758 auto isRegAvailable = [&](
unsigned Reg) {
759 return Reg != AddrReg && !STI->isRegisterReservedByUser(
Reg);
761 for (
auto &
Reg : ScratchRegs) {
762 if (isRegAvailable(
Reg))
764 while (!isRegAvailable(NextReg))
767 if (
Reg > RISCV::X31)
771 if (AddrReg == RISCV::X0) {
774 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
775 .addReg(ScratchRegs[0])
781 int NopSize = STI->hasStdExtZca() ? 2 : 4;
783 MI.getMF()->getFunction().getFnAttributeAsParsedInteger(
784 "patchable-function-prefix");
787 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::LW)
788 .addReg(ScratchRegs[0])
790 .addImm(-(PrefixNops * NopSize + 4)));
794 const int64_t
Type =
MI.getOperand(1).getImm();
795 const int64_t Hi20 = ((
Type + 0x800) >> 12) & 0xFFFFF;
800 MCInstBuilder(RISCV::LUI).addReg(ScratchRegs[1]).addImm(Hi20));
802 if (Lo12 || Hi20 == 0) {
803 EmitToStreamer(*OutStreamer,
804 MCInstBuilder((STI->
hasFeature(RISCV::Feature64Bit) && Hi20)
807 .addReg(ScratchRegs[1])
808 .addReg(ScratchRegs[1])
814 EmitToStreamer(*OutStreamer,
815 MCInstBuilder(RISCV::BEQ)
816 .addReg(ScratchRegs[0])
817 .addReg(ScratchRegs[1])
822 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::EBREAK));
823 emitKCFITrapEntry(*
MI.getMF(),
Trap);
827void RISCVAsmPrinter::EmitHwasanMemaccessSymbols(
Module &M) {
828 if (HwasanMemaccessSymbols.empty())
831 assert(
M.getTargetTriple().isOSBinFormatELF());
835 const MCSubtargetInfo &MCSTI = TM.getMCSubtargetInfo();
838 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
841 RISCVTargetStreamer &RTS = getTargetStreamer();
844 const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
849 for (
auto &
P : HwasanMemaccessSymbols) {
850 unsigned Reg = std::get<0>(
P.first);
851 uint32_t AccessInfo = std::get<1>(
P.first);
869 MCInstBuilder(RISCV::SLLI).addReg(RISCV::X6).addReg(
Reg).addImm(8),
871 EmitToStreamer(*OutStreamer,
872 MCInstBuilder(RISCV::SRLI)
878 EmitToStreamer(*OutStreamer,
879 MCInstBuilder(RISCV::ADD)
886 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
891 MCInstBuilder(RISCV::SRLI).addReg(RISCV::X7).addReg(
Reg).addImm(56),
893 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
895 EmitToStreamer(*OutStreamer,
896 MCInstBuilder(RISCV::BNE)
900 HandleMismatchOrPartialSym, OutContext)),
902 MCSymbol *ReturnSym = OutContext.createTempSymbol();
904 EmitToStreamer(*OutStreamer,
905 MCInstBuilder(RISCV::JALR)
910 OutStreamer->
emitLabel(HandleMismatchOrPartialSym);
912 EmitToStreamer(*OutStreamer,
913 MCInstBuilder(RISCV::ADDI)
918 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
921 MCInstBuilder(RISCV::BGEU)
929 MCInstBuilder(RISCV::ANDI).addReg(RISCV::X28).addReg(
Reg).addImm(0xF),
933 EmitToStreamer(*OutStreamer,
934 MCInstBuilder(RISCV::ADDI)
941 MCInstBuilder(RISCV::BGE)
949 MCInstBuilder(RISCV::ORI).addReg(RISCV::X6).addReg(
Reg).addImm(0xF),
953 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
955 EmitToStreamer(*OutStreamer,
956 MCInstBuilder(RISCV::BEQ)
962 OutStreamer->
emitLabel(HandleMismatchSym);
999 EmitToStreamer(*OutStreamer,
1000 MCInstBuilder(RISCV::ADDI)
1007 EmitToStreamer(*OutStreamer,
1008 MCInstBuilder(RISCV::SD)
1014 EmitToStreamer(*OutStreamer,
1015 MCInstBuilder(RISCV::SD)
1024 MCInstBuilder(RISCV::SD).addReg(RISCV::X8).addReg(RISCV::X2).addImm(8 *
1030 MCInstBuilder(RISCV::SD).addReg(RISCV::X1).addReg(RISCV::X2).addImm(1 *
1033 if (
Reg != RISCV::X10)
1036 MCInstBuilder(RISCV::ADDI).addReg(RISCV::X10).addReg(
Reg).addImm(0),
1038 EmitToStreamer(*OutStreamer,
1039 MCInstBuilder(RISCV::ADDI)
1045 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr),
1050void RISCVAsmPrinter::emitNoteGnuProperty(
const Module &M) {
1051 assert(
M.getTargetTriple().isOSBinFormatELF() &&
"invalid binary format");
1052 uint32_t GnuProps = 0;
1053 if (
const Metadata *
const Flag =
M.getModuleFlag(
"cf-protection-return");
1057 if (
const Metadata *
const Flag =
M.getModuleFlag(
"cf-protection-branch");
1059 using namespace llvm::RISCVISAUtils;
1060 const Metadata *
const CFBranchLabelSchemeFlag =
1061 M.getModuleFlag(
"cf-branch-label-scheme");
1062 assert(CFBranchLabelSchemeFlag &&
1063 "cf-protection=branch should come with cf-branch-label-scheme=... "
1064 "on RISC-V targets");
1065 const StringRef CFBranchLabelScheme =
1084 auto &RTS =
static_cast<RISCVTargetELFStreamer &
>(getTargetStreamer());
1085 RTS.emitNoteGnuPropertySection(GnuProps);
1106 Kind = ELF::R_RISCV_HI20;
1121 Kind = ELF::R_RISCV_TPREL_HI20;
1124 Kind = ELF::R_RISCV_TPREL_ADD;
1127 Kind = ELF::R_RISCV_TLS_GOT_HI20;
1130 Kind = ELF::R_RISCV_TLS_GD_HI20;
1133 Kind = ELF::R_RISCV_TLSDESC_HI20;
1136 Kind = ELF::R_RISCV_TLSDESC_LOAD_LO12;
1139 Kind = ELF::R_RISCV_TLSDESC_ADD_LO12;
1142 Kind = ELF::R_RISCV_TLSDESC_CALL;
1160bool RISCVAsmPrinter::lowerOperand(
const MachineOperand &MO,
1161 MCOperand &MCOp)
const {
1208 RISCVVPseudosTable::getPseudoInfo(
MI->getOpcode());
1216 assert(
TRI &&
"TargetRegisterInfo expected");
1220 unsigned NumOps =
MI->getNumExplicitOperands();
1239 bool hasVLOutput = RISCVInstrInfo::isFaultOnlyFirstLoad(*
MI);
1240 for (
unsigned OpNo = 0; OpNo !=
NumOps; ++OpNo) {
1243 if (hasVLOutput && OpNo == 1)
1247 if (OpNo ==
MI->getNumExplicitDefs() && MO.
isReg() && MO.
isTied()) {
1249 "Expected tied to first def.");
1269 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1270 assert(
Reg &&
"Subregister does not exist");
1273 TRI->getMatchingSuperReg(
Reg, RISCV::sub_16, &RISCV::FPR32RegClass);
1274 assert(
Reg &&
"Subregister does not exist");
1276 Reg =
TRI->getSubReg(
Reg, RISCV::sub_32);
1277 assert(
Reg &&
"Superregister does not exist");
1289 Reg =
TRI->getSubReg(
Reg, RISCV::sub_vrm1_0);
1290 assert(
Reg &&
"Subregister does not exist");
1309 "Expected only mask operand to be missing");
1317void RISCVAsmPrinter::lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI) {
1323 for (
const MachineOperand &MO :
MI->operands()) {
1325 if (lowerOperand(MO, MCOp))
1330void RISCVAsmPrinter::emitMachineConstantPoolValue(
1331 MachineConstantPoolValue *MCPV) {
1332 auto *RCPV =
static_cast<RISCVConstantPoolValue *
>(MCPV);
1335 if (RCPV->isGlobalValue()) {
1336 auto *GV = RCPV->getGlobalValue();
1337 MCSym = getSymbol(GV);
1339 assert(RCPV->isExtSymbol() &&
"unrecognized constant pool type");
1340 auto Sym = RCPV->getSymbol();
1341 MCSym = GetExternalSymbolSymbol(Sym);
1345 uint64_t Size = getDataLayout().getTypeAllocSize(RCPV->getType());
1350RISCVAsmPrinter::getRequiredGlobalAlignmentGranule(
const GlobalVariable &GV) {
1351 const MCSubtargetInfo &MCSTI = TM.getMCSubtargetInfo();
1353 return std::nullopt;
1360 return std::nullopt;
1363 if (MCSTI.
hasFeature(RISCV::FeatureVendorXCheriot))
1364 return CHERIoTCapabilityFormat::getRequiredAlignment(
Size);
1366 if (MCSTI.
hasFeature(RISCV::FeatureStdExtY)) {
1373 return std::nullopt;
1376char RISCVAsmPrinter::ID = 0;
1383 RISCVAsmPrinter &
AsmPrinter =
static_cast<RISCVAsmPrinter &
>(
1393 RISCVAsmPrinter &
AsmPrinter =
static_cast<RISCVAsmPrinter &
>(
1404 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(const RISCVMCOptions &CLOpts, 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,...