1 //===-- CSKYInstPrinter.cpp - Convert CSKY MCInst to asm syntax ---------===//
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
7 //===----------------------------------------------------------------------===//
9 // This class prints an CSKY MCInst to a .s file.
11 //===----------------------------------------------------------------------===//
12 #include "CSKYInstPrinter.h"
13 #include "MCTargetDesc/CSKYBaseInfo.h"
14 #include "MCTargetDesc/CSKYMCExpr.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/StringExtras.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"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCSection.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/Debug.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/FormattedStream.h"
32 #define DEBUG_TYPE "csky-asm-printer"
34 // Include the auto-generated portion of the assembly writer.
35 #define PRINT_ALIAS_INSTR
36 #include "CSKYGenAsmWriter.inc"
39 NoAliases("csky-no-aliases",
40 cl::desc("Disable the emission of assembler pseudo instructions"),
41 cl::init(false), cl::Hidden
);
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
);
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
54 bool CSKYInstPrinter::applyTargetSpecificCLOption(StringRef Opt
) {
55 if (Opt
== "no-aliases") {
59 if (Opt
== "numeric") {
67 if (Opt
== "abi-names") {
75 void CSKYInstPrinter::printInst(const MCInst
*MI
, uint64_t Address
,
76 StringRef Annot
, const MCSubtargetInfo
&STI
,
78 const MCInst
*NewMI
= MI
;
80 if (NoAliases
|| !printAliasInstr(NewMI
, Address
, STI
, O
))
81 printInstruction(NewMI
, Address
, STI
, O
);
82 printAnnotation(O
, Annot
);
85 void CSKYInstPrinter::printRegName(raw_ostream
&O
, MCRegister Reg
) {
86 if (PrintBranchImmAsAddress
)
87 O
<< getRegisterName(Reg
, ABIRegNames
? CSKY::ABIRegAltName
88 : CSKY::NoRegAltName
);
90 O
<< getRegisterName(Reg
);
93 void CSKYInstPrinter::printFPRRegName(raw_ostream
&O
, unsigned RegNo
) const {
94 if (PrintBranchImmAsAddress
)
95 O
<< getRegisterName(RegNo
, CSKY::NoRegAltName
);
97 O
<< getRegisterName(RegNo
);
100 void 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
);
107 unsigned Reg
= MO
.getReg();
108 bool useABIName
= false;
109 if (PrintBranchImmAsAddress
)
110 useABIName
= ABIRegNames
;
112 useABIName
= !ArchRegNames
;
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");
124 printRegName(O
, Reg
);
126 printRegName(O
, Reg
);
132 uint64_t TSFlags
= MII
.get(MI
->getOpcode()).TSFlags
;
134 if (((TSFlags
& CSKYII::AddrModeMask
) != CSKYII::AddrModeNone
) &&
135 PrintBranchImmAsAddress
)
136 O
<< formatHex(MO
.getImm());
142 assert(MO
.isExpr() && "Unknown operand kind in printOperand");
143 MO
.getExpr()->print(O
, &MAI
);
146 void CSKYInstPrinter::printDataSymbol(const MCInst
*MI
, unsigned OpNo
,
147 const MCSubtargetInfo
&STI
,
149 const MCOperand
&MO
= MI
->getOperand(OpNo
);
155 MO
.getExpr()->print(O
, &MAI
);
159 void CSKYInstPrinter::printConstpool(const MCInst
*MI
, uint64_t Address
,
160 unsigned OpNo
, const MCSubtargetInfo
&STI
,
162 const MCOperand
&MO
= MI
->getOperand(OpNo
);
165 if (PrintBranchImmAsAddress
) {
166 uint64_t Target
= Address
+ MO
.getImm();
167 Target
&= 0xfffffffc;
168 O
<< formatHex(Target
);
175 assert(MO
.isExpr() && "Unknown operand kind in printConstpool");
178 MO
.getExpr()->print(O
, &MAI
);
182 void CSKYInstPrinter::printCSKYSymbolOperand(const MCInst
*MI
, uint64_t Address
,
184 const MCSubtargetInfo
&STI
,
186 const MCOperand
&MO
= MI
->getOperand(OpNo
);
188 return printOperand(MI
, OpNo
, STI
, O
);
191 if (PrintBranchImmAsAddress
) {
192 uint64_t Target
= Address
+ MO
.getImm();
193 Target
&= 0xffffffff;
194 O
<< formatHex(Target
);
200 void CSKYInstPrinter::printPSRFlag(const MCInst
*MI
, unsigned OpNo
,
201 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
202 auto V
= MI
->getOperand(OpNo
).getImm();
216 void CSKYInstPrinter::printRegisterSeq(const MCInst
*MI
, unsigned OpNum
,
217 const MCSubtargetInfo
&STI
,
219 printRegName(O
, MI
->getOperand(OpNum
).getReg());
221 printRegName(O
, MI
->getOperand(OpNum
+ 1).getReg());
224 void CSKYInstPrinter::printRegisterList(const MCInst
*MI
, unsigned OpNum
,
225 const MCSubtargetInfo
&STI
,
227 auto V
= MI
->getOperand(OpNum
).getImm();
232 printRegName(O
, CSKY::R4
);
233 auto Offset
= (V
& 0xf) - 1;
236 printRegName(O
, CSKY::R4
+ Offset
);
240 if ((V
>> 4) & 0x1) {
242 printRegName(O
, CSKY::R15
);
245 if ((V
>> 5) & 0x7) {
247 printRegName(O
, CSKY::R16
);
249 auto Offset
= ((V
>> 5) & 0x7) - 1;
253 printRegName(O
, CSKY::R16
+ Offset
);
257 if ((V
>> 8) & 0x1) {
259 printRegName(O
, CSKY::R28
);
263 const char *CSKYInstPrinter::getRegisterName(MCRegister Reg
) {
264 return getRegisterName(Reg
, ArchRegNames
? CSKY::NoRegAltName
265 : CSKY::ABIRegAltName
);
268 void CSKYInstPrinter::printFPR(const MCInst
*MI
, unsigned OpNo
,
269 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
270 const MCOperand
&MO
= MI
->getOperand(OpNo
);
273 printFPRRegName(O
, MO
.getReg());