1 //===-- LanaiInstPrinter.cpp - Convert Lanai MCInst to asm syntax ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This class prints an Lanai MCInst to a .s file.
12 //===----------------------------------------------------------------------===//
14 #include "LanaiInstPrinter.h"
16 #include "MCTargetDesc/LanaiMCExpr.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCSymbol.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/FormattedStream.h"
26 #define DEBUG_TYPE "asm-printer"
28 // Include the auto-generated portion of the assembly writer.
29 #define PRINT_ALIAS_INSTR
30 #include "LanaiGenAsmWriter.inc"
32 void LanaiInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
33 OS << StringRef(getRegisterName(RegNo)).lower();
36 bool LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
37 StringRef Alias, unsigned OpNo0,
39 OS << "\t" << Alias << " ";
40 printOperand(MI, OpNo0, OS);
42 printOperand(MI, OpNo1, OS);
46 static bool usesGivenOffset(const MCInst *MI, int AddOffset) {
47 unsigned AluCode = MI->getOperand(3).getImm();
48 return LPAC::encodeLanaiAluCode(AluCode) == LPAC::ADD &&
49 (MI->getOperand(2).getImm() == AddOffset ||
50 MI->getOperand(2).getImm() == -AddOffset);
53 static bool isPreIncrementForm(const MCInst *MI, int AddOffset) {
54 unsigned AluCode = MI->getOperand(3).getImm();
55 return LPAC::isPreOp(AluCode) && usesGivenOffset(MI, AddOffset);
58 static bool isPostIncrementForm(const MCInst *MI, int AddOffset) {
59 unsigned AluCode = MI->getOperand(3).getImm();
60 return LPAC::isPostOp(AluCode) && usesGivenOffset(MI, AddOffset);
63 static StringRef decIncOperator(const MCInst *MI) {
64 if (MI->getOperand(2).getImm() < 0)
69 bool LanaiInstPrinter::printMemoryLoadIncrement(const MCInst *MI,
73 if (isPreIncrementForm(MI, AddOffset)) {
74 OS << "\t" << Opcode << "\t[" << decIncOperator(MI) << "%"
75 << getRegisterName(MI->getOperand(1).getReg()) << "], %"
76 << getRegisterName(MI->getOperand(0).getReg());
79 if (isPostIncrementForm(MI, AddOffset)) {
80 OS << "\t" << Opcode << "\t[%"
81 << getRegisterName(MI->getOperand(1).getReg()) << decIncOperator(MI)
82 << "], %" << getRegisterName(MI->getOperand(0).getReg());
88 bool LanaiInstPrinter::printMemoryStoreIncrement(const MCInst *MI,
92 if (isPreIncrementForm(MI, AddOffset)) {
93 OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())
94 << ", [" << decIncOperator(MI) << "%"
95 << getRegisterName(MI->getOperand(1).getReg()) << "]";
98 if (isPostIncrementForm(MI, AddOffset)) {
99 OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())
100 << ", [%" << getRegisterName(MI->getOperand(1).getReg())
101 << decIncOperator(MI) << "]";
107 bool LanaiInstPrinter::printAlias(const MCInst *MI, raw_ostream &OS) {
108 switch (MI->getOpcode()) {
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 // ld -4[%rN*], %rX => ld [imm--], %rX
114 return printMemoryLoadIncrement(MI, OS, "ld", 4);
116 return printMemoryLoadIncrement(MI, OS, "ld.h", 2);
118 return printMemoryLoadIncrement(MI, OS, "uld.h", 2);
120 return printMemoryLoadIncrement(MI, OS, "ld.b", 1);
122 return printMemoryLoadIncrement(MI, OS, "uld.b", 1);
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 // st %rX, -4[%rN*] => st %rX, [imm--]
128 return printMemoryStoreIncrement(MI, OS, "st", 4);
130 return printMemoryStoreIncrement(MI, OS, "st.h", 2);
132 return printMemoryStoreIncrement(MI, OS, "st.b", 1);
138 void LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
139 StringRef Annotation,
140 const MCSubtargetInfo & /*STI*/) {
141 if (!printAlias(MI, OS) && !printAliasInstr(MI, OS))
142 printInstruction(MI, OS);
143 printAnnotation(OS, Annotation);
146 void LanaiInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
147 raw_ostream &OS, const char *Modifier) {
148 assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
149 const MCOperand &Op = MI->getOperand(OpNo);
151 OS << "%" << getRegisterName(Op.getReg());
153 OS << formatHex(Op.getImm());
155 assert(Op.isExpr() && "Expected an expression");
156 Op.getExpr()->print(OS, &MAI);
160 void LanaiInstPrinter::printMemImmOperand(const MCInst *MI, unsigned OpNo,
162 const MCOperand &Op = MI->getOperand(OpNo);
164 OS << '[' << formatHex(Op.getImm()) << ']';
166 // Symbolic operand will be lowered to immediate value by linker
167 assert(Op.isExpr() && "Expected an expression");
169 Op.getExpr()->print(OS, &MAI);
174 void LanaiInstPrinter::printHi16ImmOperand(const MCInst *MI, unsigned OpNo,
176 const MCOperand &Op = MI->getOperand(OpNo);
178 OS << formatHex(Op.getImm() << 16);
180 // Symbolic operand will be lowered to immediate value by linker
181 assert(Op.isExpr() && "Expected an expression");
182 Op.getExpr()->print(OS, &MAI);
186 void LanaiInstPrinter::printHi16AndImmOperand(const MCInst *MI, unsigned OpNo,
188 const MCOperand &Op = MI->getOperand(OpNo);
190 OS << formatHex((Op.getImm() << 16) | 0xffff);
192 // Symbolic operand will be lowered to immediate value by linker
193 assert(Op.isExpr() && "Expected an expression");
194 Op.getExpr()->print(OS, &MAI);
198 void LanaiInstPrinter::printLo16AndImmOperand(const MCInst *MI, unsigned OpNo,
200 const MCOperand &Op = MI->getOperand(OpNo);
202 OS << formatHex(0xffff0000 | Op.getImm());
204 // Symbolic operand will be lowered to immediate value by linker
205 assert(Op.isExpr() && "Expected an expression");
206 Op.getExpr()->print(OS, &MAI);
210 static void printMemoryBaseRegister(raw_ostream &OS, const unsigned AluCode,
211 const MCOperand &RegOp) {
212 assert(RegOp.isReg() && "Register operand expected");
214 if (LPAC::isPreOp(AluCode))
216 OS << "%" << LanaiInstPrinter::getRegisterName(RegOp.getReg());
217 if (LPAC::isPostOp(AluCode))
222 template <unsigned SizeInBits>
223 static void printMemoryImmediateOffset(const MCAsmInfo &MAI,
224 const MCOperand &OffsetOp,
226 assert((OffsetOp.isImm() || OffsetOp.isExpr()) && "Immediate expected");
227 if (OffsetOp.isImm()) {
228 assert(isInt<SizeInBits>(OffsetOp.getImm()) && "Constant value truncated");
229 OS << OffsetOp.getImm();
231 OffsetOp.getExpr()->print(OS, &MAI);
234 void LanaiInstPrinter::printMemRiOperand(const MCInst *MI, int OpNo,
236 const char * /*Modifier*/) {
237 const MCOperand &RegOp = MI->getOperand(OpNo);
238 const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
239 const MCOperand &AluOp = MI->getOperand(OpNo + 2);
240 const unsigned AluCode = AluOp.getImm();
243 printMemoryImmediateOffset<16>(MAI, OffsetOp, OS);
246 printMemoryBaseRegister(OS, AluCode, RegOp);
249 void LanaiInstPrinter::printMemRrOperand(const MCInst *MI, int OpNo,
251 const char * /*Modifier*/) {
252 const MCOperand &RegOp = MI->getOperand(OpNo);
253 const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
254 const MCOperand &AluOp = MI->getOperand(OpNo + 2);
255 const unsigned AluCode = AluOp.getImm();
256 assert(OffsetOp.isReg() && RegOp.isReg() && "Registers expected.");
258 // [ Base OP Offset ]
260 if (LPAC::isPreOp(AluCode))
262 OS << "%" << getRegisterName(RegOp.getReg());
263 if (LPAC::isPostOp(AluCode))
265 OS << " " << LPAC::lanaiAluCodeToString(AluCode) << " ";
266 OS << "%" << getRegisterName(OffsetOp.getReg());
270 void LanaiInstPrinter::printMemSplsOperand(const MCInst *MI, int OpNo,
272 const char * /*Modifier*/) {
273 const MCOperand &RegOp = MI->getOperand(OpNo);
274 const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
275 const MCOperand &AluOp = MI->getOperand(OpNo + 2);
276 const unsigned AluCode = AluOp.getImm();
279 printMemoryImmediateOffset<10>(MAI, OffsetOp, OS);
282 printMemoryBaseRegister(OS, AluCode, RegOp);
285 void LanaiInstPrinter::printCCOperand(const MCInst *MI, int OpNo,
288 static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
289 // Handle the undefined value here for printing so we don't abort().
290 if (CC >= LPCC::UNKNOWN)
293 OS << lanaiCondCodeToString(CC);
296 void LanaiInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
299 static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
300 // Handle the undefined value here for printing so we don't abort().
301 if (CC >= LPCC::UNKNOWN)
303 else if (CC != LPCC::ICC_T)
304 OS << "." << lanaiCondCodeToString(CC);