xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- RISCVAsmPrinter.cpp - RISC-V LLVM assembly writer -----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains a printer that converts from our internal representation
10 // of machine-dependent LLVM code to the RISC-V assembly language.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "MCTargetDesc/RISCVBaseInfo.h"
15 #include "MCTargetDesc/RISCVInstPrinter.h"
16 #include "MCTargetDesc/RISCVMCExpr.h"
17 #include "MCTargetDesc/RISCVMatInt.h"
18 #include "MCTargetDesc/RISCVTargetStreamer.h"
19 #include "RISCV.h"
20 #include "RISCVMachineFunctionInfo.h"
21 #include "RISCVTargetMachine.h"
22 #include "TargetInfo/RISCVTargetInfo.h"
23 #include "llvm/ADT/APInt.h"
24 #include "llvm/ADT/Statistic.h"
25 #include "llvm/BinaryFormat/ELF.h"
26 #include "llvm/CodeGen/AsmPrinter.h"
27 #include "llvm/CodeGen/MachineConstantPool.h"
28 #include "llvm/CodeGen/MachineFunctionPass.h"
29 #include "llvm/CodeGen/MachineInstr.h"
30 #include "llvm/CodeGen/MachineModuleInfo.h"
31 #include "llvm/IR/Module.h"
32 #include "llvm/MC/MCAsmInfo.h"
33 #include "llvm/MC/MCContext.h"
34 #include "llvm/MC/MCInst.h"
35 #include "llvm/MC/MCInstBuilder.h"
36 #include "llvm/MC/MCObjectFileInfo.h"
37 #include "llvm/MC/MCSectionELF.h"
38 #include "llvm/MC/MCStreamer.h"
39 #include "llvm/MC/MCSymbol.h"
40 #include "llvm/MC/TargetRegistry.h"
41 #include "llvm/Support/raw_ostream.h"
42 #include "llvm/TargetParser/RISCVISAInfo.h"
43 #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
44 
45 using namespace llvm;
46 
47 #define DEBUG_TYPE "asm-printer"
48 
49 STATISTIC(RISCVNumInstrsCompressed,
50           "Number of RISC-V Compressed instructions emitted");
51 
52 namespace llvm {
53 extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
54 } // namespace llvm
55 
56 namespace {
57 class RISCVAsmPrinter : public AsmPrinter {
58   const RISCVSubtarget *STI;
59 
60 public:
RISCVAsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)61   explicit RISCVAsmPrinter(TargetMachine &TM,
62                            std::unique_ptr<MCStreamer> Streamer)
63       : AsmPrinter(TM, std::move(Streamer)) {}
64 
getPassName() const65   StringRef getPassName() const override { return "RISC-V Assembly Printer"; }
66 
67   void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
68                      const MachineInstr &MI);
69 
70   void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
71                        const MachineInstr &MI);
72 
73   void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
74                        const MachineInstr &MI);
75 
76   bool runOnMachineFunction(MachineFunction &MF) override;
77 
78   void emitInstruction(const MachineInstr *MI) override;
79 
80   bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
81                        const char *ExtraCode, raw_ostream &OS) override;
82   bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
83                              const char *ExtraCode, raw_ostream &OS) override;
84 
85   // Returns whether Inst is compressed.
86   bool EmitToStreamer(MCStreamer &S, const MCInst &Inst);
87   bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
88                                    const MachineInstr *MI);
89 
90   typedef std::tuple<unsigned, uint32_t> HwasanMemaccessTuple;
91   std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
92   void LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI);
93   void LowerKCFI_CHECK(const MachineInstr &MI);
94   void EmitHwasanMemaccessSymbols(Module &M);
95 
96   // Wrapper needed for tblgenned pseudo lowering.
97   bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const;
98 
99   void emitStartOfAsmFile(Module &M) override;
100   void emitEndOfAsmFile(Module &M) override;
101 
102   void emitFunctionEntryLabel() override;
103   bool emitDirectiveOptionArch();
104 
105 private:
106   void emitAttributes(const MCSubtargetInfo &SubtargetInfo);
107 
108   void emitNTLHint(const MachineInstr *MI);
109 
110   bool lowerToMCInst(const MachineInstr *MI, MCInst &OutMI);
111 };
112 }
113 
LowerSTACKMAP(MCStreamer & OutStreamer,StackMaps & SM,const MachineInstr & MI)114 void RISCVAsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
115                                     const MachineInstr &MI) {
116   unsigned NOPBytes = STI->hasStdExtCOrZca() ? 2 : 4;
117   unsigned NumNOPBytes = StackMapOpers(&MI).getNumPatchBytes();
118 
119   auto &Ctx = OutStreamer.getContext();
120   MCSymbol *MILabel = Ctx.createTempSymbol();
121   OutStreamer.emitLabel(MILabel);
122 
123   SM.recordStackMap(*MILabel, MI);
124   assert(NumNOPBytes % NOPBytes == 0 &&
125          "Invalid number of NOP bytes requested!");
126 
127   // Scan ahead to trim the shadow.
128   const MachineBasicBlock &MBB = *MI.getParent();
129   MachineBasicBlock::const_iterator MII(MI);
130   ++MII;
131   while (NumNOPBytes > 0) {
132     if (MII == MBB.end() || MII->isCall() ||
133         MII->getOpcode() == RISCV::DBG_VALUE ||
134         MII->getOpcode() == TargetOpcode::PATCHPOINT ||
135         MII->getOpcode() == TargetOpcode::STACKMAP)
136       break;
137     ++MII;
138     NumNOPBytes -= 4;
139   }
140 
141   // Emit nops.
142   emitNops(NumNOPBytes / NOPBytes);
143 }
144 
145 // Lower a patchpoint of the form:
146 // [<def>], <id>, <numBytes>, <target>, <numArgs>
LowerPATCHPOINT(MCStreamer & OutStreamer,StackMaps & SM,const MachineInstr & MI)147 void RISCVAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
148                                       const MachineInstr &MI) {
149   unsigned NOPBytes = STI->hasStdExtCOrZca() ? 2 : 4;
150 
151   auto &Ctx = OutStreamer.getContext();
152   MCSymbol *MILabel = Ctx.createTempSymbol();
153   OutStreamer.emitLabel(MILabel);
154   SM.recordPatchPoint(*MILabel, MI);
155 
156   PatchPointOpers Opers(&MI);
157 
158   const MachineOperand &CalleeMO = Opers.getCallTarget();
159   unsigned EncodedBytes = 0;
160 
161   if (CalleeMO.isImm()) {
162     uint64_t CallTarget = CalleeMO.getImm();
163     if (CallTarget) {
164       assert((CallTarget & 0xFFFF'FFFF'FFFF) == CallTarget &&
165              "High 16 bits of call target should be zero.");
166       // Materialize the jump address:
167       SmallVector<MCInst, 8> Seq;
168       RISCVMatInt::generateMCInstSeq(CallTarget, *STI, RISCV::X1, Seq);
169       for (MCInst &Inst : Seq) {
170         bool Compressed = EmitToStreamer(OutStreamer, Inst);
171         EncodedBytes += Compressed ? 2 : 4;
172       }
173       bool Compressed = EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
174                                                         .addReg(RISCV::X1)
175                                                         .addReg(RISCV::X1)
176                                                         .addImm(0));
177       EncodedBytes += Compressed ? 2 : 4;
178     }
179   } else if (CalleeMO.isGlobal()) {
180     MCOperand CallTargetMCOp;
181     lowerOperand(CalleeMO, CallTargetMCOp);
182     EmitToStreamer(OutStreamer,
183                    MCInstBuilder(RISCV::PseudoCALL).addOperand(CallTargetMCOp));
184     EncodedBytes += 8;
185   }
186 
187   // Emit padding.
188   unsigned NumBytes = Opers.getNumPatchBytes();
189   assert(NumBytes >= EncodedBytes &&
190          "Patchpoint can't request size less than the length of a call.");
191   assert((NumBytes - EncodedBytes) % NOPBytes == 0 &&
192          "Invalid number of NOP bytes requested!");
193   emitNops((NumBytes - EncodedBytes) / NOPBytes);
194 }
195 
LowerSTATEPOINT(MCStreamer & OutStreamer,StackMaps & SM,const MachineInstr & MI)196 void RISCVAsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
197                                       const MachineInstr &MI) {
198   unsigned NOPBytes = STI->hasStdExtCOrZca() ? 2 : 4;
199 
200   StatepointOpers SOpers(&MI);
201   if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {
202     assert(PatchBytes % NOPBytes == 0 &&
203            "Invalid number of NOP bytes requested!");
204     emitNops(PatchBytes / NOPBytes);
205   } else {
206     // Lower call target and choose correct opcode
207     const MachineOperand &CallTarget = SOpers.getCallTarget();
208     MCOperand CallTargetMCOp;
209     switch (CallTarget.getType()) {
210     case MachineOperand::MO_GlobalAddress:
211     case MachineOperand::MO_ExternalSymbol:
212       lowerOperand(CallTarget, CallTargetMCOp);
213       EmitToStreamer(
214           OutStreamer,
215           MCInstBuilder(RISCV::PseudoCALL).addOperand(CallTargetMCOp));
216       break;
217     case MachineOperand::MO_Immediate:
218       CallTargetMCOp = MCOperand::createImm(CallTarget.getImm());
219       EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JAL)
220                                       .addReg(RISCV::X1)
221                                       .addOperand(CallTargetMCOp));
222       break;
223     case MachineOperand::MO_Register:
224       CallTargetMCOp = MCOperand::createReg(CallTarget.getReg());
225       EmitToStreamer(OutStreamer, MCInstBuilder(RISCV::JALR)
226                                       .addReg(RISCV::X1)
227                                       .addOperand(CallTargetMCOp)
228                                       .addImm(0));
229       break;
230     default:
231       llvm_unreachable("Unsupported operand type in statepoint call target");
232       break;
233     }
234   }
235 
236   auto &Ctx = OutStreamer.getContext();
237   MCSymbol *MILabel = Ctx.createTempSymbol();
238   OutStreamer.emitLabel(MILabel);
239   SM.recordStatepoint(*MILabel, MI);
240 }
241 
EmitToStreamer(MCStreamer & S,const MCInst & Inst)242 bool RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {
243   MCInst CInst;
244   bool Res = RISCVRVC::compress(CInst, Inst, *STI);
245   if (Res)
246     ++RISCVNumInstrsCompressed;
247   AsmPrinter::EmitToStreamer(*OutStreamer, Res ? CInst : Inst);
248   return Res;
249 }
250 
251 // Simple pseudo-instructions have their lowering (with expansion to real
252 // instructions) auto-generated.
253 #include "RISCVGenMCPseudoLowering.inc"
254 
255 // If the target supports Zihintntl and the instruction has a nontemporal
256 // MachineMemOperand, emit an NTLH hint instruction before it.
emitNTLHint(const MachineInstr * MI)257 void RISCVAsmPrinter::emitNTLHint(const MachineInstr *MI) {
258   if (!STI->hasStdExtZihintntl())
259     return;
260 
261   if (MI->memoperands_empty())
262     return;
263 
264   MachineMemOperand *MMO = *(MI->memoperands_begin());
265   if (!MMO->isNonTemporal())
266     return;
267 
268   unsigned NontemporalMode = 0;
269   if (MMO->getFlags() & MONontemporalBit0)
270     NontemporalMode += 0b1;
271   if (MMO->getFlags() & MONontemporalBit1)
272     NontemporalMode += 0b10;
273 
274   MCInst Hint;
275   if (STI->hasStdExtCOrZca() && STI->enableRVCHintInstrs())
276     Hint.setOpcode(RISCV::C_ADD_HINT);
277   else
278     Hint.setOpcode(RISCV::ADD);
279 
280   Hint.addOperand(MCOperand::createReg(RISCV::X0));
281   Hint.addOperand(MCOperand::createReg(RISCV::X0));
282   Hint.addOperand(MCOperand::createReg(RISCV::X2 + NontemporalMode));
283 
284   EmitToStreamer(*OutStreamer, Hint);
285 }
286 
emitInstruction(const MachineInstr * MI)287 void RISCVAsmPrinter::emitInstruction(const MachineInstr *MI) {
288   RISCV_MC::verifyInstructionPredicates(MI->getOpcode(),
289                                         getSubtargetInfo().getFeatureBits());
290 
291   emitNTLHint(MI);
292 
293   // Do any auto-generated pseudo lowerings.
294   if (emitPseudoExpansionLowering(*OutStreamer, MI))
295     return;
296 
297 
298   switch (MI->getOpcode()) {
299   case RISCV::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
300     LowerHWASAN_CHECK_MEMACCESS(*MI);
301     return;
302   case RISCV::KCFI_CHECK:
303     LowerKCFI_CHECK(*MI);
304     return;
305   case RISCV::PseudoRVVInitUndefM1:
306   case RISCV::PseudoRVVInitUndefM2:
307   case RISCV::PseudoRVVInitUndefM4:
308   case RISCV::PseudoRVVInitUndefM8:
309     return;
310   case TargetOpcode::STACKMAP:
311     return LowerSTACKMAP(*OutStreamer, SM, *MI);
312   case TargetOpcode::PATCHPOINT:
313     return LowerPATCHPOINT(*OutStreamer, SM, *MI);
314   case TargetOpcode::STATEPOINT:
315     return LowerSTATEPOINT(*OutStreamer, SM, *MI);
316   }
317 
318   MCInst OutInst;
319   if (!lowerToMCInst(MI, OutInst))
320     EmitToStreamer(*OutStreamer, OutInst);
321 }
322 
PrintAsmOperand(const MachineInstr * MI,unsigned OpNo,const char * ExtraCode,raw_ostream & OS)323 bool RISCVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
324                                       const char *ExtraCode, raw_ostream &OS) {
325   // First try the generic code, which knows about modifiers like 'c' and 'n'.
326   if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
327     return false;
328 
329   const MachineOperand &MO = MI->getOperand(OpNo);
330   if (ExtraCode && ExtraCode[0]) {
331     if (ExtraCode[1] != 0)
332       return true; // Unknown modifier.
333 
334     switch (ExtraCode[0]) {
335     default:
336       return true; // Unknown modifier.
337     case 'z':      // Print zero register if zero, regular printing otherwise.
338       if (MO.isImm() && MO.getImm() == 0) {
339         OS << RISCVInstPrinter::getRegisterName(RISCV::X0);
340         return false;
341       }
342       break;
343     case 'i': // Literal 'i' if operand is not a register.
344       if (!MO.isReg())
345         OS << 'i';
346       return false;
347     }
348   }
349 
350   switch (MO.getType()) {
351   case MachineOperand::MO_Immediate:
352     OS << MO.getImm();
353     return false;
354   case MachineOperand::MO_Register:
355     OS << RISCVInstPrinter::getRegisterName(MO.getReg());
356     return false;
357   case MachineOperand::MO_GlobalAddress:
358     PrintSymbolOperand(MO, OS);
359     return false;
360   case MachineOperand::MO_BlockAddress: {
361     MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
362     Sym->print(OS, MAI);
363     return false;
364   }
365   default:
366     break;
367   }
368 
369   return true;
370 }
371 
PrintAsmMemoryOperand(const MachineInstr * MI,unsigned OpNo,const char * ExtraCode,raw_ostream & OS)372 bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
373                                             unsigned OpNo,
374                                             const char *ExtraCode,
375                                             raw_ostream &OS) {
376   if (ExtraCode)
377     return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS);
378 
379   const MachineOperand &AddrReg = MI->getOperand(OpNo);
380   assert(MI->getNumOperands() > OpNo + 1 && "Expected additional operand");
381   const MachineOperand &Offset = MI->getOperand(OpNo + 1);
382   // All memory operands should have a register and an immediate operand (see
383   // RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand).
384   if (!AddrReg.isReg())
385     return true;
386   if (!Offset.isImm() && !Offset.isGlobal() && !Offset.isBlockAddress() &&
387       !Offset.isMCSymbol())
388     return true;
389 
390   MCOperand MCO;
391   if (!lowerOperand(Offset, MCO))
392     return true;
393 
394   if (Offset.isImm())
395     OS << MCO.getImm();
396   else if (Offset.isGlobal() || Offset.isBlockAddress() || Offset.isMCSymbol())
397     OS << *MCO.getExpr();
398   OS << "(" << RISCVInstPrinter::getRegisterName(AddrReg.getReg()) << ")";
399   return false;
400 }
401 
emitDirectiveOptionArch()402 bool RISCVAsmPrinter::emitDirectiveOptionArch() {
403   RISCVTargetStreamer &RTS =
404       static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
405   SmallVector<RISCVOptionArchArg> NeedEmitStdOptionArgs;
406   const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
407   for (const auto &Feature : RISCVFeatureKV) {
408     if (STI->hasFeature(Feature.Value) == MCSTI.hasFeature(Feature.Value))
409       continue;
410 
411     if (!llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key))
412       continue;
413 
414     auto Delta = STI->hasFeature(Feature.Value) ? RISCVOptionArchArgType::Plus
415                                                 : RISCVOptionArchArgType::Minus;
416     NeedEmitStdOptionArgs.emplace_back(Delta, Feature.Key);
417   }
418   if (!NeedEmitStdOptionArgs.empty()) {
419     RTS.emitDirectiveOptionPush();
420     RTS.emitDirectiveOptionArch(NeedEmitStdOptionArgs);
421     return true;
422   }
423 
424   return false;
425 }
426 
runOnMachineFunction(MachineFunction & MF)427 bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
428   STI = &MF.getSubtarget<RISCVSubtarget>();
429   RISCVTargetStreamer &RTS =
430       static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
431 
432   bool EmittedOptionArch = emitDirectiveOptionArch();
433 
434   SetupMachineFunction(MF);
435   emitFunctionBody();
436 
437   if (EmittedOptionArch)
438     RTS.emitDirectiveOptionPop();
439   return false;
440 }
441 
emitStartOfAsmFile(Module & M)442 void RISCVAsmPrinter::emitStartOfAsmFile(Module &M) {
443   RISCVTargetStreamer &RTS =
444       static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
445   if (const MDString *ModuleTargetABI =
446           dyn_cast_or_null<MDString>(M.getModuleFlag("target-abi")))
447     RTS.setTargetABI(RISCVABI::getTargetABI(ModuleTargetABI->getString()));
448 
449   MCSubtargetInfo SubtargetInfo = *TM.getMCSubtargetInfo();
450 
451   // Use module flag to update feature bits.
452   if (auto *MD = dyn_cast_or_null<MDNode>(M.getModuleFlag("riscv-isa"))) {
453     for (auto &ISA : MD->operands()) {
454       if (auto *ISAString = dyn_cast_or_null<MDString>(ISA)) {
455         auto ParseResult = llvm::RISCVISAInfo::parseArchString(
456             ISAString->getString(), /*EnableExperimentalExtension=*/true,
457             /*ExperimentalExtensionVersionCheck=*/true);
458         if (!errorToBool(ParseResult.takeError())) {
459           auto &ISAInfo = *ParseResult;
460           for (const auto &Feature : RISCVFeatureKV) {
461             if (ISAInfo->hasExtension(Feature.Key) &&
462                 !SubtargetInfo.hasFeature(Feature.Value))
463               SubtargetInfo.ToggleFeature(Feature.Key);
464           }
465         }
466       }
467     }
468 
469     RTS.setFlagsFromFeatures(SubtargetInfo);
470   }
471 
472   if (TM.getTargetTriple().isOSBinFormatELF())
473     emitAttributes(SubtargetInfo);
474 }
475 
emitEndOfAsmFile(Module & M)476 void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) {
477   RISCVTargetStreamer &RTS =
478       static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
479 
480   if (TM.getTargetTriple().isOSBinFormatELF())
481     RTS.finishAttributeSection();
482   EmitHwasanMemaccessSymbols(M);
483 }
484 
emitAttributes(const MCSubtargetInfo & SubtargetInfo)485 void RISCVAsmPrinter::emitAttributes(const MCSubtargetInfo &SubtargetInfo) {
486   RISCVTargetStreamer &RTS =
487       static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
488   // Use MCSubtargetInfo from TargetMachine. Individual functions may have
489   // attributes that differ from other functions in the module and we have no
490   // way to know which function is correct.
491   RTS.emitTargetAttributes(SubtargetInfo, /*EmitStackAlign*/ true);
492 }
493 
emitFunctionEntryLabel()494 void RISCVAsmPrinter::emitFunctionEntryLabel() {
495   const auto *RMFI = MF->getInfo<RISCVMachineFunctionInfo>();
496   if (RMFI->isVectorCall()) {
497     auto &RTS =
498         static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
499     RTS.emitDirectiveVariantCC(*CurrentFnSym);
500   }
501   return AsmPrinter::emitFunctionEntryLabel();
502 }
503 
504 // Force static initialization.
LLVMInitializeRISCVAsmPrinter()505 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmPrinter() {
506   RegisterAsmPrinter<RISCVAsmPrinter> X(getTheRISCV32Target());
507   RegisterAsmPrinter<RISCVAsmPrinter> Y(getTheRISCV64Target());
508 }
509 
LowerHWASAN_CHECK_MEMACCESS(const MachineInstr & MI)510 void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI) {
511   Register Reg = MI.getOperand(0).getReg();
512   uint32_t AccessInfo = MI.getOperand(1).getImm();
513   MCSymbol *&Sym =
514       HwasanMemaccessSymbols[HwasanMemaccessTuple(Reg, AccessInfo)];
515   if (!Sym) {
516     // FIXME: Make this work on non-ELF.
517     if (!TM.getTargetTriple().isOSBinFormatELF())
518       report_fatal_error("llvm.hwasan.check.memaccess only supported on ELF");
519 
520     std::string SymName = "__hwasan_check_x" + utostr(Reg - RISCV::X0) + "_" +
521                           utostr(AccessInfo) + "_short";
522     Sym = OutContext.getOrCreateSymbol(SymName);
523   }
524   auto Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, OutContext);
525   auto Expr = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, OutContext);
526 
527   EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr));
528 }
529 
LowerKCFI_CHECK(const MachineInstr & MI)530 void RISCVAsmPrinter::LowerKCFI_CHECK(const MachineInstr &MI) {
531   Register AddrReg = MI.getOperand(0).getReg();
532   assert(std::next(MI.getIterator())->isCall() &&
533          "KCFI_CHECK not followed by a call instruction");
534   assert(std::next(MI.getIterator())->getOperand(0).getReg() == AddrReg &&
535          "KCFI_CHECK call target doesn't match call operand");
536 
537   // Temporary registers for comparing the hashes. If a register is used
538   // for the call target, or reserved by the user, we can clobber another
539   // temporary register as the check is immediately followed by the
540   // call. The check defaults to X6/X7, but can fall back to X28-X31 if
541   // needed.
542   unsigned ScratchRegs[] = {RISCV::X6, RISCV::X7};
543   unsigned NextReg = RISCV::X28;
544   auto isRegAvailable = [&](unsigned Reg) {
545     return Reg != AddrReg && !STI->isRegisterReservedByUser(Reg);
546   };
547   for (auto &Reg : ScratchRegs) {
548     if (isRegAvailable(Reg))
549       continue;
550     while (!isRegAvailable(NextReg))
551       ++NextReg;
552     Reg = NextReg++;
553     if (Reg > RISCV::X31)
554       report_fatal_error("Unable to find scratch registers for KCFI_CHECK");
555   }
556 
557   if (AddrReg == RISCV::X0) {
558     // Checking X0 makes no sense. Instead of emitting a load, zero
559     // ScratchRegs[0].
560     EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
561                                      .addReg(ScratchRegs[0])
562                                      .addReg(RISCV::X0)
563                                      .addImm(0));
564   } else {
565     // Adjust the offset for patchable-function-prefix. This assumes that
566     // patchable-function-prefix is the same for all functions.
567     int NopSize = STI->hasStdExtCOrZca() ? 2 : 4;
568     int64_t PrefixNops = 0;
569     (void)MI.getMF()
570         ->getFunction()
571         .getFnAttribute("patchable-function-prefix")
572         .getValueAsString()
573         .getAsInteger(10, PrefixNops);
574 
575     // Load the target function type hash.
576     EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::LW)
577                                      .addReg(ScratchRegs[0])
578                                      .addReg(AddrReg)
579                                      .addImm(-(PrefixNops * NopSize + 4)));
580   }
581 
582   // Load the expected 32-bit type hash.
583   const int64_t Type = MI.getOperand(1).getImm();
584   const int64_t Hi20 = ((Type + 0x800) >> 12) & 0xFFFFF;
585   const int64_t Lo12 = SignExtend64<12>(Type);
586   if (Hi20) {
587     EmitToStreamer(
588         *OutStreamer,
589         MCInstBuilder(RISCV::LUI).addReg(ScratchRegs[1]).addImm(Hi20));
590   }
591   if (Lo12 || Hi20 == 0) {
592     EmitToStreamer(*OutStreamer,
593                    MCInstBuilder((STI->hasFeature(RISCV::Feature64Bit) && Hi20)
594                                      ? RISCV::ADDIW
595                                      : RISCV::ADDI)
596                        .addReg(ScratchRegs[1])
597                        .addReg(ScratchRegs[1])
598                        .addImm(Lo12));
599   }
600 
601   // Compare the hashes and trap if there's a mismatch.
602   MCSymbol *Pass = OutContext.createTempSymbol();
603   EmitToStreamer(*OutStreamer,
604                  MCInstBuilder(RISCV::BEQ)
605                      .addReg(ScratchRegs[0])
606                      .addReg(ScratchRegs[1])
607                      .addExpr(MCSymbolRefExpr::create(Pass, OutContext)));
608 
609   MCSymbol *Trap = OutContext.createTempSymbol();
610   OutStreamer->emitLabel(Trap);
611   EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::EBREAK));
612   emitKCFITrapEntry(*MI.getMF(), Trap);
613   OutStreamer->emitLabel(Pass);
614 }
615 
EmitHwasanMemaccessSymbols(Module & M)616 void RISCVAsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
617   if (HwasanMemaccessSymbols.empty())
618     return;
619 
620   assert(TM.getTargetTriple().isOSBinFormatELF());
621   // Use MCSubtargetInfo from TargetMachine. Individual functions may have
622   // attributes that differ from other functions in the module and we have no
623   // way to know which function is correct.
624   const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
625 
626   MCSymbol *HwasanTagMismatchV2Sym =
627       OutContext.getOrCreateSymbol("__hwasan_tag_mismatch_v2");
628   // Annotate symbol as one having incompatible calling convention, so
629   // run-time linkers can instead eagerly bind this function.
630   auto &RTS =
631       static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
632   RTS.emitDirectiveVariantCC(*HwasanTagMismatchV2Sym);
633 
634   const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
635       MCSymbolRefExpr::create(HwasanTagMismatchV2Sym, OutContext);
636   auto Expr = RISCVMCExpr::create(HwasanTagMismatchV2Ref,
637                                   RISCVMCExpr::VK_RISCV_CALL, OutContext);
638 
639   for (auto &P : HwasanMemaccessSymbols) {
640     unsigned Reg = std::get<0>(P.first);
641     uint32_t AccessInfo = std::get<1>(P.first);
642     MCSymbol *Sym = P.second;
643 
644     unsigned Size =
645         1 << ((AccessInfo >> HWASanAccessInfo::AccessSizeShift) & 0xf);
646     OutStreamer->switchSection(OutContext.getELFSection(
647         ".text.hot", ELF::SHT_PROGBITS,
648         ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, Sym->getName(),
649         /*IsComdat=*/true));
650 
651     OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
652     OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak);
653     OutStreamer->emitSymbolAttribute(Sym, MCSA_Hidden);
654     OutStreamer->emitLabel(Sym);
655 
656     // Extract shadow offset from ptr
657     OutStreamer->emitInstruction(
658         MCInstBuilder(RISCV::SLLI).addReg(RISCV::X6).addReg(Reg).addImm(8),
659         MCSTI);
660     OutStreamer->emitInstruction(MCInstBuilder(RISCV::SRLI)
661                                      .addReg(RISCV::X6)
662                                      .addReg(RISCV::X6)
663                                      .addImm(12),
664                                  MCSTI);
665     // load shadow tag in X6, X5 contains shadow base
666     OutStreamer->emitInstruction(MCInstBuilder(RISCV::ADD)
667                                      .addReg(RISCV::X6)
668                                      .addReg(RISCV::X5)
669                                      .addReg(RISCV::X6),
670                                  MCSTI);
671     OutStreamer->emitInstruction(
672         MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
673         MCSTI);
674     // Extract tag from X5 and compare it with loaded tag from shadow
675     OutStreamer->emitInstruction(
676         MCInstBuilder(RISCV::SRLI).addReg(RISCV::X7).addReg(Reg).addImm(56),
677         MCSTI);
678     MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
679     // X7 contains tag from memory, while X6 contains tag from the pointer
680     OutStreamer->emitInstruction(
681         MCInstBuilder(RISCV::BNE)
682             .addReg(RISCV::X7)
683             .addReg(RISCV::X6)
684             .addExpr(MCSymbolRefExpr::create(HandleMismatchOrPartialSym,
685                                              OutContext)),
686         MCSTI);
687     MCSymbol *ReturnSym = OutContext.createTempSymbol();
688     OutStreamer->emitLabel(ReturnSym);
689     OutStreamer->emitInstruction(MCInstBuilder(RISCV::JALR)
690                                      .addReg(RISCV::X0)
691                                      .addReg(RISCV::X1)
692                                      .addImm(0),
693                                  MCSTI);
694     OutStreamer->emitLabel(HandleMismatchOrPartialSym);
695 
696     OutStreamer->emitInstruction(MCInstBuilder(RISCV::ADDI)
697                                      .addReg(RISCV::X28)
698                                      .addReg(RISCV::X0)
699                                      .addImm(16),
700                                  MCSTI);
701     MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
702     OutStreamer->emitInstruction(
703         MCInstBuilder(RISCV::BGEU)
704             .addReg(RISCV::X6)
705             .addReg(RISCV::X28)
706             .addExpr(MCSymbolRefExpr::create(HandleMismatchSym, OutContext)),
707         MCSTI);
708 
709     OutStreamer->emitInstruction(
710         MCInstBuilder(RISCV::ANDI).addReg(RISCV::X28).addReg(Reg).addImm(0xF),
711         MCSTI);
712 
713     if (Size != 1)
714       OutStreamer->emitInstruction(MCInstBuilder(RISCV::ADDI)
715                                        .addReg(RISCV::X28)
716                                        .addReg(RISCV::X28)
717                                        .addImm(Size - 1),
718                                    MCSTI);
719     OutStreamer->emitInstruction(
720         MCInstBuilder(RISCV::BGE)
721             .addReg(RISCV::X28)
722             .addReg(RISCV::X6)
723             .addExpr(MCSymbolRefExpr::create(HandleMismatchSym, OutContext)),
724         MCSTI);
725 
726     OutStreamer->emitInstruction(
727         MCInstBuilder(RISCV::ORI).addReg(RISCV::X6).addReg(Reg).addImm(0xF),
728         MCSTI);
729     OutStreamer->emitInstruction(
730         MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
731         MCSTI);
732     OutStreamer->emitInstruction(
733         MCInstBuilder(RISCV::BEQ)
734             .addReg(RISCV::X6)
735             .addReg(RISCV::X7)
736             .addExpr(MCSymbolRefExpr::create(ReturnSym, OutContext)),
737         MCSTI);
738 
739     OutStreamer->emitLabel(HandleMismatchSym);
740 
741     // | Previous stack frames...        |
742     // +=================================+ <-- [SP + 256]
743     // |              ...                |
744     // |                                 |
745     // | Stack frame space for x12 - x31.|
746     // |                                 |
747     // |              ...                |
748     // +---------------------------------+ <-- [SP + 96]
749     // | Saved x11(arg1), as             |
750     // | __hwasan_check_* clobbers it.   |
751     // +---------------------------------+ <-- [SP + 88]
752     // | Saved x10(arg0), as             |
753     // | __hwasan_check_* clobbers it.   |
754     // +---------------------------------+ <-- [SP + 80]
755     // |                                 |
756     // | Stack frame space for x9.       |
757     // +---------------------------------+ <-- [SP + 72]
758     // |                                 |
759     // | Saved x8(fp), as                |
760     // | __hwasan_check_* clobbers it.   |
761     // +---------------------------------+ <-- [SP + 64]
762     // |              ...                |
763     // |                                 |
764     // | Stack frame space for x2 - x7.  |
765     // |                                 |
766     // |              ...                |
767     // +---------------------------------+ <-- [SP + 16]
768     // | Return address (x1) for caller  |
769     // | of __hwasan_check_*.            |
770     // +---------------------------------+ <-- [SP + 8]
771     // | Reserved place for x0, possibly |
772     // | junk, since we don't save it.   |
773     // +---------------------------------+ <-- [x2 / SP]
774 
775     // Adjust sp
776     OutStreamer->emitInstruction(MCInstBuilder(RISCV::ADDI)
777                                      .addReg(RISCV::X2)
778                                      .addReg(RISCV::X2)
779                                      .addImm(-256),
780                                  MCSTI);
781 
782     // store x10(arg0) by new sp
783     OutStreamer->emitInstruction(MCInstBuilder(RISCV::SD)
784                                      .addReg(RISCV::X10)
785                                      .addReg(RISCV::X2)
786                                      .addImm(8 * 10),
787                                  MCSTI);
788     // store x11(arg1) by new sp
789     OutStreamer->emitInstruction(MCInstBuilder(RISCV::SD)
790                                      .addReg(RISCV::X11)
791                                      .addReg(RISCV::X2)
792                                      .addImm(8 * 11),
793                                  MCSTI);
794 
795     // store x8(fp) by new sp
796     OutStreamer->emitInstruction(
797         MCInstBuilder(RISCV::SD).addReg(RISCV::X8).addReg(RISCV::X2).addImm(8 *
798                                                                             8),
799         MCSTI);
800     // store x1(ra) by new sp
801     OutStreamer->emitInstruction(
802         MCInstBuilder(RISCV::SD).addReg(RISCV::X1).addReg(RISCV::X2).addImm(1 *
803                                                                             8),
804         MCSTI);
805     if (Reg != RISCV::X10)
806       OutStreamer->emitInstruction(MCInstBuilder(RISCV::ADDI)
807                                        .addReg(RISCV::X10)
808                                        .addReg(Reg)
809                                        .addImm(0),
810                                    MCSTI);
811     OutStreamer->emitInstruction(
812         MCInstBuilder(RISCV::ADDI)
813             .addReg(RISCV::X11)
814             .addReg(RISCV::X0)
815             .addImm(AccessInfo & HWASanAccessInfo::RuntimeMask),
816         MCSTI);
817 
818     OutStreamer->emitInstruction(MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr),
819                                  MCSTI);
820   }
821 }
822 
lowerSymbolOperand(const MachineOperand & MO,MCSymbol * Sym,const AsmPrinter & AP)823 static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
824                                     const AsmPrinter &AP) {
825   MCContext &Ctx = AP.OutContext;
826   RISCVMCExpr::VariantKind Kind;
827 
828   switch (MO.getTargetFlags()) {
829   default:
830     llvm_unreachable("Unknown target flag on GV operand");
831   case RISCVII::MO_None:
832     Kind = RISCVMCExpr::VK_RISCV_None;
833     break;
834   case RISCVII::MO_CALL:
835     Kind = RISCVMCExpr::VK_RISCV_CALL_PLT;
836     break;
837   case RISCVII::MO_LO:
838     Kind = RISCVMCExpr::VK_RISCV_LO;
839     break;
840   case RISCVII::MO_HI:
841     Kind = RISCVMCExpr::VK_RISCV_HI;
842     break;
843   case RISCVII::MO_PCREL_LO:
844     Kind = RISCVMCExpr::VK_RISCV_PCREL_LO;
845     break;
846   case RISCVII::MO_PCREL_HI:
847     Kind = RISCVMCExpr::VK_RISCV_PCREL_HI;
848     break;
849   case RISCVII::MO_GOT_HI:
850     Kind = RISCVMCExpr::VK_RISCV_GOT_HI;
851     break;
852   case RISCVII::MO_TPREL_LO:
853     Kind = RISCVMCExpr::VK_RISCV_TPREL_LO;
854     break;
855   case RISCVII::MO_TPREL_HI:
856     Kind = RISCVMCExpr::VK_RISCV_TPREL_HI;
857     break;
858   case RISCVII::MO_TPREL_ADD:
859     Kind = RISCVMCExpr::VK_RISCV_TPREL_ADD;
860     break;
861   case RISCVII::MO_TLS_GOT_HI:
862     Kind = RISCVMCExpr::VK_RISCV_TLS_GOT_HI;
863     break;
864   case RISCVII::MO_TLS_GD_HI:
865     Kind = RISCVMCExpr::VK_RISCV_TLS_GD_HI;
866     break;
867   case RISCVII::MO_TLSDESC_HI:
868     Kind = RISCVMCExpr::VK_RISCV_TLSDESC_HI;
869     break;
870   case RISCVII::MO_TLSDESC_LOAD_LO:
871     Kind = RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO;
872     break;
873   case RISCVII::MO_TLSDESC_ADD_LO:
874     Kind = RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO;
875     break;
876   case RISCVII::MO_TLSDESC_CALL:
877     Kind = RISCVMCExpr::VK_RISCV_TLSDESC_CALL;
878     break;
879   }
880 
881   const MCExpr *ME =
882       MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
883 
884   if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
885     ME = MCBinaryExpr::createAdd(
886         ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
887 
888   if (Kind != RISCVMCExpr::VK_RISCV_None)
889     ME = RISCVMCExpr::create(ME, Kind, Ctx);
890   return MCOperand::createExpr(ME);
891 }
892 
lowerOperand(const MachineOperand & MO,MCOperand & MCOp) const893 bool RISCVAsmPrinter::lowerOperand(const MachineOperand &MO,
894                                    MCOperand &MCOp) const {
895   switch (MO.getType()) {
896   default:
897     report_fatal_error("lowerOperand: unknown operand type");
898   case MachineOperand::MO_Register:
899     // Ignore all implicit register operands.
900     if (MO.isImplicit())
901       return false;
902     MCOp = MCOperand::createReg(MO.getReg());
903     break;
904   case MachineOperand::MO_RegisterMask:
905     // Regmasks are like implicit defs.
906     return false;
907   case MachineOperand::MO_Immediate:
908     MCOp = MCOperand::createImm(MO.getImm());
909     break;
910   case MachineOperand::MO_MachineBasicBlock:
911     MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), *this);
912     break;
913   case MachineOperand::MO_GlobalAddress:
914     MCOp = lowerSymbolOperand(MO, getSymbolPreferLocal(*MO.getGlobal()), *this);
915     break;
916   case MachineOperand::MO_BlockAddress:
917     MCOp = lowerSymbolOperand(MO, GetBlockAddressSymbol(MO.getBlockAddress()),
918                               *this);
919     break;
920   case MachineOperand::MO_ExternalSymbol:
921     MCOp = lowerSymbolOperand(MO, GetExternalSymbolSymbol(MO.getSymbolName()),
922                               *this);
923     break;
924   case MachineOperand::MO_ConstantPoolIndex:
925     MCOp = lowerSymbolOperand(MO, GetCPISymbol(MO.getIndex()), *this);
926     break;
927   case MachineOperand::MO_JumpTableIndex:
928     MCOp = lowerSymbolOperand(MO, GetJTISymbol(MO.getIndex()), *this);
929     break;
930   case MachineOperand::MO_MCSymbol:
931     MCOp = lowerSymbolOperand(MO, MO.getMCSymbol(), *this);
932     break;
933   }
934   return true;
935 }
936 
lowerRISCVVMachineInstrToMCInst(const MachineInstr * MI,MCInst & OutMI)937 static bool lowerRISCVVMachineInstrToMCInst(const MachineInstr *MI,
938                                             MCInst &OutMI) {
939   const RISCVVPseudosTable::PseudoInfo *RVV =
940       RISCVVPseudosTable::getPseudoInfo(MI->getOpcode());
941   if (!RVV)
942     return false;
943 
944   OutMI.setOpcode(RVV->BaseInstr);
945 
946   const MachineBasicBlock *MBB = MI->getParent();
947   assert(MBB && "MI expected to be in a basic block");
948   const MachineFunction *MF = MBB->getParent();
949   assert(MF && "MBB expected to be in a machine function");
950 
951   const RISCVSubtarget &Subtarget = MF->getSubtarget<RISCVSubtarget>();
952   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
953   const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
954   assert(TRI && "TargetRegisterInfo expected");
955 
956   const MCInstrDesc &MCID = MI->getDesc();
957   uint64_t TSFlags = MCID.TSFlags;
958   unsigned NumOps = MI->getNumExplicitOperands();
959 
960   // Skip policy, SEW, VL, VXRM/FRM operands which are the last operands if
961   // present.
962   if (RISCVII::hasVecPolicyOp(TSFlags))
963     --NumOps;
964   if (RISCVII::hasSEWOp(TSFlags))
965     --NumOps;
966   if (RISCVII::hasVLOp(TSFlags))
967     --NumOps;
968   if (RISCVII::hasRoundModeOp(TSFlags))
969     --NumOps;
970 
971   bool hasVLOutput = RISCV::isFaultFirstLoad(*MI);
972   for (unsigned OpNo = 0; OpNo != NumOps; ++OpNo) {
973     const MachineOperand &MO = MI->getOperand(OpNo);
974     // Skip vl ouput. It should be the second output.
975     if (hasVLOutput && OpNo == 1)
976       continue;
977 
978     // Skip merge op. It should be the first operand after the defs.
979     if (OpNo == MI->getNumExplicitDefs() && MO.isReg() && MO.isTied()) {
980       assert(MCID.getOperandConstraint(OpNo, MCOI::TIED_TO) == 0 &&
981              "Expected tied to first def.");
982       const MCInstrDesc &OutMCID = TII->get(OutMI.getOpcode());
983       // Skip if the next operand in OutMI is not supposed to be tied. Unless it
984       // is a _TIED instruction.
985       if (OutMCID.getOperandConstraint(OutMI.getNumOperands(), MCOI::TIED_TO) <
986               0 &&
987           !RISCVII::isTiedPseudo(TSFlags))
988         continue;
989     }
990 
991     MCOperand MCOp;
992     switch (MO.getType()) {
993     default:
994       llvm_unreachable("Unknown operand type");
995     case MachineOperand::MO_Register: {
996       Register Reg = MO.getReg();
997 
998       if (RISCV::VRM2RegClass.contains(Reg) ||
999           RISCV::VRM4RegClass.contains(Reg) ||
1000           RISCV::VRM8RegClass.contains(Reg)) {
1001         Reg = TRI->getSubReg(Reg, RISCV::sub_vrm1_0);
1002         assert(Reg && "Subregister does not exist");
1003       } else if (RISCV::FPR16RegClass.contains(Reg)) {
1004         Reg =
1005             TRI->getMatchingSuperReg(Reg, RISCV::sub_16, &RISCV::FPR32RegClass);
1006         assert(Reg && "Subregister does not exist");
1007       } else if (RISCV::FPR64RegClass.contains(Reg)) {
1008         Reg = TRI->getSubReg(Reg, RISCV::sub_32);
1009         assert(Reg && "Superregister does not exist");
1010       } else if (RISCV::VRN2M1RegClass.contains(Reg) ||
1011                  RISCV::VRN2M2RegClass.contains(Reg) ||
1012                  RISCV::VRN2M4RegClass.contains(Reg) ||
1013                  RISCV::VRN3M1RegClass.contains(Reg) ||
1014                  RISCV::VRN3M2RegClass.contains(Reg) ||
1015                  RISCV::VRN4M1RegClass.contains(Reg) ||
1016                  RISCV::VRN4M2RegClass.contains(Reg) ||
1017                  RISCV::VRN5M1RegClass.contains(Reg) ||
1018                  RISCV::VRN6M1RegClass.contains(Reg) ||
1019                  RISCV::VRN7M1RegClass.contains(Reg) ||
1020                  RISCV::VRN8M1RegClass.contains(Reg)) {
1021         Reg = TRI->getSubReg(Reg, RISCV::sub_vrm1_0);
1022         assert(Reg && "Subregister does not exist");
1023       }
1024 
1025       MCOp = MCOperand::createReg(Reg);
1026       break;
1027     }
1028     case MachineOperand::MO_Immediate:
1029       MCOp = MCOperand::createImm(MO.getImm());
1030       break;
1031     }
1032     OutMI.addOperand(MCOp);
1033   }
1034 
1035   // Unmasked pseudo instructions need to append dummy mask operand to
1036   // V instructions. All V instructions are modeled as the masked version.
1037   const MCInstrDesc &OutMCID = TII->get(OutMI.getOpcode());
1038   if (OutMI.getNumOperands() < OutMCID.getNumOperands()) {
1039     assert(OutMCID.operands()[OutMI.getNumOperands()].RegClass ==
1040                RISCV::VMV0RegClassID &&
1041            "Expected only mask operand to be missing");
1042     OutMI.addOperand(MCOperand::createReg(RISCV::NoRegister));
1043   }
1044 
1045   assert(OutMI.getNumOperands() == OutMCID.getNumOperands());
1046   return true;
1047 }
1048 
lowerToMCInst(const MachineInstr * MI,MCInst & OutMI)1049 bool RISCVAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) {
1050   if (lowerRISCVVMachineInstrToMCInst(MI, OutMI))
1051     return false;
1052 
1053   OutMI.setOpcode(MI->getOpcode());
1054 
1055   for (const MachineOperand &MO : MI->operands()) {
1056     MCOperand MCOp;
1057     if (lowerOperand(MO, MCOp))
1058       OutMI.addOperand(MCOp);
1059   }
1060 
1061   switch (OutMI.getOpcode()) {
1062   case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1063     const Function &F = MI->getParent()->getParent()->getFunction();
1064     if (F.hasFnAttribute("patchable-function-entry")) {
1065       unsigned Num;
1066       if (F.getFnAttribute("patchable-function-entry")
1067               .getValueAsString()
1068               .getAsInteger(10, Num))
1069         return false;
1070       emitNops(Num);
1071       return true;
1072     }
1073     break;
1074   }
1075   }
1076   return false;
1077 }
1078