LLVM 18.0.0git
RISCVAsmPrinter.cpp
Go to the documentation of this file.
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
18#include "RISCV.h"
20#include "RISCVTargetMachine.h"
22#include "llvm/ADT/APInt.h"
23#include "llvm/ADT/Statistic.h"
30#include "llvm/MC/MCAsmInfo.h"
31#include "llvm/MC/MCContext.h"
32#include "llvm/MC/MCInst.h"
36#include "llvm/MC/MCStreamer.h"
37#include "llvm/MC/MCSymbol.h"
42
43using namespace llvm;
44
45#define DEBUG_TYPE "asm-printer"
46
47STATISTIC(RISCVNumInstrsCompressed,
48 "Number of RISC-V Compressed instructions emitted");
49
50namespace llvm {
51extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
52} // namespace llvm
53
54namespace {
55class RISCVAsmPrinter : public AsmPrinter {
56 const RISCVSubtarget *STI;
57
58public:
59 explicit RISCVAsmPrinter(TargetMachine &TM,
60 std::unique_ptr<MCStreamer> Streamer)
61 : AsmPrinter(TM, std::move(Streamer)) {}
62
63 StringRef getPassName() const override { return "RISC-V Assembly Printer"; }
64
65 void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
66 const MachineInstr &MI);
67
68 void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
69 const MachineInstr &MI);
70
71 void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
72 const MachineInstr &MI);
73
74 bool runOnMachineFunction(MachineFunction &MF) override;
75
76 void emitInstruction(const MachineInstr *MI) override;
77
78 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
79 const char *ExtraCode, raw_ostream &OS) override;
80 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
81 const char *ExtraCode, raw_ostream &OS) override;
82
83 void EmitToStreamer(MCStreamer &S, const MCInst &Inst);
84 bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
85 const MachineInstr *MI);
86
87 typedef std::tuple<unsigned, uint32_t> HwasanMemaccessTuple;
88 std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
89 void LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI);
90 void LowerKCFI_CHECK(const MachineInstr &MI);
91 void EmitHwasanMemaccessSymbols(Module &M);
92
93 // Wrapper needed for tblgenned pseudo lowering.
94 bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const;
95
96 void emitStartOfAsmFile(Module &M) override;
97 void emitEndOfAsmFile(Module &M) override;
98
99 void emitFunctionEntryLabel() override;
100 bool emitDirectiveOptionArch();
101
102private:
103 void emitAttributes();
104
105 void emitNTLHint(const MachineInstr *MI);
106
107 bool lowerToMCInst(const MachineInstr *MI, MCInst &OutMI);
108};
109}
110
111void RISCVAsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
112 const MachineInstr &MI) {
113 unsigned NOPBytes = STI->getFeatureBits()[RISCV::FeatureStdExtC] ? 2 : 4;
114 unsigned NumNOPBytes = StackMapOpers(&MI).getNumPatchBytes();
115
116 auto &Ctx = OutStreamer.getContext();
117 MCSymbol *MILabel = Ctx.createTempSymbol();
118 OutStreamer.emitLabel(MILabel);
119
120 SM.recordStackMap(*MILabel, MI);
121 assert(NumNOPBytes % NOPBytes == 0 &&
122 "Invalid number of NOP bytes requested!");
123
124 // Scan ahead to trim the shadow.
125 const MachineBasicBlock &MBB = *MI.getParent();
127 ++MII;
128 while (NumNOPBytes > 0) {
129 if (MII == MBB.end() || MII->isCall() ||
130 MII->getOpcode() == RISCV::DBG_VALUE ||
131 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
132 MII->getOpcode() == TargetOpcode::STACKMAP)
133 break;
134 ++MII;
135 NumNOPBytes -= 4;
136 }
137
138 // Emit nops.
139 emitNops(NumNOPBytes / NOPBytes);
140}
141
142// Lower a patchpoint of the form:
143// [<def>], <id>, <numBytes>, <target>, <numArgs>
144void RISCVAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
145 const MachineInstr &MI) {
146 unsigned NOPBytes = STI->getFeatureBits()[RISCV::FeatureStdExtC] ? 2 : 4;
147
148 auto &Ctx = OutStreamer.getContext();
149 MCSymbol *MILabel = Ctx.createTempSymbol();
150 OutStreamer.emitLabel(MILabel);
151 SM.recordPatchPoint(*MILabel, MI);
152
153 PatchPointOpers Opers(&MI);
154
155 unsigned EncodedBytes = 0;
156
157 // Emit padding.
158 unsigned NumBytes = Opers.getNumPatchBytes();
159 assert(NumBytes >= EncodedBytes &&
160 "Patchpoint can't request size less than the length of a call.");
161 assert((NumBytes - EncodedBytes) % NOPBytes == 0 &&
162 "Invalid number of NOP bytes requested!");
163 emitNops((NumBytes - EncodedBytes) / NOPBytes);
164}
165
166void RISCVAsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
167 const MachineInstr &MI) {
168 unsigned NOPBytes = STI->getFeatureBits()[RISCV::FeatureStdExtC] ? 2 : 4;
169
170 StatepointOpers SOpers(&MI);
171 if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {
172 assert(PatchBytes % NOPBytes == 0 &&
173 "Invalid number of NOP bytes requested!");
174 emitNops(PatchBytes / NOPBytes);
175 }
176
177 auto &Ctx = OutStreamer.getContext();
178 MCSymbol *MILabel = Ctx.createTempSymbol();
179 OutStreamer.emitLabel(MILabel);
180 SM.recordStatepoint(*MILabel, MI);
181}
182
183void RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {
184 MCInst CInst;
185 bool Res = RISCVRVC::compress(CInst, Inst, *STI);
186 if (Res)
187 ++RISCVNumInstrsCompressed;
188 AsmPrinter::EmitToStreamer(*OutStreamer, Res ? CInst : Inst);
189}
190
191// Simple pseudo-instructions have their lowering (with expansion to real
192// instructions) auto-generated.
193#include "RISCVGenMCPseudoLowering.inc"
194
195// If the target supports Zihintntl and the instruction has a nontemporal
196// MachineMemOperand, emit an NTLH hint instruction before it.
197void RISCVAsmPrinter::emitNTLHint(const MachineInstr *MI) {
198 if (!STI->hasStdExtZihintntl())
199 return;
200
201 if (MI->memoperands_empty())
202 return;
203
204 MachineMemOperand *MMO = *(MI->memoperands_begin());
205 if (!MMO->isNonTemporal())
206 return;
207
208 unsigned NontemporalMode = 0;
209 if (MMO->getFlags() & MONontemporalBit0)
210 NontemporalMode += 0b1;
211 if (MMO->getFlags() & MONontemporalBit1)
212 NontemporalMode += 0b10;
213
214 MCInst Hint;
215 if (STI->hasStdExtCOrZca() && STI->enableRVCHintInstrs())
216 Hint.setOpcode(RISCV::C_ADD_HINT);
217 else
218 Hint.setOpcode(RISCV::ADD);
219
220 Hint.addOperand(MCOperand::createReg(RISCV::X0));
221 Hint.addOperand(MCOperand::createReg(RISCV::X0));
222 Hint.addOperand(MCOperand::createReg(RISCV::X2 + NontemporalMode));
223
224 EmitToStreamer(*OutStreamer, Hint);
225}
226
227void RISCVAsmPrinter::emitInstruction(const MachineInstr *MI) {
228 RISCV_MC::verifyInstructionPredicates(MI->getOpcode(),
229 getSubtargetInfo().getFeatureBits());
230
231 emitNTLHint(MI);
232
233 // Do any auto-generated pseudo lowerings.
234 if (emitPseudoExpansionLowering(*OutStreamer, MI))
235 return;
236
237
238 switch (MI->getOpcode()) {
239 case RISCV::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
240 LowerHWASAN_CHECK_MEMACCESS(*MI);
241 return;
242 case RISCV::KCFI_CHECK:
243 LowerKCFI_CHECK(*MI);
244 return;
245 case RISCV::PseudoRVVInitUndefM1:
246 case RISCV::PseudoRVVInitUndefM2:
247 case RISCV::PseudoRVVInitUndefM4:
248 case RISCV::PseudoRVVInitUndefM8:
249 return;
250 case TargetOpcode::STACKMAP:
251 return LowerSTACKMAP(*OutStreamer, SM, *MI);
252 case TargetOpcode::PATCHPOINT:
253 return LowerPATCHPOINT(*OutStreamer, SM, *MI);
254 case TargetOpcode::STATEPOINT:
255 return LowerSTATEPOINT(*OutStreamer, SM, *MI);
256 }
257
258 MCInst OutInst;
259 if (!lowerToMCInst(MI, OutInst))
260 EmitToStreamer(*OutStreamer, OutInst);
261}
262
263bool RISCVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
264 const char *ExtraCode, raw_ostream &OS) {
265 // First try the generic code, which knows about modifiers like 'c' and 'n'.
266 if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
267 return false;
268
269 const MachineOperand &MO = MI->getOperand(OpNo);
270 if (ExtraCode && ExtraCode[0]) {
271 if (ExtraCode[1] != 0)
272 return true; // Unknown modifier.
273
274 switch (ExtraCode[0]) {
275 default:
276 return true; // Unknown modifier.
277 case 'z': // Print zero register if zero, regular printing otherwise.
278 if (MO.isImm() && MO.getImm() == 0) {
280 return false;
281 }
282 break;
283 case 'i': // Literal 'i' if operand is not a register.
284 if (!MO.isReg())
285 OS << 'i';
286 return false;
287 }
288 }
289
290 switch (MO.getType()) {
292 OS << MO.getImm();
293 return false;
296 return false;
298 PrintSymbolOperand(MO, OS);
299 return false;
301 MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
302 Sym->print(OS, MAI);
303 return false;
304 }
305 default:
306 break;
307 }
308
309 return true;
310}
311
312bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
313 unsigned OpNo,
314 const char *ExtraCode,
315 raw_ostream &OS) {
316 if (ExtraCode)
317 return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS);
318
319 const MachineOperand &AddrReg = MI->getOperand(OpNo);
320 assert(MI->getNumOperands() > OpNo + 1 && "Expected additional operand");
321 const MachineOperand &Offset = MI->getOperand(OpNo + 1);
322 // All memory operands should have a register and an immediate operand (see
323 // RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand).
324 if (!AddrReg.isReg())
325 return true;
326 if (!Offset.isImm() && !Offset.isGlobal() && !Offset.isBlockAddress())
327 return true;
328
329 MCOperand MCO;
330 if (!lowerOperand(Offset, MCO))
331 return true;
332
333 if (Offset.isImm())
334 OS << MCO.getImm();
335 else if (Offset.isGlobal() || Offset.isBlockAddress())
336 OS << *MCO.getExpr();
337 OS << "(" << RISCVInstPrinter::getRegisterName(AddrReg.getReg()) << ")";
338 return false;
339}
340
341bool RISCVAsmPrinter::emitDirectiveOptionArch() {
343 static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
344 SmallVector<RISCVOptionArchArg> NeedEmitStdOptionArgs;
345 const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
346 for (const auto &Feature : RISCVFeatureKV) {
347 if (STI->hasFeature(Feature.Value) == MCSTI.hasFeature(Feature.Value))
348 continue;
349
351 continue;
352
353 auto Delta = STI->hasFeature(Feature.Value) ? RISCVOptionArchArgType::Plus
354 : RISCVOptionArchArgType::Minus;
355 NeedEmitStdOptionArgs.emplace_back(Delta, Feature.Key);
356 }
357 if (!NeedEmitStdOptionArgs.empty()) {
359 RTS.emitDirectiveOptionArch(NeedEmitStdOptionArgs);
360 return true;
361 }
362
363 return false;
364}
365
366bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
367 STI = &MF.getSubtarget<RISCVSubtarget>();
369 static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
370
371 bool EmittedOptionArch = emitDirectiveOptionArch();
372
373 SetupMachineFunction(MF);
374 emitFunctionBody();
375
376 if (EmittedOptionArch)
377 RTS.emitDirectiveOptionPop();
378 return false;
379}
380
381void RISCVAsmPrinter::emitStartOfAsmFile(Module &M) {
383 static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
384 if (const MDString *ModuleTargetABI =
385 dyn_cast_or_null<MDString>(M.getModuleFlag("target-abi")))
386 RTS.setTargetABI(RISCVABI::getTargetABI(ModuleTargetABI->getString()));
387 if (TM.getTargetTriple().isOSBinFormatELF())
388 emitAttributes();
389}
390
391void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) {
393 static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
394
395 if (TM.getTargetTriple().isOSBinFormatELF())
397 EmitHwasanMemaccessSymbols(M);
398}
399
400void RISCVAsmPrinter::emitAttributes() {
402 static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
403 // Use MCSubtargetInfo from TargetMachine. Individual functions may have
404 // attributes that differ from other functions in the module and we have no
405 // way to know which function is correct.
406 RTS.emitTargetAttributes(*TM.getMCSubtargetInfo(), /*EmitStackAlign*/ true);
407}
408
409void RISCVAsmPrinter::emitFunctionEntryLabel() {
410 const auto *RMFI = MF->getInfo<RISCVMachineFunctionInfo>();
411 if (RMFI->isVectorCall()) {
412 auto &RTS =
413 static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
414 RTS.emitDirectiveVariantCC(*CurrentFnSym);
415 }
417}
418
419// Force static initialization.
423}
424
425void RISCVAsmPrinter::LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI) {
426 Register Reg = MI.getOperand(0).getReg();
427 uint32_t AccessInfo = MI.getOperand(1).getImm();
428 MCSymbol *&Sym =
429 HwasanMemaccessSymbols[HwasanMemaccessTuple(Reg, AccessInfo)];
430 if (!Sym) {
431 // FIXME: Make this work on non-ELF.
432 if (!TM.getTargetTriple().isOSBinFormatELF())
433 report_fatal_error("llvm.hwasan.check.memaccess only supported on ELF");
434
435 std::string SymName = "__hwasan_check_x" + utostr(Reg - RISCV::X0) + "_" +
436 utostr(AccessInfo) + "_short";
437 Sym = OutContext.getOrCreateSymbol(SymName);
438 }
440 auto Expr = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, OutContext);
441
442 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr));
443}
444
445void RISCVAsmPrinter::LowerKCFI_CHECK(const MachineInstr &MI) {
446 Register AddrReg = MI.getOperand(0).getReg();
447 assert(std::next(MI.getIterator())->isCall() &&
448 "KCFI_CHECK not followed by a call instruction");
449 assert(std::next(MI.getIterator())->getOperand(0).getReg() == AddrReg &&
450 "KCFI_CHECK call target doesn't match call operand");
451
452 // Temporary registers for comparing the hashes. If a register is used
453 // for the call target, or reserved by the user, we can clobber another
454 // temporary register as the check is immediately followed by the
455 // call. The check defaults to X6/X7, but can fall back to X28-X31 if
456 // needed.
457 unsigned ScratchRegs[] = {RISCV::X6, RISCV::X7};
458 unsigned NextReg = RISCV::X28;
459 auto isRegAvailable = [&](unsigned Reg) {
460 return Reg != AddrReg && !STI->isRegisterReservedByUser(Reg);
461 };
462 for (auto &Reg : ScratchRegs) {
463 if (isRegAvailable(Reg))
464 continue;
465 while (!isRegAvailable(NextReg))
466 ++NextReg;
467 Reg = NextReg++;
468 if (Reg > RISCV::X31)
469 report_fatal_error("Unable to find scratch registers for KCFI_CHECK");
470 }
471
472 if (AddrReg == RISCV::X0) {
473 // Checking X0 makes no sense. Instead of emitting a load, zero
474 // ScratchRegs[0].
475 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::ADDI)
476 .addReg(ScratchRegs[0])
477 .addReg(RISCV::X0)
478 .addImm(0));
479 } else {
480 // Adjust the offset for patchable-function-prefix. This assumes that
481 // patchable-function-prefix is the same for all functions.
482 int NopSize = STI->hasStdExtCOrZca() ? 2 : 4;
483 int64_t PrefixNops = 0;
484 (void)MI.getMF()
485 ->getFunction()
486 .getFnAttribute("patchable-function-prefix")
487 .getValueAsString()
488 .getAsInteger(10, PrefixNops);
489
490 // Load the target function type hash.
491 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::LW)
492 .addReg(ScratchRegs[0])
493 .addReg(AddrReg)
494 .addImm(-(PrefixNops * NopSize + 4)));
495 }
496
497 // Load the expected 32-bit type hash.
498 const int64_t Type = MI.getOperand(1).getImm();
499 const int64_t Hi20 = ((Type + 0x800) >> 12) & 0xFFFFF;
500 const int64_t Lo12 = SignExtend64<12>(Type);
501 if (Hi20) {
502 EmitToStreamer(
503 *OutStreamer,
504 MCInstBuilder(RISCV::LUI).addReg(ScratchRegs[1]).addImm(Hi20));
505 }
506 if (Lo12 || Hi20 == 0) {
507 EmitToStreamer(*OutStreamer,
508 MCInstBuilder((STI->hasFeature(RISCV::Feature64Bit) && Hi20)
509 ? RISCV::ADDIW
510 : RISCV::ADDI)
511 .addReg(ScratchRegs[1])
512 .addReg(ScratchRegs[1])
513 .addImm(Lo12));
514 }
515
516 // Compare the hashes and trap if there's a mismatch.
517 MCSymbol *Pass = OutContext.createTempSymbol();
518 EmitToStreamer(*OutStreamer,
519 MCInstBuilder(RISCV::BEQ)
520 .addReg(ScratchRegs[0])
521 .addReg(ScratchRegs[1])
522 .addExpr(MCSymbolRefExpr::create(Pass, OutContext)));
523
524 MCSymbol *Trap = OutContext.createTempSymbol();
525 OutStreamer->emitLabel(Trap);
526 EmitToStreamer(*OutStreamer, MCInstBuilder(RISCV::EBREAK));
527 emitKCFITrapEntry(*MI.getMF(), Trap);
528 OutStreamer->emitLabel(Pass);
529}
530
531void RISCVAsmPrinter::EmitHwasanMemaccessSymbols(Module &M) {
532 if (HwasanMemaccessSymbols.empty())
533 return;
534
535 assert(TM.getTargetTriple().isOSBinFormatELF());
536 // Use MCSubtargetInfo from TargetMachine. Individual functions may have
537 // attributes that differ from other functions in the module and we have no
538 // way to know which function is correct.
539 const MCSubtargetInfo &MCSTI = *TM.getMCSubtargetInfo();
540
541 MCSymbol *HwasanTagMismatchV2Sym =
542 OutContext.getOrCreateSymbol("__hwasan_tag_mismatch_v2");
543 // Annotate symbol as one having incompatible calling convention, so
544 // run-time linkers can instead eagerly bind this function.
545 auto &RTS =
546 static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
547 RTS.emitDirectiveVariantCC(*HwasanTagMismatchV2Sym);
548
549 const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
550 MCSymbolRefExpr::create(HwasanTagMismatchV2Sym, OutContext);
551 auto Expr = RISCVMCExpr::create(HwasanTagMismatchV2Ref,
552 RISCVMCExpr::VK_RISCV_CALL, OutContext);
553
554 for (auto &P : HwasanMemaccessSymbols) {
555 unsigned Reg = std::get<0>(P.first);
556 uint32_t AccessInfo = std::get<1>(P.first);
557 MCSymbol *Sym = P.second;
558
559 unsigned Size =
560 1 << ((AccessInfo >> HWASanAccessInfo::AccessSizeShift) & 0xf);
561 OutStreamer->switchSection(OutContext.getELFSection(
562 ".text.hot", ELF::SHT_PROGBITS,
564 /*IsComdat=*/true));
565
567 OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak);
568 OutStreamer->emitSymbolAttribute(Sym, MCSA_Hidden);
569 OutStreamer->emitLabel(Sym);
570
571 // Extract shadow offset from ptr
572 OutStreamer->emitInstruction(
573 MCInstBuilder(RISCV::SLLI).addReg(RISCV::X6).addReg(Reg).addImm(8),
574 MCSTI);
575 OutStreamer->emitInstruction(MCInstBuilder(RISCV::SRLI)
576 .addReg(RISCV::X6)
577 .addReg(RISCV::X6)
578 .addImm(12),
579 MCSTI);
580 // load shadow tag in X6, X5 contains shadow base
581 OutStreamer->emitInstruction(MCInstBuilder(RISCV::ADD)
582 .addReg(RISCV::X6)
583 .addReg(RISCV::X5)
584 .addReg(RISCV::X6),
585 MCSTI);
586 OutStreamer->emitInstruction(
587 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
588 MCSTI);
589 // Extract tag from X5 and compare it with loaded tag from shadow
590 OutStreamer->emitInstruction(
591 MCInstBuilder(RISCV::SRLI).addReg(RISCV::X7).addReg(Reg).addImm(56),
592 MCSTI);
593 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
594 // X7 contains tag from memory, while X6 contains tag from the pointer
595 OutStreamer->emitInstruction(
596 MCInstBuilder(RISCV::BNE)
597 .addReg(RISCV::X7)
598 .addReg(RISCV::X6)
599 .addExpr(MCSymbolRefExpr::create(HandleMismatchOrPartialSym,
600 OutContext)),
601 MCSTI);
602 MCSymbol *ReturnSym = OutContext.createTempSymbol();
603 OutStreamer->emitLabel(ReturnSym);
604 OutStreamer->emitInstruction(MCInstBuilder(RISCV::JALR)
605 .addReg(RISCV::X0)
606 .addReg(RISCV::X1)
607 .addImm(0),
608 MCSTI);
609 OutStreamer->emitLabel(HandleMismatchOrPartialSym);
610
611 OutStreamer->emitInstruction(MCInstBuilder(RISCV::ADDI)
612 .addReg(RISCV::X28)
613 .addReg(RISCV::X0)
614 .addImm(16),
615 MCSTI);
616 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
617 OutStreamer->emitInstruction(
618 MCInstBuilder(RISCV::BGEU)
619 .addReg(RISCV::X6)
620 .addReg(RISCV::X28)
621 .addExpr(MCSymbolRefExpr::create(HandleMismatchSym, OutContext)),
622 MCSTI);
623
624 OutStreamer->emitInstruction(
625 MCInstBuilder(RISCV::ANDI).addReg(RISCV::X28).addReg(Reg).addImm(0xF),
626 MCSTI);
627
628 if (Size != 1)
629 OutStreamer->emitInstruction(MCInstBuilder(RISCV::ADDI)
630 .addReg(RISCV::X28)
631 .addReg(RISCV::X28)
632 .addImm(Size - 1),
633 MCSTI);
634 OutStreamer->emitInstruction(
635 MCInstBuilder(RISCV::BGE)
636 .addReg(RISCV::X28)
637 .addReg(RISCV::X6)
638 .addExpr(MCSymbolRefExpr::create(HandleMismatchSym, OutContext)),
639 MCSTI);
640
641 OutStreamer->emitInstruction(
642 MCInstBuilder(RISCV::ORI).addReg(RISCV::X6).addReg(Reg).addImm(0xF),
643 MCSTI);
644 OutStreamer->emitInstruction(
645 MCInstBuilder(RISCV::LBU).addReg(RISCV::X6).addReg(RISCV::X6).addImm(0),
646 MCSTI);
647 OutStreamer->emitInstruction(
648 MCInstBuilder(RISCV::BEQ)
649 .addReg(RISCV::X6)
650 .addReg(RISCV::X7)
651 .addExpr(MCSymbolRefExpr::create(ReturnSym, OutContext)),
652 MCSTI);
653
654 OutStreamer->emitLabel(HandleMismatchSym);
655
656 // | Previous stack frames... |
657 // +=================================+ <-- [SP + 256]
658 // | ... |
659 // | |
660 // | Stack frame space for x12 - x31.|
661 // | |
662 // | ... |
663 // +---------------------------------+ <-- [SP + 96]
664 // | Saved x11(arg1), as |
665 // | __hwasan_check_* clobbers it. |
666 // +---------------------------------+ <-- [SP + 88]
667 // | Saved x10(arg0), as |
668 // | __hwasan_check_* clobbers it. |
669 // +---------------------------------+ <-- [SP + 80]
670 // | |
671 // | Stack frame space for x9. |
672 // +---------------------------------+ <-- [SP + 72]
673 // | |
674 // | Saved x8(fp), as |
675 // | __hwasan_check_* clobbers it. |
676 // +---------------------------------+ <-- [SP + 64]
677 // | ... |
678 // | |
679 // | Stack frame space for x2 - x7. |
680 // | |
681 // | ... |
682 // +---------------------------------+ <-- [SP + 16]
683 // | Return address (x1) for caller |
684 // | of __hwasan_check_*. |
685 // +---------------------------------+ <-- [SP + 8]
686 // | Reserved place for x0, possibly |
687 // | junk, since we don't save it. |
688 // +---------------------------------+ <-- [x2 / SP]
689
690 // Adjust sp
691 OutStreamer->emitInstruction(MCInstBuilder(RISCV::ADDI)
692 .addReg(RISCV::X2)
693 .addReg(RISCV::X2)
694 .addImm(-256),
695 MCSTI);
696
697 // store x10(arg0) by new sp
698 OutStreamer->emitInstruction(MCInstBuilder(RISCV::SD)
699 .addReg(RISCV::X10)
700 .addReg(RISCV::X2)
701 .addImm(8 * 10),
702 MCSTI);
703 // store x11(arg1) by new sp
704 OutStreamer->emitInstruction(MCInstBuilder(RISCV::SD)
705 .addReg(RISCV::X11)
706 .addReg(RISCV::X2)
707 .addImm(8 * 11),
708 MCSTI);
709
710 // store x8(fp) by new sp
711 OutStreamer->emitInstruction(
712 MCInstBuilder(RISCV::SD).addReg(RISCV::X8).addReg(RISCV::X2).addImm(8 *
713 8),
714 MCSTI);
715 // store x1(ra) by new sp
716 OutStreamer->emitInstruction(
717 MCInstBuilder(RISCV::SD).addReg(RISCV::X1).addReg(RISCV::X2).addImm(1 *
718 8),
719 MCSTI);
720 if (Reg != RISCV::X10)
721 OutStreamer->emitInstruction(MCInstBuilder(RISCV::ADDI)
722 .addReg(RISCV::X10)
723 .addReg(Reg)
724 .addImm(0),
725 MCSTI);
726 OutStreamer->emitInstruction(
727 MCInstBuilder(RISCV::ADDI)
728 .addReg(RISCV::X11)
729 .addReg(RISCV::X0)
731 MCSTI);
732
733 OutStreamer->emitInstruction(MCInstBuilder(RISCV::PseudoCALL).addExpr(Expr),
734 MCSTI);
735 }
736}
737
739 const AsmPrinter &AP) {
740 MCContext &Ctx = AP.OutContext;
742
743 switch (MO.getTargetFlags()) {
744 default:
745 llvm_unreachable("Unknown target flag on GV operand");
746 case RISCVII::MO_None:
748 break;
749 case RISCVII::MO_CALL:
751 break;
752 case RISCVII::MO_PLT:
754 break;
755 case RISCVII::MO_LO:
757 break;
758 case RISCVII::MO_HI:
760 break;
763 break;
766 break;
769 break;
772 break;
775 break;
778 break;
781 break;
784 break;
785 }
786
787 const MCExpr *ME =
789
790 if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
792 ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
793
794 if (Kind != RISCVMCExpr::VK_RISCV_None)
795 ME = RISCVMCExpr::create(ME, Kind, Ctx);
796 return MCOperand::createExpr(ME);
797}
798
799bool RISCVAsmPrinter::lowerOperand(const MachineOperand &MO,
800 MCOperand &MCOp) const {
801 switch (MO.getType()) {
802 default:
803 report_fatal_error("lowerOperand: unknown operand type");
805 // Ignore all implicit register operands.
806 if (MO.isImplicit())
807 return false;
808 MCOp = MCOperand::createReg(MO.getReg());
809 break;
811 // Regmasks are like implicit defs.
812 return false;
814 MCOp = MCOperand::createImm(MO.getImm());
815 break;
817 MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), *this);
818 break;
820 MCOp = lowerSymbolOperand(MO, getSymbolPreferLocal(*MO.getGlobal()), *this);
821 break;
823 MCOp = lowerSymbolOperand(MO, GetBlockAddressSymbol(MO.getBlockAddress()),
824 *this);
825 break;
827 MCOp = lowerSymbolOperand(MO, GetExternalSymbolSymbol(MO.getSymbolName()),
828 *this);
829 break;
831 MCOp = lowerSymbolOperand(MO, GetCPISymbol(MO.getIndex()), *this);
832 break;
834 MCOp = lowerSymbolOperand(MO, GetJTISymbol(MO.getIndex()), *this);
835 break;
837 MCOp = lowerSymbolOperand(MO, MO.getMCSymbol(), *this);
838 break;
839 }
840 return true;
841}
842
844 MCInst &OutMI) {
846 RISCVVPseudosTable::getPseudoInfo(MI->getOpcode());
847 if (!RVV)
848 return false;
849
850 OutMI.setOpcode(RVV->BaseInstr);
851
852 const MachineBasicBlock *MBB = MI->getParent();
853 assert(MBB && "MI expected to be in a basic block");
854 const MachineFunction *MF = MBB->getParent();
855 assert(MF && "MBB expected to be in a machine function");
856
857 const RISCVSubtarget &Subtarget = MF->getSubtarget<RISCVSubtarget>();
858 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
859 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
860 assert(TRI && "TargetRegisterInfo expected");
861
862 const MCInstrDesc &MCID = MI->getDesc();
863 uint64_t TSFlags = MCID.TSFlags;
864 unsigned NumOps = MI->getNumExplicitOperands();
865
866 // Skip policy, SEW, VL, VXRM/FRM operands which are the last operands if
867 // present.
868 if (RISCVII::hasVecPolicyOp(TSFlags))
869 --NumOps;
870 if (RISCVII::hasSEWOp(TSFlags))
871 --NumOps;
872 if (RISCVII::hasVLOp(TSFlags))
873 --NumOps;
874 if (RISCVII::hasRoundModeOp(TSFlags))
875 --NumOps;
876
877 bool hasVLOutput = RISCV::isFaultFirstLoad(*MI);
878 for (unsigned OpNo = 0; OpNo != NumOps; ++OpNo) {
879 const MachineOperand &MO = MI->getOperand(OpNo);
880 // Skip vl ouput. It should be the second output.
881 if (hasVLOutput && OpNo == 1)
882 continue;
883
884 // Skip merge op. It should be the first operand after the defs.
885 if (OpNo == MI->getNumExplicitDefs() && MO.isReg() && MO.isTied()) {
886 assert(MCID.getOperandConstraint(OpNo, MCOI::TIED_TO) == 0 &&
887 "Expected tied to first def.");
888 const MCInstrDesc &OutMCID = TII->get(OutMI.getOpcode());
889 // Skip if the next operand in OutMI is not supposed to be tied. Unless it
890 // is a _TIED instruction.
892 0 &&
893 !RISCVII::isTiedPseudo(TSFlags))
894 continue;
895 }
896
897 MCOperand MCOp;
898 switch (MO.getType()) {
899 default:
900 llvm_unreachable("Unknown operand type");
902 Register Reg = MO.getReg();
903
904 if (RISCV::VRM2RegClass.contains(Reg) ||
905 RISCV::VRM4RegClass.contains(Reg) ||
906 RISCV::VRM8RegClass.contains(Reg)) {
907 Reg = TRI->getSubReg(Reg, RISCV::sub_vrm1_0);
908 assert(Reg && "Subregister does not exist");
909 } else if (RISCV::FPR16RegClass.contains(Reg)) {
910 Reg =
911 TRI->getMatchingSuperReg(Reg, RISCV::sub_16, &RISCV::FPR32RegClass);
912 assert(Reg && "Subregister does not exist");
913 } else if (RISCV::FPR64RegClass.contains(Reg)) {
914 Reg = TRI->getSubReg(Reg, RISCV::sub_32);
915 assert(Reg && "Superregister does not exist");
916 } else if (RISCV::VRN2M1RegClass.contains(Reg) ||
917 RISCV::VRN2M2RegClass.contains(Reg) ||
918 RISCV::VRN2M4RegClass.contains(Reg) ||
919 RISCV::VRN3M1RegClass.contains(Reg) ||
920 RISCV::VRN3M2RegClass.contains(Reg) ||
921 RISCV::VRN4M1RegClass.contains(Reg) ||
922 RISCV::VRN4M2RegClass.contains(Reg) ||
923 RISCV::VRN5M1RegClass.contains(Reg) ||
924 RISCV::VRN6M1RegClass.contains(Reg) ||
925 RISCV::VRN7M1RegClass.contains(Reg) ||
926 RISCV::VRN8M1RegClass.contains(Reg)) {
927 Reg = TRI->getSubReg(Reg, RISCV::sub_vrm1_0);
928 assert(Reg && "Subregister does not exist");
929 }
930
931 MCOp = MCOperand::createReg(Reg);
932 break;
933 }
935 MCOp = MCOperand::createImm(MO.getImm());
936 break;
937 }
938 OutMI.addOperand(MCOp);
939 }
940
941 // Unmasked pseudo instructions need to append dummy mask operand to
942 // V instructions. All V instructions are modeled as the masked version.
943 const MCInstrDesc &OutMCID = TII->get(OutMI.getOpcode());
944 if (OutMI.getNumOperands() < OutMCID.getNumOperands()) {
945 assert(OutMCID.operands()[OutMI.getNumOperands()].RegClass ==
946 RISCV::VMV0RegClassID &&
947 "Expected only mask operand to be missing");
948 OutMI.addOperand(MCOperand::createReg(RISCV::NoRegister));
949 }
950
951 assert(OutMI.getNumOperands() == OutMCID.getNumOperands());
952 return true;
953}
954
955bool RISCVAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) {
957 return false;
958
959 OutMI.setOpcode(MI->getOpcode());
960
961 for (const MachineOperand &MO : MI->operands()) {
962 MCOperand MCOp;
963 if (lowerOperand(MO, MCOp))
964 OutMI.addOperand(MCOp);
965 }
966
967 switch (OutMI.getOpcode()) {
968 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
969 const Function &F = MI->getParent()->getParent()->getFunction();
970 if (F.hasFnAttribute("patchable-function-entry")) {
971 unsigned Num;
972 if (F.getFnAttribute("patchable-function-entry")
973 .getValueAsString()
974 .getAsInteger(10, Num))
975 return false;
976 emitNops(Num);
977 return true;
978 }
979 break;
980 }
981 }
982 return false;
983}
MachineBasicBlock & MBB
This file implements a class to represent arbitrary precision integral constant values and operations...
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:135
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:477
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned const TargetRegisterInfo * TRI
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
#define P(N)
const char LLVMTargetMachineRef TM
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmPrinter()
static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym, const AsmPrinter &AP)
static bool lowerRISCVVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:84
virtual void emitInstruction(const MachineInstr *)
Targets should implement this to emit instructions.
Definition: AsmPrinter.h:571
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:401
virtual void emitStartOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the start of their fi...
Definition: AsmPrinter.h:547
virtual void emitEndOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the end of their file...
Definition: AsmPrinter.h:551
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:94
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
Definition: AsmPrinter.h:399
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:528
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
Context object for machine code objects.
Definition: MCContext.h:76
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
Definition: MCInstBuilder.h:31
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:37
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Definition: MCInstBuilder.h:55
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
unsigned getNumOperands() const
Definition: MCInst.h:208
unsigned getOpcode() const
Definition: MCInst.h:198
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
void setOpcode(unsigned Op)
Definition: MCInst.h:197
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:237
ArrayRef< MCOperandInfo > operands() const
Definition: MCInstrDesc.h:239
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
Definition: MCInstrDesc.h:219
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
int64_t getImm() const
Definition: MCInst.h:80
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
const MCExpr * getExpr() const
Definition: MCInst.h:114
Streaming machine code generation interface.
Definition: MCStreamer.h:212
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.
MCContext & getContext() const
Definition: MCStreamer.h:297
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:424
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:304
virtual void switchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:389
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
A single uniqued string.
Definition: Metadata.h:698
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
Definition: MachineInstr.h:68
A description of a memory reference used in the backend.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
int64_t getImm() const
bool isImplicit() 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
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.
Definition: Module.h:65
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:94
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
MI-level patchpoint operands.
Definition: StackMaps.h:76
static bool isSupportedExtensionFeature(StringRef Ext)
static const char * getRegisterName(MCRegister Reg)
static const RISCVMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
Definition: RISCVMCExpr.cpp:31
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
virtual void emitDirectiveVariantCC(MCSymbol &Symbol)
void emitTargetAttributes(const MCSubtargetInfo &STI, bool EmitStackAlign)
void setTargetABI(RISCVABI::ABI ABI)
virtual void emitDirectiveOptionArch(ArrayRef< RISCVOptionArchArg > Args)
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
bool empty() const
Definition: SmallVector.h:94
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:941
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
MI-level stackmap operands.
Definition: StackMaps.h:35
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
Definition: StackMaps.h:50
void recordStatepoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a statepoint instruction.
Definition: StackMaps.cpp:575
void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
Definition: StackMaps.cpp:554
void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
Definition: StackMaps.cpp:544
MI-level Statepoint operands.
Definition: StackMaps.h:158
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
TargetInstrInfo - Interface to description of machine instruction set.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:78
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SHT_PROGBITS
Definition: ELF.h:1004
@ SHF_ALLOC
Definition: ELF.h:1093
@ SHF_GROUP
Definition: ELF.h:1115
@ SHF_EXECINSTR
Definition: ELF.h:1096
ABI getTargetABI(StringRef ABIName)
static bool hasRoundModeOp(uint64_t TSFlags)
static bool isTiedPseudo(uint64_t TSFlags)
static bool hasVLOp(uint64_t TSFlags)
static bool hasVecPolicyOp(uint64_t TSFlags)
static bool hasSEWOp(uint64_t TSFlags)
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
bool isFaultFirstLoad(const MachineInstr &MI)
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
static const MachineMemOperand::Flags MONontemporalBit1
Target & getTheRISCV32Target()
static const MachineMemOperand::Flags MONontemporalBit0
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
Target & getTheRISCV64Target()
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1853
const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]
@ MCSA_Weak
.weak
Definition: MCDirectives.h:45
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
@ MCSA_Hidden
.hidden (ELF)
Definition: MCDirectives.h:33
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
Used to provide key value pairs for feature and CPU bit flags.