Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / lib / Target / Lanai / InstPrinter / LanaiInstPrinter.cpp
blob2aadc510462da2aca9484d410386bb523c81d2c7
1 //===-- LanaiInstPrinter.cpp - Convert Lanai 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 Lanai MCInst to a .s file.
11 //===----------------------------------------------------------------------===//
13 #include "LanaiInstPrinter.h"
14 #include "Lanai.h"
15 #include "MCTargetDesc/LanaiMCExpr.h"
16 #include "llvm/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/FormattedStream.h"
23 using namespace llvm;
25 #define DEBUG_TYPE "asm-printer"
27 // Include the auto-generated portion of the assembly writer.
28 #define PRINT_ALIAS_INSTR
29 #include "LanaiGenAsmWriter.inc"
31 void LanaiInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
32 OS << StringRef(getRegisterName(RegNo)).lower();
35 bool LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
36 StringRef Alias, unsigned OpNo0,
37 unsigned OpNo1) {
38 OS << "\t" << Alias << " ";
39 printOperand(MI, OpNo0, OS);
40 OS << ", ";
41 printOperand(MI, OpNo1, OS);
42 return true;
45 static bool usesGivenOffset(const MCInst *MI, int AddOffset) {
46 unsigned AluCode = MI->getOperand(3).getImm();
47 return LPAC::encodeLanaiAluCode(AluCode) == LPAC::ADD &&
48 (MI->getOperand(2).getImm() == AddOffset ||
49 MI->getOperand(2).getImm() == -AddOffset);
52 static bool isPreIncrementForm(const MCInst *MI, int AddOffset) {
53 unsigned AluCode = MI->getOperand(3).getImm();
54 return LPAC::isPreOp(AluCode) && usesGivenOffset(MI, AddOffset);
57 static bool isPostIncrementForm(const MCInst *MI, int AddOffset) {
58 unsigned AluCode = MI->getOperand(3).getImm();
59 return LPAC::isPostOp(AluCode) && usesGivenOffset(MI, AddOffset);
62 static StringRef decIncOperator(const MCInst *MI) {
63 if (MI->getOperand(2).getImm() < 0)
64 return "--";
65 return "++";
68 bool LanaiInstPrinter::printMemoryLoadIncrement(const MCInst *MI,
69 raw_ostream &OS,
70 StringRef Opcode,
71 int AddOffset) {
72 if (isPreIncrementForm(MI, AddOffset)) {
73 OS << "\t" << Opcode << "\t[" << decIncOperator(MI) << "%"
74 << getRegisterName(MI->getOperand(1).getReg()) << "], %"
75 << getRegisterName(MI->getOperand(0).getReg());
76 return true;
78 if (isPostIncrementForm(MI, AddOffset)) {
79 OS << "\t" << Opcode << "\t[%"
80 << getRegisterName(MI->getOperand(1).getReg()) << decIncOperator(MI)
81 << "], %" << getRegisterName(MI->getOperand(0).getReg());
82 return true;
84 return false;
87 bool LanaiInstPrinter::printMemoryStoreIncrement(const MCInst *MI,
88 raw_ostream &OS,
89 StringRef Opcode,
90 int AddOffset) {
91 if (isPreIncrementForm(MI, AddOffset)) {
92 OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())
93 << ", [" << decIncOperator(MI) << "%"
94 << getRegisterName(MI->getOperand(1).getReg()) << "]";
95 return true;
97 if (isPostIncrementForm(MI, AddOffset)) {
98 OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())
99 << ", [%" << getRegisterName(MI->getOperand(1).getReg())
100 << decIncOperator(MI) << "]";
101 return true;
103 return false;
106 bool LanaiInstPrinter::printAlias(const MCInst *MI, raw_ostream &OS) {
107 switch (MI->getOpcode()) {
108 case Lanai::LDW_RI:
109 // ld 4[*%rN], %rX => ld [++imm], %rX
110 // ld -4[*%rN], %rX => ld [--imm], %rX
111 // ld 4[%rN*], %rX => ld [imm++], %rX
112 // ld -4[%rN*], %rX => ld [imm--], %rX
113 return printMemoryLoadIncrement(MI, OS, "ld", 4);
114 case Lanai::LDHs_RI:
115 return printMemoryLoadIncrement(MI, OS, "ld.h", 2);
116 case Lanai::LDHz_RI:
117 return printMemoryLoadIncrement(MI, OS, "uld.h", 2);
118 case Lanai::LDBs_RI:
119 return printMemoryLoadIncrement(MI, OS, "ld.b", 1);
120 case Lanai::LDBz_RI:
121 return printMemoryLoadIncrement(MI, OS, "uld.b", 1);
122 case Lanai::SW_RI:
123 // st %rX, 4[*%rN] => st %rX, [++imm]
124 // st %rX, -4[*%rN] => st %rX, [--imm]
125 // st %rX, 4[%rN*] => st %rX, [imm++]
126 // st %rX, -4[%rN*] => st %rX, [imm--]
127 return printMemoryStoreIncrement(MI, OS, "st", 4);
128 case Lanai::STH_RI:
129 return printMemoryStoreIncrement(MI, OS, "st.h", 2);
130 case Lanai::STB_RI:
131 return printMemoryStoreIncrement(MI, OS, "st.b", 1);
132 default:
133 return false;
137 void LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
138 StringRef Annotation,
139 const MCSubtargetInfo & /*STI*/) {
140 if (!printAlias(MI, OS) && !printAliasInstr(MI, OS))
141 printInstruction(MI, OS);
142 printAnnotation(OS, Annotation);
145 void LanaiInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
146 raw_ostream &OS, const char *Modifier) {
147 assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
148 const MCOperand &Op = MI->getOperand(OpNo);
149 if (Op.isReg())
150 OS << "%" << getRegisterName(Op.getReg());
151 else if (Op.isImm())
152 OS << formatHex(Op.getImm());
153 else {
154 assert(Op.isExpr() && "Expected an expression");
155 Op.getExpr()->print(OS, &MAI);
159 void LanaiInstPrinter::printMemImmOperand(const MCInst *MI, unsigned OpNo,
160 raw_ostream &OS) {
161 const MCOperand &Op = MI->getOperand(OpNo);
162 if (Op.isImm()) {
163 OS << '[' << formatHex(Op.getImm()) << ']';
164 } else {
165 // Symbolic operand will be lowered to immediate value by linker
166 assert(Op.isExpr() && "Expected an expression");
167 OS << '[';
168 Op.getExpr()->print(OS, &MAI);
169 OS << ']';
173 void LanaiInstPrinter::printHi16ImmOperand(const MCInst *MI, unsigned OpNo,
174 raw_ostream &OS) {
175 const MCOperand &Op = MI->getOperand(OpNo);
176 if (Op.isImm()) {
177 OS << formatHex(Op.getImm() << 16);
178 } else {
179 // Symbolic operand will be lowered to immediate value by linker
180 assert(Op.isExpr() && "Expected an expression");
181 Op.getExpr()->print(OS, &MAI);
185 void LanaiInstPrinter::printHi16AndImmOperand(const MCInst *MI, unsigned OpNo,
186 raw_ostream &OS) {
187 const MCOperand &Op = MI->getOperand(OpNo);
188 if (Op.isImm()) {
189 OS << formatHex((Op.getImm() << 16) | 0xffff);
190 } else {
191 // Symbolic operand will be lowered to immediate value by linker
192 assert(Op.isExpr() && "Expected an expression");
193 Op.getExpr()->print(OS, &MAI);
197 void LanaiInstPrinter::printLo16AndImmOperand(const MCInst *MI, unsigned OpNo,
198 raw_ostream &OS) {
199 const MCOperand &Op = MI->getOperand(OpNo);
200 if (Op.isImm()) {
201 OS << formatHex(0xffff0000 | Op.getImm());
202 } else {
203 // Symbolic operand will be lowered to immediate value by linker
204 assert(Op.isExpr() && "Expected an expression");
205 Op.getExpr()->print(OS, &MAI);
209 static void printMemoryBaseRegister(raw_ostream &OS, const unsigned AluCode,
210 const MCOperand &RegOp) {
211 assert(RegOp.isReg() && "Register operand expected");
212 OS << "[";
213 if (LPAC::isPreOp(AluCode))
214 OS << "*";
215 OS << "%" << LanaiInstPrinter::getRegisterName(RegOp.getReg());
216 if (LPAC::isPostOp(AluCode))
217 OS << "*";
218 OS << "]";
221 template <unsigned SizeInBits>
222 static void printMemoryImmediateOffset(const MCAsmInfo &MAI,
223 const MCOperand &OffsetOp,
224 raw_ostream &OS) {
225 assert((OffsetOp.isImm() || OffsetOp.isExpr()) && "Immediate expected");
226 if (OffsetOp.isImm()) {
227 assert(isInt<SizeInBits>(OffsetOp.getImm()) && "Constant value truncated");
228 OS << OffsetOp.getImm();
229 } else
230 OffsetOp.getExpr()->print(OS, &MAI);
233 void LanaiInstPrinter::printMemRiOperand(const MCInst *MI, int OpNo,
234 raw_ostream &OS,
235 const char * /*Modifier*/) {
236 const MCOperand &RegOp = MI->getOperand(OpNo);
237 const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
238 const MCOperand &AluOp = MI->getOperand(OpNo + 2);
239 const unsigned AluCode = AluOp.getImm();
241 // Offset
242 printMemoryImmediateOffset<16>(MAI, OffsetOp, OS);
244 // Register
245 printMemoryBaseRegister(OS, AluCode, RegOp);
248 void LanaiInstPrinter::printMemRrOperand(const MCInst *MI, int OpNo,
249 raw_ostream &OS,
250 const char * /*Modifier*/) {
251 const MCOperand &RegOp = MI->getOperand(OpNo);
252 const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
253 const MCOperand &AluOp = MI->getOperand(OpNo + 2);
254 const unsigned AluCode = AluOp.getImm();
255 assert(OffsetOp.isReg() && RegOp.isReg() && "Registers expected.");
257 // [ Base OP Offset ]
258 OS << "[";
259 if (LPAC::isPreOp(AluCode))
260 OS << "*";
261 OS << "%" << getRegisterName(RegOp.getReg());
262 if (LPAC::isPostOp(AluCode))
263 OS << "*";
264 OS << " " << LPAC::lanaiAluCodeToString(AluCode) << " ";
265 OS << "%" << getRegisterName(OffsetOp.getReg());
266 OS << "]";
269 void LanaiInstPrinter::printMemSplsOperand(const MCInst *MI, int OpNo,
270 raw_ostream &OS,
271 const char * /*Modifier*/) {
272 const MCOperand &RegOp = MI->getOperand(OpNo);
273 const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
274 const MCOperand &AluOp = MI->getOperand(OpNo + 2);
275 const unsigned AluCode = AluOp.getImm();
277 // Offset
278 printMemoryImmediateOffset<10>(MAI, OffsetOp, OS);
280 // Register
281 printMemoryBaseRegister(OS, AluCode, RegOp);
284 void LanaiInstPrinter::printCCOperand(const MCInst *MI, int OpNo,
285 raw_ostream &OS) {
286 LPCC::CondCode CC =
287 static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
288 // Handle the undefined value here for printing so we don't abort().
289 if (CC >= LPCC::UNKNOWN)
290 OS << "<und>";
291 else
292 OS << lanaiCondCodeToString(CC);
295 void LanaiInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
296 raw_ostream &OS) {
297 LPCC::CondCode CC =
298 static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
299 // Handle the undefined value here for printing so we don't abort().
300 if (CC >= LPCC::UNKNOWN)
301 OS << "<und>";
302 else if (CC != LPCC::ICC_T)
303 OS << "." << lanaiCondCodeToString(CC);