Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Lanai/MCTargetDesc/LanaiMCCodeEmitter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- LanaiMCCodeEmitter.cpp - Convert Lanai code to machine code -------===//
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 file implements the LanaiMCCodeEmitter class.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "Lanai.h"
15
#include "LanaiAluCode.h"
16
#include "MCTargetDesc/LanaiBaseInfo.h"
17
#include "MCTargetDesc/LanaiFixupKinds.h"
18
#include "MCTargetDesc/LanaiMCExpr.h"
19
#include "llvm/ADT/SmallVector.h"
20
#include "llvm/ADT/Statistic.h"
21
#include "llvm/MC/MCCodeEmitter.h"
22
#include "llvm/MC/MCExpr.h"
23
#include "llvm/MC/MCFixup.h"
24
#include "llvm/MC/MCInst.h"
25
#include "llvm/MC/MCInstrInfo.h"
26
#include "llvm/MC/MCRegisterInfo.h"
27
#include "llvm/MC/MCSubtargetInfo.h"
28
#include "llvm/Support/Casting.h"
29
#include "llvm/Support/raw_ostream.h"
30
#include <cassert>
31
#include <cstdint>
32
33
#define DEBUG_TYPE "mccodeemitter"
34
35
STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
36
37
namespace llvm {
38
39
namespace {
40
41
class LanaiMCCodeEmitter : public MCCodeEmitter {
42
public:
43
5
  LanaiMCCodeEmitter(const MCInstrInfo &MCII, MCContext &C) {}
44
  LanaiMCCodeEmitter(const LanaiMCCodeEmitter &) = delete;
45
  void operator=(const LanaiMCCodeEmitter &) = delete;
46
5
  ~LanaiMCCodeEmitter() override = default;
47
48
  // The functions below are called by TableGen generated functions for getting
49
  // the binary encoding of instructions/opereands.
50
51
  // getBinaryCodeForInstr - TableGen'erated function for getting the
52
  // binary encoding for an instruction.
53
  uint64_t getBinaryCodeForInstr(const MCInst &Inst,
54
                                 SmallVectorImpl<MCFixup> &Fixups,
55
                                 const MCSubtargetInfo &SubtargetInfo) const;
56
57
  // getMachineOpValue - Return binary encoding of operand. If the machine
58
  // operand requires relocation, record the relocation and return zero.
59
  unsigned getMachineOpValue(const MCInst &Inst, const MCOperand &MCOp,
60
                             SmallVectorImpl<MCFixup> &Fixups,
61
                             const MCSubtargetInfo &SubtargetInfo) const;
62
63
  unsigned getRiMemoryOpValue(const MCInst &Inst, unsigned OpNo,
64
                              SmallVectorImpl<MCFixup> &Fixups,
65
                              const MCSubtargetInfo &SubtargetInfo) const;
66
67
  unsigned getRrMemoryOpValue(const MCInst &Inst, unsigned OpNo,
68
                              SmallVectorImpl<MCFixup> &Fixups,
69
                              const MCSubtargetInfo &SubtargetInfo) const;
70
71
  unsigned getSplsOpValue(const MCInst &Inst, unsigned OpNo,
72
                          SmallVectorImpl<MCFixup> &Fixups,
73
                          const MCSubtargetInfo &SubtargetInfo) const;
74
75
  unsigned getBranchTargetOpValue(const MCInst &Inst, unsigned OpNo,
76
                                  SmallVectorImpl<MCFixup> &Fixups,
77
                                  const MCSubtargetInfo &SubtargetInfo) const;
78
79
  void encodeInstruction(const MCInst &Inst, raw_ostream &Ostream,
80
                         SmallVectorImpl<MCFixup> &Fixups,
81
                         const MCSubtargetInfo &SubtargetInfo) const override;
82
83
  unsigned adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value,
84
                                const MCSubtargetInfo &STI) const;
85
86
  unsigned adjustPqBitsSpls(const MCInst &Inst, unsigned Value,
87
                            const MCSubtargetInfo &STI) const;
88
};
89
90
} // end anonymous namespace
91
92
2
static Lanai::Fixups FixupKind(const MCExpr *Expr) {
93
2
  if (isa<MCSymbolRefExpr>(Expr))
94
0
    return Lanai::FIXUP_LANAI_21;
95
2
  
if (const LanaiMCExpr *2
McExpr2
= dyn_cast<LanaiMCExpr>(Expr)) {
96
2
    LanaiMCExpr::VariantKind ExprKind = McExpr->getKind();
97
2
    switch (ExprKind) {
98
0
    case LanaiMCExpr::VK_Lanai_None:
99
0
      return Lanai::FIXUP_LANAI_21;
100
2
    case LanaiMCExpr::VK_Lanai_ABS_HI:
101
2
      return Lanai::FIXUP_LANAI_HI16;
102
0
    case LanaiMCExpr::VK_Lanai_ABS_LO:
103
0
      return Lanai::FIXUP_LANAI_LO16;
104
0
    }
105
0
  }
106
0
  return Lanai::Fixups(0);
107
0
}
108
109
// getMachineOpValue - Return binary encoding of operand. If the machine
110
// operand requires relocation, record the relocation and return zero.
111
unsigned LanaiMCCodeEmitter::getMachineOpValue(
112
    const MCInst &Inst, const MCOperand &MCOp, SmallVectorImpl<MCFixup> &Fixups,
113
1.09k
    const MCSubtargetInfo &SubtargetInfo) const {
114
1.09k
  if (MCOp.isReg())
115
876
    return getLanaiRegisterNumbering(MCOp.getReg());
116
215
  
if (215
MCOp.isImm()215
)
117
213
    return static_cast<unsigned>(MCOp.getImm());
118
2
119
2
  // MCOp must be an expression
120
215
  assert(MCOp.isExpr());
121
2
  const MCExpr *Expr = MCOp.getExpr();
122
2
123
2
  // Extract the symbolic reference side of a binary expression.
124
2
  if (
Expr->getKind() == MCExpr::Binary2
) {
125
1
    const MCBinaryExpr *BinaryExpr = static_cast<const MCBinaryExpr *>(Expr);
126
1
    Expr = BinaryExpr->getLHS();
127
1
  }
128
1.09k
129
1.09k
  assert(isa<LanaiMCExpr>(Expr) || Expr->getKind() == MCExpr::SymbolRef);
130
1.09k
  // Push fixup (all info is contained within)
131
1.09k
  Fixups.push_back(
132
1.09k
      MCFixup::create(0, MCOp.getExpr(), MCFixupKind(FixupKind(Expr))));
133
1.09k
  return 0;
134
1.09k
}
135
136
// Helper function to adjust P and Q bits on load and store instructions.
137
static unsigned adjustPqBits(const MCInst &Inst, unsigned Value,
138
294
                             unsigned PBitShift, unsigned QBitShift) {
139
294
  const MCOperand AluOp = Inst.getOperand(3);
140
294
  unsigned AluCode = AluOp.getImm();
141
294
142
294
  // Set the P bit to one iff the immediate is nonzero and not a post-op
143
294
  // instruction.
144
294
  const MCOperand Op2 = Inst.getOperand(2);
145
294
  Value &= ~(1 << PBitShift);
146
294
  if (!LPAC::isPostOp(AluCode) &&
147
192
      
((Op2.isImm() && 192
Op2.getImm() != 0107
) ||
148
192
       
(Op2.isReg() && 95
Op2.getReg() != Lanai::R085
) ||
(Op2.isExpr())10
))
149
182
    Value |= (1 << PBitShift);
150
294
151
294
  // Set the Q bit to one iff it is a post- or pre-op instruction.
152
294
  assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
153
294
         "Expected register operand.");
