LLVM 19.0.0git
CSKYInstPrinter.cpp
Go to the documentation of this file.
1//===-- CSKYInstPrinter.cpp - Convert CSKY 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 CSKY MCInst to a .s file.
10//
11//===----------------------------------------------------------------------===//
12#include "CSKYInstPrinter.h"
15#include "llvm/ADT/STLExtras.h"
17#include "llvm/MC/MCAsmInfo.h"
18#include "llvm/MC/MCExpr.h"
19#include "llvm/MC/MCInst.h"
20#include "llvm/MC/MCInstrInfo.h"
22#include "llvm/MC/MCSection.h"
24#include "llvm/MC/MCSymbol.h"
26#include "llvm/Support/Debug.h"
29
30using namespace llvm;
31
32#define DEBUG_TYPE "csky-asm-printer"
33
34// Include the auto-generated portion of the assembly writer.
35#define PRINT_ALIAS_INSTR
36#include "CSKYGenAsmWriter.inc"
37
38static cl::opt<bool>
39 NoAliases("csky-no-aliases",
40 cl::desc("Disable the emission of assembler pseudo instructions"),
41 cl::init(false), cl::Hidden);
42
43static cl::opt<bool>
44 ArchRegNames("csky-arch-reg-names",
45 cl::desc("Print architectural register names rather than the "
46 "ABI names (such as r14 instead of sp)"),
47 cl::init(false), cl::Hidden);
48
49// The command-line flags above are used by llvm-mc and llc. They can be used by
50// `llvm-objdump`, but we override their values here to handle options passed to
51// `llvm-objdump` with `-M` (which matches GNU objdump). There did not seem to
52// be an easier way to allow these options in all these tools, without doing it
53// this way.
55 if (Opt == "no-aliases") {
56 NoAliases = true;
57 return true;
58 }
59 if (Opt == "numeric") {
60 ArchRegNames = true;
61 return true;
62 }
63 if (Opt == "debug") {
64 DebugFlag = true;
65 return true;
66 }
67 if (Opt == "abi-names") {
68 ABIRegNames = true;
69 return true;
70 }
71
72 return false;
73}
74
76 StringRef Annot, const MCSubtargetInfo &STI,
77 raw_ostream &O) {
78 const MCInst *NewMI = MI;
79
80 if (NoAliases || !printAliasInstr(NewMI, Address, STI, O))
81 printInstruction(NewMI, Address, STI, O);
82 printAnnotation(O, Annot);
83}
84
87 O << getRegisterName(Reg, ABIRegNames ? CSKY::ABIRegAltName
88 : CSKY::NoRegAltName);
89 else
90 O << getRegisterName(Reg);
91}
92
93void CSKYInstPrinter::printFPRRegName(raw_ostream &O, unsigned RegNo) const {
95 O << getRegisterName(RegNo, CSKY::NoRegAltName);
96 else
97 O << getRegisterName(RegNo);
98}
99
100void CSKYInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
101 const MCSubtargetInfo &STI, raw_ostream &O,
102 const char *Modifier) {
103 assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
104 const MCOperand &MO = MI->getOperand(OpNo);
105
106 if (MO.isReg()) {
107 unsigned Reg = MO.getReg();
108 bool useABIName = false;
110 useABIName = ABIRegNames;
111 else
112 useABIName = !ArchRegNames;
113
114 if (Reg == CSKY::C)
115 O << "";
116 else if (STI.hasFeature(CSKY::FeatureJAVA)) {
117 if (Reg == CSKY::R23)
118 O << (useABIName ? "fp" : "r23");
119 else if (Reg == CSKY::R24)
120 O << (useABIName ? "top" : "r24");
121 else if (Reg == CSKY::R25)
122 O << (useABIName ? "bsp" : "r25");
123 else
124 printRegName(O, Reg);
125 } else
126 printRegName(O, Reg);
127
128 return;
129 }
130
131 if (MO.isImm()) {
132 uint64_t TSFlags = MII.get(MI->getOpcode()).TSFlags;
133
134 if (((TSFlags & CSKYII::AddrModeMask) != CSKYII::AddrModeNone) &&
136 O << formatHex(MO.getImm());
137 else
138 O << MO.getImm();
139 return;
140 }
141
142 assert(MO.isExpr() && "Unknown operand kind in printOperand");
143 MO.getExpr()->print(O, &MAI);
144}
145
146void CSKYInstPrinter::printDataSymbol(const MCInst *MI, unsigned OpNo,
147 const MCSubtargetInfo &STI,
148 raw_ostream &O) {
149 const MCOperand &MO = MI->getOperand(OpNo);
150
151 O << "[";
152 if (MO.isImm())
153 O << MO.getImm();
154 else
155 MO.getExpr()->print(O, &MAI);
156 O << "]";
157}
158
160 unsigned OpNo, const MCSubtargetInfo &STI,
161 raw_ostream &O) {
162 const MCOperand &MO = MI->getOperand(OpNo);
163
164 if (MO.isImm()) {
166 uint64_t Target = Address + MO.getImm();
167 Target &= 0xfffffffc;
168 O << formatHex(Target);
169 } else {
170 O << MO.getImm();
171 }
172 return;
173 }
174
175 assert(MO.isExpr() && "Unknown operand kind in printConstpool");
176
177 O << "[";
178 MO.getExpr()->print(O, &MAI);
179 O << "]";
180}
181
183 unsigned OpNo,
184 const MCSubtargetInfo &STI,
185 raw_ostream &O) {
186 const MCOperand &MO = MI->getOperand(OpNo);
187 if (!MO.isImm()) {
188 return printOperand(MI, OpNo, STI, O);
189 }
190
192 uint64_t Target = Address + MO.getImm();
193 Target &= 0xffffffff;
194 O << formatHex(Target);
195 } else {
196 O << MO.getImm();
197 }
198}
199
200void CSKYInstPrinter::printPSRFlag(const MCInst *MI, unsigned OpNo,
201 const MCSubtargetInfo &STI, raw_ostream &O) {
202 auto V = MI->getOperand(OpNo).getImm();
203
204 ListSeparator LS;
205
206 if ((V >> 3) & 0x1)
207 O << LS << "ee";
208 if ((V >> 2) & 0x1)
209 O << LS << "ie";
210 if ((V >> 1) & 0x1)
211 O << LS << "fe";
212 if ((V >> 0) & 0x1)
213 O << LS << "af";
214}
215
216void CSKYInstPrinter::printRegisterSeq(const MCInst *MI, unsigned OpNum,
217 const MCSubtargetInfo &STI,
218 raw_ostream &O) {
219 printRegName(O, MI->getOperand(OpNum).getReg());
220 O << "-";
221 printRegName(O, MI->getOperand(OpNum + 1).getReg());
222}
223
224void CSKYInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
225 const MCSubtargetInfo &STI,
226 raw_ostream &O) {
227 auto V = MI->getOperand(OpNum).getImm();
228 ListSeparator LS;
229
230 if (V & 0xf) {
231 O << LS;
232 printRegName(O, CSKY::R4);
233 auto Offset = (V & 0xf) - 1;
234 if (Offset) {
235 O << "-";
236 printRegName(O, CSKY::R4 + Offset);
237 }
238 }
239
240 if ((V >> 4) & 0x1) {
241 O << LS;
242 printRegName(O, CSKY::R15);
243 }
244
245 if ((V >> 5) & 0x7) {
246 O << LS;
247 printRegName(O, CSKY::R16);
248
249 auto Offset = ((V >> 5) & 0x7) - 1;
250
251 if (Offset) {
252 O << "-";
253 printRegName(O, CSKY::R16 + Offset);
254 }
255 }
256
257 if ((V >> 8) & 0x1) {
258 O << LS;
259 printRegName(O, CSKY::R28);
260 }
261}
262
264 return getRegisterName(Reg, ArchRegNames ? CSKY::NoRegAltName
265 : CSKY::ABIRegAltName);
266}
267
268void CSKYInstPrinter::printFPR(const MCInst *MI, unsigned OpNo,
269 const MCSubtargetInfo &STI, raw_ostream &O) {
270 const MCOperand &MO = MI->getOperand(OpNo);
271 assert(MO.isReg());
272
273 printFPRRegName(O, MO.getReg());
274}
static cl::opt< bool > NoAliases("csky-no-aliases", cl::desc("Disable the emission of assembler pseudo instructions"), cl::init(false), cl::Hidden)
static cl::opt< bool > ArchRegNames("csky-arch-reg-names", cl::desc("Print architectural register names rather than the " "ABI names (such as r14 instead of sp)"), cl::init(false), cl::Hidden)
IRTranslator LLVM IR MI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
This file contains some functions that are useful when dealing with strings.
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 printRegisterSeq(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O, const char *Modifier=nullptr)
void printFPRRegName(raw_ostream &O, unsigned RegNo) const
static const char * getRegisterName(MCRegister Reg)
void printDataSymbol(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.
void printPSRFlag(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printRegName(raw_ostream &O, MCRegister Reg) const override
Print the assembler register name.
void printCSKYSymbolOperand(const MCInst *MI, uint64_t Address, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printFPR(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printConstpool(const MCInst *MI, uint64_t Address, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
bool printAliasInstr(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
void printRegisterList(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:41
format_object< int64_t > formatHex(int64_t Value) const
const MCInstrInfo & MII
Definition: MCInstPrinter.h:52
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:51
bool PrintBranchImmAsAddress
If true, a branch immediate (e.g.
Definition: MCInstPrinter.h:74
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition: MCInstrInfo.h:63
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
int64_t getImm() const
Definition: MCInst.h:80
bool isImm() const
Definition: MCInst.h:62
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69
bool isReg() const
Definition: MCInst.h:61
const MCExpr * getExpr() const
Definition: MCInst.h:114
bool isExpr() const
Definition: MCInst.h:65
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Target - Wrapper for Target specific information.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:450
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
bool DebugFlag
This boolean is set to true if the '-debug' command line option is specified.
Definition: Debug.cpp:45