Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Lanai/MCTargetDesc/LanaiInstPrinter.cpp
Line
Count
Source (jump to first uncovered line)
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.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "LanaiInstPrinter.h"
14
#include "LanaiMCExpr.h"
15
#include "LanaiAluCode.h"
16
#include "LanaiCondCode.h"
17
#include "MCTargetDesc/LanaiMCTargetDesc.h"
18
#include "llvm/MC/MCAsmInfo.h"
19
#include "llvm/MC/MCExpr.h"
20
#include "llvm/MC/MCInst.h"
21
#include "llvm/MC/MCRegisterInfo.h"
22
#include "llvm/MC/MCSymbol.h"
23
#include "llvm/Support/ErrorHandling.h"
24
#include "llvm/Support/FormattedStream.h"
25
26
using namespace llvm;
27
28
#define DEBUG_TYPE "asm-printer"
29
30
// Include the auto-generated portion of the assembly writer.
31
#define PRINT_ALIAS_INSTR
32
#include "LanaiGenAsmWriter.inc"
33
34
0
void LanaiInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
35
0
  OS << StringRef(getRegisterName(RegNo)).lower();
36
0
}
37
38
bool LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
39
                                 StringRef Alias, unsigned OpNo0,
40
0
                                 unsigned OpNo1) {
41
0
  OS << "\t" << Alias << " ";
42
0
  printOperand(MI, OpNo0, OS);
43
0
  OS << ", ";
44
0
  printOperand(MI, OpNo1, OS);
45
0
  return true;
46
0
}
47
48
321
static bool usesGivenOffset(const MCInst *MI, int AddOffset) {
49
321
  unsigned AluCode = MI->getOperand(3).getImm();
50
321
  return LPAC::encodeLanaiAluCode(AluCode) == LPAC::ADD &&
51
321
         (MI->getOperand(2).getImm() == AddOffset ||
52
321
          
MI->getOperand(2).getImm() == -AddOffset284
);
53
321
}
54
55
566
static bool isPreIncrementForm(const MCInst *MI, int AddOffset) {
56
566
  unsigned AluCode = MI->getOperand(3).getImm();
57
566
  return LPAC::isPreOp(AluCode) && 
usesGivenOffset(MI, AddOffset)212
;
58
566
}
59
60
426
static bool isPostIncrementForm(const MCInst *MI, int AddOffset) {
61
426
  unsigned AluCode = MI->getOperand(3).getImm();
62
426
  return LPAC::isPostOp(AluCode) && 
usesGivenOffset(MI, AddOffset)109
;
63
426
}
64
65
177
static StringRef decIncOperator(const MCInst *MI) {
66
177
  if (MI->getOperand(2).getImm() < 0)
67
140
    return "--";
68
37
  return "++";
69
37
}
70
71
bool LanaiInstPrinter::printMemoryLoadIncrement(const MCInst *MI,
72
                                                raw_ostream &OS,
73
                                                StringRef Opcode,
74
347
                                                int AddOffset) {
75
347
  if (isPreIncrementForm(MI, AddOffset)) {
76
22
    OS << "\t" << Opcode << "\t[" << decIncOperator(MI) << "%"
77
22
       << getRegisterName(MI->getOperand(1).getReg()) << "], %"
78
22
       << getRegisterName(MI->getOperand(0).getReg());
79
22
    return true;
80
22
  }
81
325
  if (isPostIncrementForm(MI, AddOffset)) {
82
22
    OS << "\t" << Opcode << "\t[%"
83
22
       << getRegisterName(MI->getOperand(1).getReg()) << decIncOperator(MI)
84
22
       << "], %" << getRegisterName(MI->getOperand(0).getReg());
85
22
    return true;
86
22
  }
87
303
  return false;
88
303
}
89
90
bool LanaiInstPrinter::printMemoryStoreIncrement(const MCInst *MI,
91
                                                 raw_ostream &OS,
92
                                                 StringRef Opcode,
93
219
                                                 int AddOffset) {
94
219
  if (isPreIncrementForm(MI, AddOffset)) {
95
118
    OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())
96
118
       << ", [" << decIncOperator(MI) << "%"
97
118
       << getRegisterName(MI->getOperand(1).getReg()) << "]";
98
118
    return true;
99
118
  }
