LLVM 24.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"
25#include "llvm/Support/Debug.h"
28
29using namespace llvm;
30
31#define DEBUG_TYPE "csky-asm-printer"
32
33// Include the auto-generated portion of the assembly writer.
34#define PRINT_ALIAS_INSTR
35#include "CSKYGenAsmWriter.inc"
36
37// Set by `-M numeric`. Static because the static getRegisterName reads it.
38static bool ArchRegNames;
39
41 const MCRegisterInfo &MRI)
43 CLOpts(CSKY_MC::getCLOpts(MAI.getTargetOptions())) {}
44
45// -csky-no-aliases and -csky-arch-reg-names are used by llvm-mc and llc. They
46// can be used by `llvm-objdump`, but we override their values here to handle
47// options passed to `llvm-objdump` with `-M` (which matches GNU objdump). There
48// did not seem to be an easier way to allow these options in all these tools,
49// without doing it this way.
51 if (Opt == "no-aliases") {
52 PrintAliases = false;
53 return true;
54 }
55 if (Opt == "numeric") {
56 ArchRegNames = true;
57 return true;
58 }
59 if (Opt == "debug") {
60 DebugFlag = true;
61 return true;
62 }
63 if (Opt == "abi-names") {
64 ABIRegNames = true;
65 return true;
66 }
67
68 return false;
69}
70
72 StringRef Annot, const MCSubtargetInfo &STI,
73 raw_ostream &O) {
74 const MCInst *NewMI = MI;
75
76 if (!PrintAliases || CLOpts.no_aliases ||
77 !printAliasInstr(NewMI, Address, STI, O))
78 printInstruction(NewMI, Address, STI, O);
79 printAnnotation(O, Annot);
80}
81
84 O << getRegisterName(Reg, ABIRegNames ? CSKY::ABIRegAltName
85 : CSKY::NoRegAltName);
86 else
87 O << getRegisterName(CLOpts, Reg);
88}
89
90void CSKYInstPrinter::printFPRRegName(raw_ostream &O, unsigned RegNo) const {
92 O << getRegisterName(RegNo, CSKY::NoRegAltName);
93 else
94 O << getRegisterName(CLOpts, RegNo);
95}
96
97void CSKYInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
98 const MCSubtargetInfo &STI, raw_ostream &O) {
99 const MCOperand &MO = MI->getOperand(OpNo);
100
101 if (MO.isReg()) {
102 unsigned Reg = MO.getReg();
103 bool useABIName = false;
105 useABIName = ABIRegNames;
106 else
107 useABIName = !(ArchRegNames || CLOpts.arch_reg_names);
108
109 if (Reg == CSKY::C)
110 O << "";
111 else if (STI.hasFeature(CSKY::FeatureJAVA)) {
112 if (Reg == CSKY::R23)
113 O << (useABIName ? "fp" : "r23");
114 else if (Reg == CSKY::R24)
115 O << (useABIName ? "top" : "r24");
116 else if (Reg == CSKY::R25)
117 O << (useABIName ? "bsp" : "r25");
118 else
119 printRegName(O, Reg);
120 } else
121 printRegName(O, Reg);
122
123 return;
124 }
125
126 if (MO.isImm()) {
127 uint64_t TSFlags = MII.get(MI->getOpcode()).TSFlags;
128
129 if (((TSFlags & CSKYII::AddrModeMask) != CSKYII::AddrModeNone) &&
131 O << formatHex(MO.getImm());
132 else
133 O << MO.getImm();
134 return;
135 }
136
137 assert(MO.isExpr() && "Unknown operand kind in printOperand");
138 MAI.printExpr(O, *MO.getExpr());
139}
140
141void CSKYInstPrinter::printDataSymbol(const MCInst *MI, unsigned OpNo,
142 const MCSubtargetInfo &STI,
143 raw_ostream &O) {
144 const MCOperand &MO = MI->getOperand(OpNo);
145
146 O << "[";
147 if (MO.isImm())
148 O << MO.getImm();
149 else
150 MAI.printExpr(O, *MO.getExpr());
151 O << "]";
152}
153
155 unsigned OpNo, const MCSubtargetInfo &STI,
156 raw_ostream &O) {
157 const MCOperand &MO = MI->getOperand(OpNo);
158
159 if (MO.isImm()) {
161 uint64_t Target = Address + MO.getImm();
162 Target &= 0xfffffffc;
163 O << formatHex(Target);
164 } else {
165 O << MO.getImm();
166 }
167 return;
168 }
169
170 assert(MO.isExpr() && "Unknown operand kind in printConstpool");
171
172 O << "[";
173 MAI.printExpr(O, *MO.getExpr());
174 O << "]";
175}
176
178 unsigned OpNo,
179 const MCSubtargetInfo &STI,
180 raw_ostream &O) {
181 const MCOperand &MO = MI->getOperand(OpNo);
182 if (!MO.isImm()) {
183 return printOperand(MI, OpNo, STI, O);
184 }
185
187 uint64_t Target = Address + MO.getImm();
188 Target &= 0xffffffff;
189 O << formatHex(Target);
190 } else {
191 O << MO.getImm();
192 }
193}
194
195void CSKYInstPrinter::printPSRFlag(const MCInst *MI, unsigned OpNo,
196 const MCSubtargetInfo &STI, raw_ostream &O) {
197 auto V = MI->getOperand(OpNo).getImm();
198
199 ListSeparator LS;
200
201 if ((V >> 3) & 0x1)
202 O << LS << "ee";
203 if ((V >> 2) & 0x1)
204 O << LS << "ie";
205 if ((V >> 1) & 0x1)
206 O << LS << "fe";
207 if ((V >> 0) & 0x1)
208 O << LS << "af";
209}
210
211void CSKYInstPrinter::printRegisterSeq(const MCInst *MI, unsigned OpNum,
212 const MCSubtargetInfo &STI,
213 raw_ostream &O) {
214 printRegName(O, MI->getOperand(OpNum).getReg());
215 O << "-";
216 printRegName(O, MI->getOperand(OpNum + 1).getReg());
217}
218
219void CSKYInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
220 const MCSubtargetInfo &STI,
221 raw_ostream &O) {
222 auto V = MI->getOperand(OpNum).getImm();
223 ListSeparator LS;
224
225 if (V & 0xf) {
226 O << LS;
227 printRegName(O, CSKY::R4);
228 auto Offset = (V & 0xf) - 1;
229 if (Offset) {
230 O << "-";
231 printRegName(O, CSKY::R4 + Offset);
232 }
233 }
234
235 if ((V >> 4) & 0x1) {
236 O << LS;
237 printRegName(O, CSKY::R15);
238 }
239
240 if ((V >> 5) & 0x7) {
241 O << LS;
242 printRegName(O, CSKY::R16);
243
244 auto Offset = ((V >> 5) & 0x7) - 1;
245
246 if (Offset) {
247 O << "-";
248 printRegName(O, CSKY::R16 + Offset);
249 }
250 }
251
252 if ((V >> 8) & 0x1) {
253 O << LS;
254 printRegName(O, CSKY::R28);
255 }
256}
257
258const char *CSKYInstPrinter::getRegisterName(const CSKYMCOptions &CLOpts,
259 MCRegister Reg) {
260 return getRegisterName(Reg, ArchRegNames || CLOpts.arch_reg_names
261 ? CSKY::NoRegAltName
262 : CSKY::ABIRegAltName);
263}
264
265void CSKYInstPrinter::printFPR(const MCInst *MI, unsigned OpNo,
266 const MCSubtargetInfo &STI, raw_ostream &O) {
267 const MCOperand &MO = MI->getOperand(OpNo);
268 assert(MO.isReg());
269
270 printFPRRegName(O, MO.getReg());
271}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool ArchRegNames
IRTranslator LLVM IR MI
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 printFPRRegName(raw_ostream &O, unsigned RegNo) const
static const char * getRegisterName(const CSKYMCOptions &CLOpts, 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 printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printPSRFlag(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
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 printRegName(raw_ostream &O, MCRegister Reg) override
Print the assembler register name.
CSKYInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
A helper class to return the specified delimiter string after the first invocation of operator String...
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:67
format_object< int64_t > formatHex(int64_t Value) const
const MCInstrInfo & MII
const MCRegisterInfo & MRI
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
bool PrintBranchImmAsAddress
If true, a branch immediate (e.g.
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri)
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
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
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
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
LLVM_ABI bool DebugFlag
This boolean is set to true if the '-debug' command line option is specified.
Definition Debug.cpp:68