Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/MipsMCInstLower.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- MipsMCInstLower.cpp - Convert Mips MachineInstr to MCInst ----------===//
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 file contains code to lower Mips MachineInstrs to their corresponding
10
// MCInst records.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "MipsMCInstLower.h"
15
#include "MCTargetDesc/MipsBaseInfo.h"
16
#include "MCTargetDesc/MipsMCExpr.h"
17
#include "MipsAsmPrinter.h"
18
#include "llvm/CodeGen/MachineBasicBlock.h"
19
#include "llvm/CodeGen/MachineInstr.h"
20
#include "llvm/CodeGen/MachineOperand.h"
21
#include "llvm/MC/MCExpr.h"
22
#include "llvm/MC/MCInst.h"
23
#include "llvm/Support/ErrorHandling.h"
24
#include <cassert>
25
26
using namespace llvm;
27
28
MipsMCInstLower::MipsMCInstLower(MipsAsmPrinter &asmprinter)
29
2.01k
  : AsmPrinter(asmprinter) {}
30
31
13.2k
void MipsMCInstLower::Initialize(MCContext *C) {
32
13.2k
  Ctx = C;
33
13.2k
}
34
35
MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
36
                                              MachineOperandType MOTy,
37
27.6k
                                              unsigned Offset) const {
38
27.6k
  MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
39
27.6k
  MipsMCExpr::MipsExprKind TargetKind = MipsMCExpr::MEK_None;
40
27.6k
  bool IsGpOff = false;
41
27.6k
  const MCSymbol *Symbol;
42
27.6k
43
27.6k
  switch(MO.getTargetFlags()) {
44
27.6k
  default:
45
0
    llvm_unreachable("Invalid target flag!");
46
27.6k
  case MipsII::MO_NO_FLAG:
47
3.12k
    break;
48
27.6k
  case MipsII::MO_GPREL:
49
17
    TargetKind = MipsMCExpr::MEK_GPREL;
50
17
    break;
51
27.6k
  case MipsII::MO_GOT_CALL:
52
1.68k
    TargetKind = MipsMCExpr::MEK_GOT_CALL;
53
1.68k
    break;
54
27.6k
  case MipsII::MO_GOT:
55
4.35k
    TargetKind = MipsMCExpr::MEK_GOT;
56
4.35k
    break;
57
27.6k
  case MipsII::MO_ABS_HI:
58
6.11k
    TargetKind = MipsMCExpr::MEK_HI;
59
6.11k
    break;
60
27.6k
  case MipsII::MO_ABS_LO:
61
7.02k
    TargetKind = MipsMCExpr::MEK_LO;
62
7.02k
    break;
63
27.6k
  case MipsII::MO_TLSGD:
64
8
    TargetKind = MipsMCExpr::MEK_TLSGD;
65
8
    break;
66
27.6k
  case MipsII::MO_TLSLDM:
67
8
    TargetKind = MipsMCExpr::MEK_TLSLDM;
68
8
    break;
69
27.6k
  case MipsII::MO_DTPREL_HI:
70
8
    TargetKind = MipsMCExpr::MEK_DTPREL_HI;
71
8
    break;
72
27.6k
  case MipsII::MO_DTPREL_LO:
73
12
    TargetKind = MipsMCExpr::MEK_DTPREL_LO;
74
12
    break;
75
27.6k
  case MipsII::MO_GOTTPREL:
76
11
    TargetKind = MipsMCExpr::MEK_GOTTPREL;
77
11
    break;
78
27.6k
  case MipsII::MO_TPREL_HI:
79
15
    TargetKind = MipsMCExpr::MEK_TPREL_HI;
80
15
    break;
81
27.6k
  case MipsII::MO_TPREL_LO:
82
15
    TargetKind = MipsMCExpr::MEK_TPREL_LO;
83
15
    break;
84
27.6k
  case MipsII::MO_GPOFF_HI:
85
1.37k
    TargetKind = MipsMCExpr::MEK_HI;
86
1.37k
    IsGpOff = true;
87
1.37k
    break;
88
27.6k
  case MipsII::MO_GPOFF_LO:
89
1.37k
    TargetKind = MipsMCExpr::MEK_LO;
90
1.37k
    IsGpOff = true;
91
1.37k
    break;
92
27.6k
  case MipsII::MO_GOT_DISP:
93
1.29k
    TargetKind = MipsMCExpr::MEK_GOT_DISP;
94
1.29k
    break;
95
27.6k
  case MipsII::MO_GOT_HI16:
96
4
    TargetKind = MipsMCExpr::MEK_GOT_HI16;
97
4
    break;
98
27.6k
  case MipsII::MO_GOT_LO16:
99
4
    TargetKind = MipsMCExpr::MEK_GOT_LO16;
100
4
    break;
101
27.6k
  case MipsII::MO_GOT_PAGE:
102
194
    TargetKind = MipsMCExpr::MEK_GOT_PAGE;
103
194
    break;
104
27.6k
  case MipsII::MO_GOT_OFST:
105
196
    TargetKind = MipsMCExpr::MEK_GOT_OFST;
106
196
    break;
107
27.6k
  case MipsII::MO_HIGHER:
108
279
    TargetKind = MipsMCExpr::MEK_HIGHER;
109
279
    break;
110
27.6k
  case MipsII::MO_HIGHEST:
111
279
    TargetKind = MipsMCExpr::MEK_HIGHEST;
112
279
    break;
113
27.6k
  case MipsII::MO_CALL_HI16:
114
8
    TargetKind = MipsMCExpr::MEK_CALL_HI16;
115
8
    break;
116
27.6k
  case MipsII::MO_CALL_LO16:
117
8
    TargetKind = MipsMCExpr::MEK_CALL_LO16;
118
8
    break;
119
27.6k
  case MipsII::MO_JALR:
120
279
    return MCOperand();
121
27.4k
  }
122
27.4k
123
27.4k
  switch (MOTy) {
124
27.4k
  case MachineOperand::MO_MachineBasicBlock:
125
1.91k
    Symbol = MO.getMBB()->getSymbol();
126
1.91k
    break;
127
27.4k
128
27.4k
  case MachineOperand::MO_GlobalAddress:
129
18.5k
    Symbol = AsmPrinter.getSymbol(MO.getGlobal());
130
18.5k
    Offset += MO.getOffset();
131
18.5k
    break;
132
27.4k
133
27.4k
  case MachineOperand::MO_BlockAddress:
134
36
    Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());
135
36
    Offset += MO.getOffset();
136
36
    break;
137
27.4k
138
27.4k
  case MachineOperand::MO_ExternalSymbol:
139
5.78k
    Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());