100
101
  if (isPostIncrementForm(MI, AddOffset)) {
101
15
    OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())
102
15
       << ", [%" << getRegisterName(MI->getOperand(1).getReg())
103
15
       << decIncOperator(MI) << "]";
104
15
    return true;
105
15
  }
106
86
  return false;
107
86
}
108
109
1.80k
bool LanaiInstPrinter::printAlias(const MCInst *MI, raw_ostream &OS) {
110
1.80k
  switch (MI->getOpcode()) {
111
1.80k
  case Lanai::LDW_RI:
112
216
    // ld 4[*%rN], %rX => ld [++imm], %rX
113
216
    // ld -4[*%rN], %rX => ld [--imm], %rX
114
216
    // ld 4[%rN*], %rX => ld [imm++], %rX
115
216
    // ld -4[%rN*], %rX => ld [imm--], %rX
116
216
    return printMemoryLoadIncrement(MI, OS, "ld", 4);
117
1.80k
  case Lanai::LDHs_RI:
118
32
    return printMemoryLoadIncrement(MI, OS, "ld.h", 2);
119
1.80k
  case Lanai::LDHz_RI:
120
34
    return printMemoryLoadIncrement(MI, OS, "uld.h", 2);
121
1.80k
  case Lanai::LDBs_RI:
122
33
    return printMemoryLoadIncrement(MI, OS, "ld.b", 1);
123
1.80k
  case Lanai::LDBz_RI:
124
32
    return printMemoryLoadIncrement(MI, OS, "uld.b", 1);
125
1.80k
  case Lanai::SW_RI:
126
148
    // st %rX, 4[*%rN] => st %rX, [++imm]
127
148
    // st %rX, -4[*%rN] => st %rX, [--imm]
128
148
    // st %rX, 4[%rN*] => st %rX, [imm++]
129
148
    // st %rX, -4[%rN*] => st %rX, [imm--]
130
148
    return printMemoryStoreIncrement(MI, OS, "st", 4);
131
1.80k
  case Lanai::STH_RI:
132
35
    return printMemoryStoreIncrement(MI, OS, "st.h", 2);
133
1.80k
  case Lanai::STB_RI:
134
36
    return printMemoryStoreIncrement(MI, OS, "st.b", 1);
135
1.80k
  default:
136
1.23k
    return false;
137
1.80k
  }
138
1.80k
}
139
140
void LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
141
                                 StringRef Annotation,