154
294
  Value &= ~(1 << QBitShift);
155
294
  if (
LPAC::modifiesOp(AluCode) && 294
((Op2.isImm() && 201
Op2.getImm() != 0119
) ||
156
88
                                    
(Op2.isReg() && 88
Op2.getReg() != Lanai::R082
)))
157
195
    Value |= (1 << QBitShift);
158
294
159
294
  return Value;
160
294
}
161
162
unsigned
163
LanaiMCCodeEmitter::adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value,
164
192
                                         const MCSubtargetInfo &STI) const {
165
192
  return adjustPqBits(Inst, Value, 17, 16);
166
192
}
167
168
unsigned
169
LanaiMCCodeEmitter::adjustPqBitsSpls(const MCInst &Inst, unsigned Value,
170
102
                                     const MCSubtargetInfo &STI) const {
171
102
  return adjustPqBits(Inst, Value, 11, 10);
172
102
}
173
174
void LanaiMCCodeEmitter::encodeInstruction(
175
    const MCInst &Inst, raw_ostream &Ostream, SmallVectorImpl<MCFixup> &Fixups,
176
481
    const MCSubtargetInfo &SubtargetInfo) const {
177
481
  // Get instruction encoding and emit it
178
481
  unsigned Value = getBinaryCodeForInstr(Inst, Fixups, SubtargetInfo);
179
481
  ++MCNumEmitted; // Keep track of the number of emitted insns.
180
481
181
481
  // Emit bytes in big-endian
182
2.40k
  for (int i = (4 - 1) * 8; 
i >= 02.40k
;
i -= 81.92k
)
183
1.92k
    Ostream << static_cast<char>((Value >> i) & 0xff);
184
481
}
185
186
// Encode Lanai Memory Operand
187
unsigned LanaiMCCodeEmitter::getRiMemoryOpValue(
188
    const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
189
130
    const MCSubtargetInfo &SubtargetInfo) const {
190
130
  unsigned Encoding;
191
130
  const MCOperand Op1 = Inst.getOperand(OpNo + 0);
192
130
  const MCOperand Op2 = Inst.getOperand(OpNo + 1);
193
130
  const MCOperand AluOp = Inst.getOperand(OpNo + 2);
194
130
195
130
  assert(Op1.isReg() && "First operand is not register.");
196
130
  assert((Op2.isImm() || Op2.isExpr()) &&
197
130
         "Second operand is neither an immediate nor an expression.");
198
130
  assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&
199
130
         "Register immediate only supports addition operator");
