LLVM 24.0.0git
LoongArchInstPrinter.cpp
Go to the documentation of this file.
1//===- LoongArchInstPrinter.cpp - Convert LoongArch MCInst to asm syntax --===//
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 class prints an LoongArch MCInst to a .s file.
10//
11//===----------------------------------------------------------------------===//
12
15#include "llvm/MC/MCAsmInfo.h"
16#include "llvm/MC/MCInst.h"
18#include "llvm/MC/MCSymbol.h"
20using namespace llvm;
21
22#define DEBUG_TYPE "loongarch-asm-printer"
23
24// Include the auto-generated portion of the assembly writer.
25#define PRINT_ALIAS_INSTR
26#include "LoongArchGenAsmWriter.inc"
27
28static cl::opt<bool>
29 NoAliases("loongarch-no-aliases",
30 cl::desc("Disable the emission of assembler pseudo instructions"),
31 cl::init(false), cl::Hidden);
32
33static cl::opt<bool>
34 NumericReg("loongarch-numeric-reg",
35 cl::desc("Print numeric register names rather than the ABI "
36 "names (such as $r0 instead of $zero)"),
37 cl::init(false), cl::Hidden);
38
39static cl::opt<bool>
40 Annotate("loongarch-annotate",
41 cl::desc("Print human-readable annotations for some instructions "
42 "(such as the barrier semantics of dbar hints)"),
43 cl::init(false), cl::Hidden);
44
45// The command-line flag above is used by llvm-mc and llc. It can be used by
46// `llvm-objdump`, but we override the value here to handle options passed to
47// `llvm-objdump` with `-M` (which matches GNU objdump). There did not seem to
48// be an easier way to allow these options in all these tools, without doing it
49// this way.
51 if (Opt == "no-aliases") {
52 PrintAliases = false;
53 return true;
54 }
55
56 if (Opt == "numeric") {
57 NumericReg = true;
58 return true;
59 }
60
61 if (Opt == "annotate") {
62 Annotate = true;
63 return true;
64 }
65
66 return false;
67}
68
69// Describe the barrier semantics of a DBAR hint in the same format as GNU
70// objdump's `-M annotate`. For hints 0-0x1f the layout is `CRW|RW`, where the
71// left side of `|` lists the preceding accesses (R: loads, W: stores) and the
72// right side the succeeding accesses ordered by the barrier, and `C` (Cached)
73// is printed when bit 4 is set. 0x700 is the same-address read-after-read
74// barrier. Other hints are reserved and are not annotated. For more detailed
75// description, see LoongArch Documents Volume 1.
77 if (Hint == 0x700) {
78 OS << "SA-RAR\n";
79 return;
80 }
81 // 0xf and 0x1f are reserved.
82 if (Hint > 0x1f || (Hint & 0xf) == 0xf)
83 return;
84 char Buf[] = " | ";
85 if (Hint & 0x10)
86 Buf[0] = 'C';
87 if (!(Hint & 0x8))
88 Buf[1] = 'R';
89 if (!(Hint & 0x4))
90 Buf[2] = 'W';
91 if (!(Hint & 0x2))
92 Buf[4] = 'R';
93 if (!(Hint & 0x1))
94 Buf[5] = 'W';
95
96 OS << StringRef(Buf).rtrim() << '\n';
97}
98
100 StringRef Annot,
101 const MCSubtargetInfo &STI,
102 raw_ostream &O) {
103 if (!PrintAliases || NoAliases || !printAliasInstr(MI, Address, STI, O))
104 printInstruction(MI, Address, STI, O);
105 if (Annotate && CommentStream && MI->getOpcode() == LoongArch::DBAR)
106 printDbarAnnotation(MI->getOperand(0).getImm(), *CommentStream);
107 printAnnotation(O, Annot);
108}
109
113
114void LoongArchInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
115 const MCSubtargetInfo &STI,
116 raw_ostream &O) {
117 const MCOperand &MO = MI->getOperand(OpNo);
118
119 if (MO.isReg()) {
120 printRegName(O, MO.getReg());
121 return;
122 }
123
124 if (MO.isImm()) {
126 return;
127 }
128
129 assert(MO.isExpr() && "Unknown operand kind in printOperand");
130 MAI.printExpr(O, *MO.getExpr());
131}
132
134 const MCSubtargetInfo &STI,
135 raw_ostream &O) {
136 const MCOperand &MO = MI->getOperand(OpNo);
137 assert(MO.isReg() && "printAtomicMemOp can only print register operands");
138 printRegName(O, MO.getReg());
139}
140
142 const MCSubtargetInfo &STI,
143 raw_ostream &O) {
144 printRegName(O, MI->getOperand(OpNo).getReg());
145 O << ", ";
146 printRegName(O, LoongArch::F0);
147 O << ", ";
148 printRegName(O, LoongArch::F0);
149}
150
152 uint64_t Address, unsigned OpNo,
153 const MCSubtargetInfo &STI,
154 raw_ostream &O) {
155 // Do not print the numeric target address when symbolizing.
157 return;
158
159 return printOperand(MI, OpNo, STI, O);
160}
161
163 // Default print reg alias name
164 return getRegisterName(Reg, NumericReg ? LoongArch::NoRegAltName
165 : LoongArch::RegAliasName);
166}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
IRTranslator LLVM IR MI
static cl::opt< bool > NumericReg("loongarch-numeric-reg", cl::desc("Print numeric register names rather than the ABI " "names (such as $r0 instead of $zero)"), cl::init(false), cl::Hidden)
static cl::opt< bool > NoAliases("loongarch-no-aliases", cl::desc("Disable the emission of assembler pseudo instructions"), cl::init(false), cl::Hidden)
static void printDbarAnnotation(uint64_t Hint, raw_ostream &OS)
static cl::opt< bool > Annotate("loongarch-annotate", cl::desc("Print human-readable annotations for some instructions " "(such as the barrier semantics of dbar hints)"), cl::init(false), cl::Hidden)
void printBranchOperand(const MCInst *MI, uint64_t Address, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override
Print the specified MCInst to the specified raw_ostream.
void printCFRSetDest(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
bool applyTargetSpecificCLOption(StringRef Opt) override
Customize the printer according to a command line option.
bool printAliasInstr(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
void printRegName(raw_ostream &O, MCRegister Reg) override
Print the assembler register name.
static const char * getRegisterName(MCRegister Reg)
void printAtomicMemOp(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
WithMarkup markup(raw_ostream &OS, Markup M)
raw_ostream * CommentStream
A stream that comments can be emitted to if desired.
bool SymbolizeOperands
If true, symbolize branch target and memory reference operands.
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
bool PrintAliases
True if we prefer aliases (e.g. nop) to raw mnemonics.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
int64_t getImm() const
Definition MCInst.h:84
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Generic base class for all target subtargets.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition StringRef.h:838
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.