142
1.80k
                                 const MCSubtargetInfo & /*STI*/) {
143
1.80k
  if (!printAlias(MI, OS) && 
!printAliasInstr(MI, OS)1.62k
)
144
1.40k
    printInstruction(MI, OS);
145
1.80k
  printAnnotation(OS, Annotation);
146
1.80k
}
147
148
void LanaiInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
149
2.75k
                                    raw_ostream &OS, const char *Modifier) {
150
2.75k
  assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
151
2.75k
  const MCOperand &Op = MI->getOperand(OpNo);
152
2.75k
  if (Op.isReg())
153
2.18k
    OS << "%" << getRegisterName(Op.getReg());
154
567
  else if (Op.isImm())
155
521
    OS << formatHex(Op.getImm());
156
46
  else {
157
46
    assert(Op.isExpr() && "Expected an expression");
158
46
    Op.getExpr()->print(OS, &MAI);
159
46
  }
160
2.75k
}
161
162
void LanaiInstPrinter::printMemImmOperand(const MCInst *MI, unsigned OpNo,
163
8
                                          raw_ostream &OS) {
164
8
  const MCOperand &Op = MI->getOperand(OpNo);
165
8
  if (Op.isImm()) {
166
7
    OS << '[' << formatHex(Op.getImm()) << ']';
167
7
  } else {
168
1
    // Symbolic operand will be lowered to immediate value by linker
169
1
    assert(Op.isExpr() && "Expected an expression");
170
1
    OS << '[';
171
1
    Op.getExpr()->print(OS, &MAI);
172
1
    OS << ']';
173
1
  }
174
8
}
175
176
void LanaiInstPrinter::printHi16ImmOperand(const MCInst *MI, unsigned OpNo,
177
39
                                           raw_ostream &OS) {
178
39
  const MCOperand &Op = MI->getOperand(OpNo);
179
39
  if (Op.isImm()) {
180
30
    OS << formatHex(Op.getImm() << 16);
181
30
  } else {
182
9
    // Symbolic operand will be lowered to immediate value by linker
183
9
    assert(Op.isExpr() && "Expected an expression");
184
9
    Op.getExpr()->print(OS, &MAI);
185
9
  }
186
39
}
187
188
void LanaiInstPrinter::printHi16AndImmOperand(const MCInst *MI, unsigned OpNo,
189
6
                                              raw_ostream &OS) {
190
6
  const MCOperand &Op = MI->getOperand(OpNo);
191
6
  if (Op.isImm()) {
192
6
    OS << formatHex((Op.getImm() << 16) | 0xffff);
193
6
  } else {
194
0
    // Symbolic operand will be lowered to immediate value by linker
195
0
    assert(Op.isExpr() && "Expected an expression");
196
0
    Op.getExpr()->print(OS, &MAI);
197
0
  }
198
6
}
199
200
void LanaiInstPrinter::printLo16AndImmOperand(const MCInst *MI, unsigned OpNo,
201
7
                                              raw_ostream &OS) {
202
7
  const MCOperand &Op = MI->getOperand(OpNo);
203
7
  if (Op.isImm()) {
204
7
    OS << formatHex(0xffff0000 | Op.getImm());
205
7
  } else {
206
0
    // Symbolic operand will be lowered to immediate value by linker
207
0
    assert(Op.isExpr() && "Expected an expression");
208
0
    Op.getExpr()->print(OS, &MAI);
209
0
  }
210
7
}
211
212
static void printMemoryBaseRegister(raw_ostream &OS, const unsigned AluCode,
213
389
                                    const MCOperand &RegOp) {
214
389
  assert(RegOp.isReg() && "Register operand expected");
215
389
  OS << "[";
216
389
  if (LPAC::isPreOp(AluCode))
217
72
    OS << "*";
218
389
  OS << "%" << LanaiInstPrinter::getRegisterName(RegOp.getReg());
219
389
  if (LPAC::isPostOp(AluCode))
220
72
    OS << "*";
221
389
  OS << "]";
222
389
}
223
224
template <unsigned SizeInBits>
225
static void printMemoryImmediateOffset(const MCAsmInfo &MAI,
226
                                       const MCOperand &OffsetOp,
227
389
                                       raw_ostream &OS) {
228
389
  assert((OffsetOp.isImm() || OffsetOp.isExpr()) && "Immediate expected");
229
389
  if (OffsetOp.isImm()) {
230
389
    assert(isInt<SizeInBits>(OffsetOp.getImm()) && "Constant value truncated");
231
389
    OS << OffsetOp.getImm();
232
389
  } else
233
0
    OffsetOp.getExpr()->print(OS, &MAI);
234
389
}
LanaiInstPrinter.cpp:void printMemoryImmediateOffset<16u>(llvm::MCAsmInfo const&, llvm::MCOperand const&, llvm::raw_ostream&)
Line
Count
Source
227
239
                                       raw_ostream &OS) {
228
239
  assert((OffsetOp.isImm() || OffsetOp.isExpr()) && "Immediate expected");
229
239
  if (OffsetOp.isImm()) {
230
239
    assert(isInt<SizeInBits>(OffsetOp.getImm()) && "Constant value truncated");
231
239
    OS << OffsetOp.getImm();
232
239
  } else
233
0
    OffsetOp.getExpr()->print(OS, &MAI);
234
239
}
LanaiInstPrinter.cpp:void printMemoryImmediateOffset<10u>(llvm::MCAsmInfo const&, llvm::MCOperand const&, llvm::raw_ostream&)
Line
Count
Source
227
150
                                       raw_ostream &OS) {
228
150
  assert((OffsetOp.isImm() || OffsetOp.isExpr()) && "Immediate expected");
229
150
  if (OffsetOp.isImm()) {
230
150
    assert(isInt<SizeInBits>(OffsetOp.getImm()) && "Constant value truncated");
231
150
    OS << OffsetOp.getImm();
232
150
  } else
233
0
    OffsetOp.getExpr()->print(OS, &MAI);
234
150
}
235
236
void LanaiInstPrinter::printMemRiOperand(const MCInst *MI, int OpNo,
237
                                         raw_ostream &OS,
238
239
                                         const char * /*Modifier*/) {
239
239
  const MCOperand &RegOp = MI->getOperand(OpNo);
240
239
  const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
241
239
  const MCOperand &AluOp = MI->getOperand(OpNo + 2);
242
239
  const unsigned AluCode = AluOp.getImm();
243
239
244
239
  // Offset
245
239
  printMemoryImmediateOffset<16>(MAI, OffsetOp, OS);
246
239
247
239
  // Register
248
239
  printMemoryBaseRegister(OS, AluCode, RegOp);
249
239
}
250
251
void LanaiInstPrinter::printMemRrOperand(const MCInst *MI, int OpNo,
252
                                         raw_ostream &OS,
253
245
                                         const char * /*Modifier*/) {
254
245
  const MCOperand &RegOp = MI->getOperand(OpNo);
255
245
  const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
256
245
  const MCOperand &AluOp = MI->getOperand(OpNo + 2);
257
245
  const unsigned AluCode = AluOp.getImm();
258
245
  assert(OffsetOp.isReg() && RegOp.isReg() && "Registers expected.");
259
245
260
245
  // [ Base OP Offset ]
261
245
  OS << "[";
262
245
  if (LPAC::isPreOp(AluCode))
263
77
    OS << "*";
264
245
  OS << "%" << getRegisterName(RegOp.getReg());
265
245
  if (LPAC::isPostOp(AluCode))
266
82
    OS << "*";
267
245
  OS << " " << LPAC::lanaiAluCodeToString(AluCode) << " ";
268
245
  OS << "%" << getRegisterName(OffsetOp.getReg());
269
245
  OS << "]";
270
245
}
271
272
void LanaiInstPrinter::printMemSplsOperand(const MCInst *MI, int OpNo,
273
                                           raw_ostream &OS,
274
150
                                           const char * /*Modifier*/) {
275
150
  const MCOperand &RegOp = MI->getOperand(OpNo);
276
150
  const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
277
150
  const MCOperand &AluOp = MI->getOperand(OpNo + 2);
278
150
  const unsigned AluCode = AluOp.getImm();
279
150
280
150
  // Offset
281
150
  printMemoryImmediateOffset<10>(MAI, OffsetOp, OS);
282
150
283
150
  // Register
284
150
  printMemoryBaseRegister(OS, AluCode, RegOp);
285
150
}
286
287
void LanaiInstPrinter::printCCOperand(const MCInst *MI, int OpNo,
288
195
                                      raw_ostream &OS) {
289
195
  LPCC::CondCode CC =
290
195
      static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
291
195
  // Handle the undefined value here for printing so we don't abort().
292
195
  if (CC >= LPCC::UNKNOWN)
293
0
    OS << "<und>";
294
195
  else
295
195
    OS << lanaiCondCodeToString(CC);
296
195
}
297
298
void LanaiInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
299
96
                                             raw_ostream &OS) {
300
96
  LPCC::CondCode CC =
301
96
      static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
302
96
  // Handle the undefined value here for printing so we don't abort().
303
96
  if (CC >= LPCC::UNKNOWN)
304
0
    OS << "<und>";
305
96
  else if (CC != LPCC::ICC_T)
306
7
    OS << "." << lanaiCondCodeToString(CC);
307
96
}