Coverage Report

Created: 2017-10-03 07:32

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