200
130
201
130
  Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 18);
202
130
  if (
Op2.isImm()130
) {
203
130
    assert(isInt<16>(Op2.getImm()) &&
204
130
           "Constant value truncated (limited to 16-bit)");
205
130
206
130
    Encoding |= (Op2.getImm() & 0xffff);
207
130
    if (
Op2.getImm() != 0130
) {
208
106
      if (LPAC::isPreOp(AluOp.getImm()))
209
36
        Encoding |= (0x3 << 16);
210
106
      if (LPAC::isPostOp(AluOp.getImm()))
211
38
        Encoding |= (0x1 << 16);
212
106
    }
213
130
  } else
214
0
    getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);
215
130
216
130
  return Encoding;
217
130
}
218
219
unsigned LanaiMCCodeEmitter::getRrMemoryOpValue(
220
    const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
221
254
    const MCSubtargetInfo &SubtargetInfo) const {
222
254
  unsigned Encoding;
223
254
  const MCOperand Op1 = Inst.getOperand(OpNo + 0);
224
254
  const MCOperand Op2 = Inst.getOperand(OpNo + 1);
225
254
  const MCOperand AluMCOp = Inst.getOperand(OpNo + 2);
226
254
227
254
  assert(Op1.isReg() && "First operand is not register.");
228
254
  Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 15);