140
5.78k
    Offset += MO.getOffset();
141
5.78k
    break;
142
27.4k
143
27.4k
  case MachineOperand::MO_MCSymbol:
144
6
    Symbol = MO.getMCSymbol();
145
6
    Offset += MO.getOffset();
146
6
    break;
147
27.4k
148
27.4k
  case MachineOperand::MO_JumpTableIndex:
149
54
    Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
150
54
    break;
151
27.4k
152
27.4k
  case MachineOperand::MO_ConstantPoolIndex:
153
1.10k
    Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
154
1.10k
    Offset += MO.getOffset();
155
1.10k
    break;
156
27.4k
157
27.4k
  default:
158
0
    llvm_unreachable("<unknown operand type>");
159
27.4k
  }
160
27.4k
161
27.4k
  const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
162
27.4k
163
27.4k
  if (Offset) {
164
0
    // Assume offset is never negative.
165
0
    assert(Offset > 0);
166
0
167
0
    Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, *Ctx),
168
0
                                   *Ctx);
169
0
  }
170
27.4k
171
27.4k
  if (IsGpOff)
172
2.74k
    Expr = MipsMCExpr::createGpOff(TargetKind, Expr, *Ctx);
173
24.6k
  else if (TargetKind != MipsMCExpr::MEK_None)
174
21.5k
    Expr = MipsMCExpr::create(TargetKind, Expr, *Ctx);
175
27.4k
176
27.4k
  return MCOperand::createExpr(Expr);
177
27.4k
}
178
179
MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO,
180
345k
                                        unsigned offset) const {
181
345k
  MachineOperandType MOTy = MO.getType();
182
345k
183
345k
  switch (MOTy) {
184
345k
  
default: 0
llvm_unreachable0
("unknown operand type");
185
345k
  case MachineOperand::MO_Register:
186
260k
    // Ignore all implicit register operands.
187
260k
    if (MO.isImplicit()) 
break18.7k
;
188
241k
    return MCOperand::createReg(MO.getReg());
189
241k
  case MachineOperand::MO_Immediate:
190
55.8k
    return MCOperand::createImm(MO.getImm() + offset);
191
241k
  case MachineOperand::MO_MachineBasicBlock:
192
27.6k
  case MachineOperand::MO_GlobalAddress:
193
27.6k
  case MachineOperand::MO_ExternalSymbol:
194
27.6k
  case MachineOperand::MO_MCSymbol:
195
27.6k
  case MachineOperand::MO_JumpTableIndex:
196
27.6k
  case MachineOperand::MO_ConstantPoolIndex:
197
27.6k
  case MachineOperand::MO_BlockAddress:
198
27.6k
    return LowerSymbolOperand(MO, MOTy, offset);
199
27.6k
  case MachineOperand::MO_RegisterMask:
200
2.08k
    break;
201
20.7k
 }
202
20.7k
203
20.7k
  return MCOperand();
204
20.7k
}
205
206
MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,
207
                                     MachineBasicBlock *BB2,
208
44
                                     MipsMCExpr::MipsExprKind Kind) const {
209
44
  const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::create(BB1->getSymbol(), *Ctx);
210
44
  const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::create(BB2->getSymbol(), *Ctx);
211
44
  const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Sym1, Sym2, *Ctx);
212
44
213
44
  return MCOperand::createExpr(MipsMCExpr::create(Kind, Sub, *Ctx));