229
254
  assert(Op2.isReg() && "Second operand is not register.");
230
254
  Encoding |= (getLanaiRegisterNumbering(Op2.getReg()) << 10);
231
254
232
254
  assert(AluMCOp.isImm() && "Third operator is not immediate.");
233
254
  // Set BBB
234
254
  unsigned AluOp = AluMCOp.getImm();
235
254
  Encoding |= LPAC::encodeLanaiAluCode(AluOp) << 5;
236
254
  // Set P and Q
237
254
  if (LPAC::isPreOp(AluOp))
238
80
    Encoding |= (0x3 << 8);
239
254
  if (LPAC::isPostOp(AluOp))
240
84
    Encoding |= (0x1 << 8);
241
254
  // Set JJJJ
242
254
  switch (LPAC::getAluOp(AluOp)) {
243
18
  case LPAC::SHL:
244
18
  case LPAC::SRL:
245
18
    Encoding |= 0x10;
246
18
    break;
247
24
  case LPAC::SRA:
248
24
    Encoding |= 0x18;
249
24
    break;
250
212
  default:
251
212
    break;
252
254
  }
253
254
254
254
  return Encoding;
255
254
}
256
257
unsigned
258
LanaiMCCodeEmitter::getSplsOpValue(const MCInst &Inst, unsigned OpNo,
259
                                   SmallVectorImpl<MCFixup> &Fixups,
260
204
                                   const MCSubtargetInfo &SubtargetInfo) const {
261
204
  unsigned Encoding;
262
204
  const MCOperand Op1 = Inst.getOperand(OpNo + 0);
263
204
  const MCOperand Op2 = Inst.getOperand(OpNo + 1);
264
204
  const MCOperand AluOp = Inst.getOperand(OpNo + 2);
265
204
266
204
  assert(Op1.isReg() && "First operand is not register.");
267
204
  assert((Op2.isImm() || Op2.isExpr()) &&
268
204
         "Second operand is neither an immediate nor an expression.");
269
204
  assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&
270
204
         "Register immediate only supports addition operator");
271
204
272
204
  Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 12);
273
204
  if (
Op2.isImm()204
) {
274
204
    assert(isInt<10>(Op2.getImm()) &&
275
204
           "Constant value truncated (limited to 10-bit)");
276
204
277
204
    Encoding |= (Op2.getImm() & 0x3ff);
278
204
    if (
Op2.getImm() != 0204
) {
279
202
      if (LPAC::isPreOp(AluOp.getImm()))
280
76
        Encoding |= (0x3 << 10);
281
202
      if (LPAC::isPostOp(AluOp.getImm()))
282
76
        Encoding |= (0x1 << 10);
283
202
    }
284
204
  } else
285
0
    getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);
286
204
287
204
  return Encoding;
288
204
}
289
290
unsigned LanaiMCCodeEmitter::getBranchTargetOpValue(
291
    const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
292
27
    const MCSubtargetInfo &SubtargetInfo) const {
293
27
  const MCOperand &MCOp = Inst.getOperand(OpNo);
294
27
  if (
MCOp.isReg() || 27
MCOp.isImm()27
)
295
22
    return getMachineOpValue(Inst, MCOp, Fixups, SubtargetInfo);
296
5
297
5
  Fixups.push_back(MCFixup::create(
298
5
      0, MCOp.getExpr(), static_cast<MCFixupKind>(Lanai::FIXUP_LANAI_25)));
299
5
300
5
  return 0;
301
5
}
302
303
#include "LanaiGenMCCodeEmitter.inc"
304
305
} // end namespace llvm
306
307
llvm::MCCodeEmitter *
308
llvm::createLanaiMCCodeEmitter(const MCInstrInfo &InstrInfo,
309
                               const MCRegisterInfo & /*MRI*/,
310
5
                               MCContext &context) {
311
5
  return new LanaiMCCodeEmitter(InstrInfo, context);
312
5
}