214
44
}
215
216
void MipsMCInstLower::
217
23
lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const {
218
23
  OutMI.setOpcode(Mips::LUi);
219
23
220
23
  // Lower register operand.
221
23
  OutMI.addOperand(LowerOperand(MI->getOperand(0)));
222
23
223
23
  MipsMCExpr::MipsExprKind Kind;
224
23
  unsigned TargetFlags = MI->getOperand(1).getTargetFlags();
225
23
  switch (TargetFlags) {
226
23
  case MipsII::MO_HIGHEST:
227
4
    Kind = MipsMCExpr::MEK_HIGHEST;
228
4
    break;
229
23
  case MipsII::MO_HIGHER:
230
0
    Kind = MipsMCExpr::MEK_HIGHER;
231
0
    break;
232
23
  case MipsII::MO_ABS_HI:
233
19
    Kind = MipsMCExpr::MEK_HI;
234
19
    break;
235
23
  case MipsII::MO_ABS_LO:
236
0
    Kind = MipsMCExpr::MEK_LO;
237
0
    break;
238
23
  default:
239
0
    report_fatal_error("Unexpected flags for lowerLongBranchLUi");
240
23
  }
241
23
242
23
  if (MI->getNumOperands() == 2) {
243
8
    const MCExpr *Expr =
244
8
        MCSymbolRefExpr::create(MI->getOperand(1).getMBB()->getSymbol(), *Ctx);
245
8
    const MipsMCExpr *MipsExpr = MipsMCExpr::create(Kind, Expr, *Ctx);
246
8
    OutMI.addOperand(MCOperand::createExpr(MipsExpr));
247
15
  } else if (MI->getNumOperands() == 3) {
248
15
    // Create %hi($tgt-$baltgt).
249
15
    OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),
250
15
                               MI->getOperand(2).getMBB(), Kind));
251
15
  }
252
23
}
253
254
void MipsMCInstLower::lowerLongBranchADDiu(const MachineInstr *MI,
255
45
                                           MCInst &OutMI, int Opcode) const {
256
45
  OutMI.setOpcode(Opcode);
257
45
258
45
  MipsMCExpr::MipsExprKind Kind;
259
45
  unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
260
45
  switch (TargetFlags) {
261
45
  case MipsII::MO_HIGHEST:
262
0
    Kind = MipsMCExpr::MEK_HIGHEST;
263
0
    break;
264
45
  case MipsII::MO_HIGHER:
265
4
    Kind = MipsMCExpr::MEK_HIGHER;
266
4
    break;
267
45
  case MipsII::MO_ABS_HI:
268
11
    Kind = MipsMCExpr::MEK_HI;
269
11
    break;
270
45
  case MipsII::MO_ABS_LO:
271
30
    Kind = MipsMCExpr::MEK_LO;
272
30
    break;
273
45
  default:
274
0
    report_fatal_error("Unexpected flags for lowerLongBranchADDiu");
275
45
  }
276
45
277
45
  // Lower two register operands.
278
135
  
for (unsigned I = 0, E = 2; 45
I != E;
++I90
) {
279
90
    const MachineOperand &MO = MI->getOperand(I);
280
90
    OutMI.addOperand(LowerOperand(MO));
281
90
  }
282
45
283
45
  if (MI->getNumOperands() == 3) {
284
16
    // Lower register operand.
285
16
    const MCExpr *Expr =
286
16
        MCSymbolRefExpr::create(MI->getOperand(2).getMBB()->getSymbol(), *Ctx);
287
16
    const MipsMCExpr *MipsExpr = MipsMCExpr::create(Kind, Expr, *Ctx);
288
16
    OutMI.addOperand(MCOperand::createExpr(MipsExpr));
289
29
  } else if (MI->getNumOperands() == 4) {
290
29
    // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
291
29
    OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),
292
29
                               MI->getOperand(3).getMBB(), Kind));
293
29
  }
294
45
}
295
296
bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
297
110k
                                      MCInst &OutMI) const {
298
110k
  switch (MI->getOpcode()) {
299
110k
  default:
300
110k
    return false;
301
110k
  case Mips::LONG_BRANCH_LUi:
302
23
  case Mips::LONG_BRANCH_LUi2Op:
303
23
  case Mips::LONG_BRANCH_LUi2Op_64:
304
23
    lowerLongBranchLUi(MI, OutMI);
305
23
    return true;
306
23
  case Mips::LONG_BRANCH_ADDiu:
307
19
  case Mips::LONG_BRANCH_ADDiu2Op:
308
19
    lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu);
309
19
    return true;
310
26
  case Mips::LONG_BRANCH_DADDiu:
311
26
  case Mips::LONG_BRANCH_DADDiu2Op:
312
26
    lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu);
313
26
    return true;
314
110k
  }
315
110k
}
316
317
110k
void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
318
110k
  if (lowerLongBranch(MI, OutMI))
319
68
    return;
320
110k
321
110k
  OutMI.setOpcode(MI->getOpcode());
322
110k
323
442k
  for (unsigned i = 0, e = MI->getNumOperands(); i != e; 
++i331k
) {
324
331k
    const MachineOperand &MO = MI->getOperand(i);
325
331k
    MCOperand MCOp = LowerOperand(MO);
326
331k
327
331k
    if (MCOp.isValid())
328
310k
      OutMI.addOperand(MCOp);
329
331k
  }
330
110k
}