Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- MipsInstructionSelector.cpp ------------------------------*- C++ -*-===//
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
/// \file
9
/// This file implements the targeting of the InstructionSelector class for
10
/// Mips.
11
/// \todo This should be generated by TableGen.
12
//===----------------------------------------------------------------------===//
13
14
#include "MCTargetDesc/MipsInstPrinter.h"
15
#include "MipsMachineFunction.h"
16
#include "MipsRegisterBankInfo.h"
17
#include "MipsTargetMachine.h"
18
#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
19
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
20
21
#define DEBUG_TYPE "mips-isel"
22
23
using namespace llvm;
24
25
namespace {
26
27
#define GET_GLOBALISEL_PREDICATE_BITSET
28
#include "MipsGenGlobalISel.inc"
29
#undef GET_GLOBALISEL_PREDICATE_BITSET
30
31
class MipsInstructionSelector : public InstructionSelector {
32
public:
33
  MipsInstructionSelector(const MipsTargetMachine &TM, const MipsSubtarget &STI,
34
                          const MipsRegisterBankInfo &RBI);
35
36
  bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
37
0
  static const char *getName() { return DEBUG_TYPE; }
38
39
private:
40
  bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
41
  bool materialize32BitImm(Register DestReg, APInt Imm,
42
                           MachineIRBuilder &B) const;
43
  bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
44
  const TargetRegisterClass *
45
  getRegClassForTypeOnBank(unsigned OpSize, const RegisterBank &RB,
46
                           const RegisterBankInfo &RBI) const;
47
48
  const MipsTargetMachine &TM;
49
  const MipsSubtarget &STI;
50
  const MipsInstrInfo &TII;
51
  const MipsRegisterInfo &TRI;
52
  const MipsRegisterBankInfo &RBI;
53
54
#define GET_GLOBALISEL_PREDICATES_DECL
55
#include "MipsGenGlobalISel.inc"
56
#undef GET_GLOBALISEL_PREDICATES_DECL
57
58
#define GET_GLOBALISEL_TEMPORARIES_DECL
59
#include "MipsGenGlobalISel.inc"
60
#undef GET_GLOBALISEL_TEMPORARIES_DECL
61
};
62
63
} // end anonymous namespace
64
65
#define GET_GLOBALISEL_IMPL
66
#include "MipsGenGlobalISel.inc"
67
#undef GET_GLOBALISEL_IMPL
68
69
MipsInstructionSelector::MipsInstructionSelector(
70
    const MipsTargetMachine &TM, const MipsSubtarget &STI,
71
    const MipsRegisterBankInfo &RBI)
72
    : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
73
      TRI(*STI.getRegisterInfo()), RBI(RBI),
74
75
#define GET_GLOBALISEL_PREDICATES_INIT
76
#include "MipsGenGlobalISel.inc"
77
#undef GET_GLOBALISEL_PREDICATES_INIT
78
#define GET_GLOBALISEL_TEMPORARIES_INIT
79
#include "MipsGenGlobalISel.inc"
80
#undef GET_GLOBALISEL_TEMPORARIES_INIT
81
11.3k
{
82
11.3k
}
83
84
bool MipsInstructionSelector::selectCopy(MachineInstr &I,
85
2.15k
                                         MachineRegisterInfo &MRI) const {
86
2.15k
  Register DstReg = I.getOperand(0).getReg();
87
2.15k
  if (TargetRegisterInfo::isPhysicalRegister(DstReg))
88
656
    return true;
89
1.49k
90
1.49k
  const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI);
91
1.49k
  const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
92
1.49k
93
1.49k
  const TargetRegisterClass *RC = &Mips::GPR32RegClass;
94
1.49k
  if (RegBank->getID() == Mips::FPRBRegBankID) {
95
421
    if (DstSize == 32)
96
206
      RC = &Mips::FGR32RegClass;
97
215
    else if (DstSize == 64)
98
215
      RC = STI.isFP64bit() ? 
&Mips::FGR64RegClass105
:
&Mips::AFGR64RegClass110
;
99
215
    else
100
215
      
llvm_unreachable0
("Unsupported destination size");
101
421
  }
102
1.49k
  if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
103
0
    LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
104
0
                      << " operand\n");
105
0
    return false;
106
0
  }
107
1.49k
  return true;
108
1.49k
}
109
110
const TargetRegisterClass *MipsInstructionSelector::getRegClassForTypeOnBank(
111
    unsigned OpSize, const RegisterBank &RB,
112
56
    const RegisterBankInfo &RBI) const {
113
56
  if (RB.getID() == Mips::GPRBRegBankID)
114
33
    return &Mips::GPR32RegClass;
115
23
116
23
  if (RB.getID() == Mips::FPRBRegBankID)
117
23
    return OpSize == 32
118
23
               ? 
&Mips::FGR32RegClass7
119
23
               : 
STI.hasMips32r6()16
||
STI.isFP64bit()16
?
&Mips::FGR64RegClass1
120
16
                                                      : 
&Mips::AFGR64RegClass15
;
121
0
122
0
  llvm_unreachable("getRegClassForTypeOnBank can't find register class.");
123
0
  return nullptr;
124
0
}
125
126
bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm,
127
202
                                                  MachineIRBuilder &B) const {
128
202
  assert(Imm.getBitWidth() == 32 && "Unsupported immediate size.");
129
202
  // Ori zero extends immediate. Used for values with zeros in high 16 bits.
130
202
  if (Imm.getHiBits(16).isNullValue()) {
131
167
    MachineInstr *Inst = B.buildInstr(Mips::ORi, {DestReg}, {Register(Mips::ZERO)})
132
167
                             .addImm(Imm.getLoBits(16).getLimitedValue());
133
167
    return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
134
167
  }
135
35
  // Lui places immediate in high 16 bits and sets low 16 bits to zero.
136
35
  if (Imm.getLoBits(16).isNullValue()) {
137
4
    MachineInstr *Inst = B.buildInstr(Mips::LUi, {DestReg}, {})
138
4
                             .addImm(Imm.getHiBits(16).getLimitedValue());
139
4
    return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
140
4
  }
141
31
  // ADDiu sign extends immediate. Used for values with 1s in high 17 bits.
142
31
  if (Imm.isSignedIntN(16)) {
143
15
    MachineInstr *Inst = B.buildInstr(Mips::ADDiu, {DestReg}, {Register(Mips::ZERO)})
144
15
                             .addImm(Imm.getLoBits(16).getLimitedValue());
145
15
    return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI);
146
15
  }
147
16
  // Values that cannot be materialized with single immediate instruction.
148
16
  Register LUiReg = B.getMRI()->createVirtualRegister(&Mips::GPR32RegClass);
149
16
  MachineInstr *LUi = B.buildInstr(Mips::LUi, {LUiReg}, {})
150
16
                          .addImm(Imm.getHiBits(16).getLimitedValue());
151
16
  MachineInstr *ORi = B.buildInstr(Mips::ORi, {DestReg}, {LUiReg})
152
16
                          .addImm(Imm.getLoBits(16).getLimitedValue());
153
16
  if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
154
0
    return false;
155
16
  if (!constrainSelectedInstRegOperands(*ORi, TII, TRI, RBI))
156
0
    return false;
157
16
  return true;
158
16
}
159
160
/// Returning Opc indicates that we failed to select MIPS instruction opcode.
161
static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned MemSizeInBytes,
162
227
                                      unsigned RegBank, bool isFP64) {
163
227
  bool isStore = Opc == TargetOpcode::G_STORE;
164
227
  if (RegBank == Mips::GPRBRegBankID) {
165
166
    if (isStore)
166
43
      switch (MemSizeInBytes) {
167
43
      case 4:
168
35
        return Mips::SW;
169
43
      case 2:
170
2
        return Mips::SH;
171
43
      case 1:
172
6
        return Mips::SB;
173
43
      default:
174
0
        return Opc;
175
123
      }
176
123
    else
177
123
      // Unspecified extending load is selected into zeroExtending load.
178
123
      switch (MemSizeInBytes) {
179
123
      case 4:
180
104
        return Mips::LW;
181
123
      case 2:
182
7
        return Opc == TargetOpcode::G_SEXTLOAD ? 
Mips::LH2
:
Mips::LHu5
;
183
123
      case 1:
184
12
        return Opc == TargetOpcode::G_SEXTLOAD ? 
Mips::LB4
:
Mips::LBu8
;
185
123
      default:
186
0
        return Opc;
187
61
      }
188
166
  }
189
61
190
61
  if (RegBank == Mips::FPRBRegBankID) {
191
61
    switch (MemSizeInBytes) {
192
61
    case 4:
193
20
      return isStore ? 
Mips::SWC17
:
Mips::LWC113
;
194
61
    case 8:
195
41
      if (isFP64)
196
2
        return isStore ? 
Mips::SDC1641
:
Mips::LDC1641
;
197
39
      else
198
39
        return isStore ? 
Mips::SDC117
:
Mips::LDC122
;
199
0
    default:
200
0
      return Opc;
201
0
    }
202
0
  }
203
0
  return Opc;
204
0
}
205
206
bool MipsInstructionSelector::select(MachineInstr &I,
207
4.36k
                                     CodeGenCoverage &CoverageInfo) const {
208
4.36k
209
4.36k
  MachineBasicBlock &MBB = *I.getParent();
210
4.36k
  MachineFunction &MF = *MBB.getParent();
211
4.36k
  MachineRegisterInfo &MRI = MF.getRegInfo();
212
4.36k
213
4.36k
  if (!isPreISelGenericOpcode(I.getOpcode())) {
214
2.93k
    if (I.isCopy())
215
2.15k
      return selectCopy(I, MRI);
216
786
217
786
    return true;
218
786
  }
219
1.42k
220
1.42k
  if (I.getOpcode() == Mips::G_MUL) {
221
23
    MachineInstr *Mul = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MUL))
222
23
                            .add(I.getOperand(0))
223
23
                            .add(I.getOperand(1))
224
23
                            .add(I.getOperand(2));
225
23
    if (!constrainSelectedInstRegOperands(*Mul, TII, TRI, RBI))
226
0
      return false;
227
23
    Mul->getOperand(3).setIsDead(true);
228
23
    Mul->getOperand(4).setIsDead(true);
229
23
230
23
    I.eraseFromParent();
231
23
    return true;
232
23
  }
233
1.40k
234
1.40k
  if (selectImpl(I, CoverageInfo))
235
544
    return true;
236
861
237
861
  MachineInstr *MI = nullptr;
238
861
  using namespace TargetOpcode;
239
861
240
861
  switch (I.getOpcode()) {
241
861
  case G_UMULH: {
242
9
    Register PseudoMULTuReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
243
9
    MachineInstr *PseudoMULTu, *PseudoMove;
244
9
245
9
    PseudoMULTu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMULTu))
246
9
                      .addDef(PseudoMULTuReg)
247
9
                      .add(I.getOperand(1))
248
9
                      .add(I.getOperand(2));
249
9
    if (!constrainSelectedInstRegOperands(*PseudoMULTu, TII, TRI, RBI))
250
0
      return false;
251
9
252
9
    PseudoMove = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMFHI))
253
9
                     .addDef(I.getOperand(0).getReg())
254
9
                     .addUse(PseudoMULTuReg);
255
9
    if (!constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI))
256
0
      return false;
257
9
258
9
    I.eraseFromParent();
259
9
    return true;
260
9
  }
261
13
  case G_GEP: {
262
13
    MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu))
263
13
             .add(I.getOperand(0))
264
13
             .add(I.getOperand(1))
265
13
             .add(I.getOperand(2));
266
13
    break;
267
9
  }
268
54
  case G_FRAME_INDEX: {
269
54
    MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
270
54
             .add(I.getOperand(0))
271
54
             .add(I.getOperand(1))
272
54
             .addImm(0);
273
54
    break;
274
9
  }
275
67
  case G_BRCOND: {
276
67
    MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::BNE))
277
67
             .add(I.getOperand(0))
278
67
             .addUse(Mips::ZERO)
279
67
             .add(I.getOperand(1));
280
67
    break;
281
9
  }
282
56
  case G_PHI: {
283
56
    const Register DestReg = I.getOperand(0).getReg();
284
56
    const unsigned OpSize = MRI.getType(DestReg).getSizeInBits();
285
56
286
56
    const TargetRegisterClass *DefRC = nullptr;
287
56
    if (TargetRegisterInfo::isPhysicalRegister(DestReg))
288
0
      DefRC = TRI.getRegClass(DestReg);
289
56
    else
290
56
      DefRC = getRegClassForTypeOnBank(OpSize,
291
56
                                       *RBI.getRegBank(DestReg, MRI, TRI), RBI);
292
56
293
56
    I.setDesc(TII.get(TargetOpcode::PHI));
294
56
    return RBI.constrainGenericRegister(DestReg, *DefRC, MRI);
295
9
  }
296
227
  case G_STORE:
297
227
  case G_LOAD:
298
227
  case G_ZEXTLOAD:
299
227
  case G_SEXTLOAD: {
300
227
    const Register DestReg = I.getOperand(0).getReg();
301
227
    const unsigned DestRegBank = RBI.getRegBank(DestReg, MRI, TRI)->getID();
302
227
    const unsigned OpSize = MRI.getType(DestReg).getSizeInBits();
303
227
    const unsigned OpMemSizeInBytes = (*I.memoperands_begin())->getSize();
304
227
305
227
    if (DestRegBank == Mips::GPRBRegBankID && 
OpSize != 32166
)
306
0
      return false;
307
227
308
227
    if (DestRegBank == Mips::FPRBRegBankID && 
OpSize != 3261
&&
OpSize != 6441
)
309
0
      return false;
310
227
311
227
    const unsigned NewOpc = selectLoadStoreOpCode(
312
227
        I.getOpcode(), OpMemSizeInBytes, DestRegBank, STI.isFP64bit());
313
227
    if (NewOpc == I.getOpcode())
314
0
      return false;
315
227
316
227
    MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
317
227
             .add(I.getOperand(0))
318
227
             .add(I.getOperand(1))
319
227
             .addImm(0)
320
227
             .addMemOperand(*I.memoperands_begin());
321
227
    break;
322
227
  }
323
227
  case G_UDIV:
324
16
  case G_UREM:
325
16
  case G_SDIV:
326
16
  case G_SREM: {
327
16
    Register HILOReg = MRI.createVirtualRegister(&Mips::ACC64RegClass);
328
16
    bool IsSigned = I.getOpcode() == G_SREM || 
I.getOpcode() == G_SDIV13
;
329
16
    bool IsDiv = I.getOpcode() == G_UDIV || 
I.getOpcode() == G_SDIV12
;
330
16
331
16
    MachineInstr *PseudoDIV, *PseudoMove;
332
16
    PseudoDIV = BuildMI(MBB, I, I.getDebugLoc(),
333
16
                        TII.get(IsSigned ? 
Mips::PseudoSDIV8
:
Mips::PseudoUDIV8
))
334
16
                    .addDef(HILOReg)
335
16
                    .add(I.getOperand(1))
336
16
                    .add(I.getOperand(2));
337
16
    if (!constrainSelectedInstRegOperands(*PseudoDIV, TII, TRI, RBI))
338
0
      return false;
339
16
340
16
    PseudoMove = BuildMI(MBB, I, I.getDebugLoc(),
341
16
                         TII.get(IsDiv ? 
Mips::PseudoMFLO9
:
Mips::PseudoMFHI7
))
342
16
                     .addDef(I.getOperand(0).getReg())
343
16
                     .addUse(HILOReg);
344
16
    if (!constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI))
345
0
      return false;
346
16
347
16
    I.eraseFromParent();
348
16
    return true;
349
16
  }
350
16
  case G_SELECT: {
351
3
    // Handle operands with pointer type.
352
3
    MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MOVN_I_I))
353
3
             .add(I.getOperand(0))
354
3
             .add(I.getOperand(2))
355
3
             .add(I.getOperand(1))
356
3
             .add(I.getOperand(3));
357
3
    break;
358
16
  }
359
187
  case G_CONSTANT: {
360
187
    MachineIRBuilder B(I);
361
187
    if (!materialize32BitImm(I.getOperand(0).getReg(),
362
187
                             I.getOperand(1).getCImm()->getValue(), B))
363
0
      return false;
364
187
365
187
    I.eraseFromParent();
366
187
    return true;
367
187
  }
368
187
  case G_FCONSTANT: {
369
10
    const APFloat &FPimm = I.getOperand(1).getFPImm()->getValueAPF();
370
10
    APInt APImm = FPimm.bitcastToAPInt();
371
10
    unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
372
10
373
10
    if (Size == 32) {
374
5
      Register GPRReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
375
5
      MachineIRBuilder B(I);
376
5
      if (!materialize32BitImm(GPRReg, APImm, B))
377
0
        return false;
378
5
379
5
      MachineInstrBuilder MTC1 =
380
5
          B.buildInstr(Mips::MTC1, {I.getOperand(0).getReg()}, {GPRReg});
381
5
      if (!MTC1.constrainAllUses(TII, TRI, RBI))
382
0
        return false;
383
10
    }
384
10
    if (Size == 64) {
385
5
      Register GPRRegHigh = MRI.createVirtualRegister(&Mips::GPR32RegClass);
386
5
      Register GPRRegLow = MRI.createVirtualRegister(&Mips::GPR32RegClass);
387
5
      MachineIRBuilder B(I);
388
5
      if (!materialize32BitImm(GPRRegHigh, APImm.getHiBits(32).trunc(32), B))
389
0
        return false;
390
5
      if (!materialize32BitImm(GPRRegLow, APImm.getLoBits(32).trunc(32), B))
391
0
        return false;
392
5
393
5
      MachineInstrBuilder PairF64 = B.buildInstr(
394
5
          STI.isFP64bit() ? 
Mips::BuildPairF64_642
:
Mips::BuildPairF643
,
395
5
          {I.getOperand(0).getReg()}, {GPRRegLow, GPRRegHigh});
396
5
      if (!PairF64.constrainAllUses(TII, TRI, RBI))
397
0
        return false;
398
10
    }
399
10
400
10
    I.eraseFromParent();
401
10
    return true;
402
10
  }
403
10
  case G_FABS: {
404
8
    unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
405
8
    unsigned FABSOpcode =
406
8
        Size == 32 ? 
Mips::FABS_S4
407
8
                   : 
STI.isFP64bit() 4
?
Mips::FABS_D642
:
Mips::FABS_D322
;
408
8
    MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FABSOpcode))
409
8
             .add(I.getOperand(0))
410
8
             .add(I.getOperand(1));
411
8
    break;
412
10
  }
413
16
  case G_FPTOSI: {
414
16
    unsigned FromSize = MRI.getType(I.getOperand(1).getReg()).getSizeInBits();
415
16
    unsigned ToSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
416
16
    (void)ToSize;
417
16
    assert((ToSize == 32) && "Unsupported integer size for G_FPTOSI");
418
16
    assert((FromSize == 32 || FromSize == 64) &&
419
16
           "Unsupported floating point size for G_FPTOSI");
420
16
421
16
    unsigned Opcode;
422
16
    if (FromSize == 32)
423
8
      Opcode = Mips::TRUNC_W_S;
424
8
    else
425
8
      Opcode = STI.isFP64bit() ? 
Mips::TRUNC_W_D644
:
Mips::TRUNC_W_D324
;
426
16
    unsigned ResultInFPR = MRI.createVirtualRegister(&Mips::FGR32RegClass);
427
16
    MachineInstr *Trunc = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode))
428
16
                .addDef(ResultInFPR)
429
16
                .addUse(I.getOperand(1).getReg());
430
16
    if (!constrainSelectedInstRegOperands(*Trunc, TII, TRI, RBI))
431
0
      return false;
432
16
433
16
    MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MFC1))
434
16
                             .addDef(I.getOperand(0).getReg())
435
16
                             .addUse(ResultInFPR);
436
16
    if (!constrainSelectedInstRegOperands(*Move, TII, TRI, RBI))
437
0
      return false;
438
16
439
16
    I.eraseFromParent();
440
16
    return true;
441
16
  }
442
16
  case G_GLOBAL_VALUE: {
443
12
    const llvm::GlobalValue *GVal = I.getOperand(1).getGlobal();
444
12
    if (MF.getTarget().isPositionIndependent()) {
445
10
      MachineInstr *LWGOT = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW))
446
10
                                .addDef(I.getOperand(0).getReg())
447
10
                                .addReg(MF.getInfo<MipsFunctionInfo>()
448
10
                                            ->getGlobalBaseRegForGlobalISel())
449
10
                                .addGlobalAddress(GVal);
450
10
      // Global Values that don't have local linkage are handled differently
451
10
      // when they are part of call sequence. MipsCallLowering::lowerCall
452
10
      // creates G_GLOBAL_VALUE instruction as part of call sequence and adds
453
10
      // MO_GOT_CALL flag when Callee doesn't have local linkage.
454
10
      if (I.getOperand(1).getTargetFlags() == MipsII::MO_GOT_CALL)
455
3
        LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT_CALL);
456
7
      else
457
7
        LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT);
458
10
      LWGOT->addMemOperand(
459
10
          MF, MF.getMachineMemOperand(MachinePointerInfo::getGOT(MF),
460
10
                                      MachineMemOperand::MOLoad, 4, 4));
461
10
      if (!constrainSelectedInstRegOperands(*LWGOT, TII, TRI, RBI))
462
0
        return false;
463
10
464
10
      if (GVal->hasLocalLinkage()) {
465
5
        Register LWGOTDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
466
5
        LWGOT->getOperand(0).setReg(LWGOTDef);
467
5
468
5
        MachineInstr *ADDiu =
469
5
            BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
470
5
                .addDef(I.getOperand(0).getReg())
471
5
                .addReg(LWGOTDef)
472
5
                .addGlobalAddress(GVal);
473
5
        ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO);
474
5
        if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI))
475
0
          return false;
476
2
      }
477
2
    } else {
478
2
      Register LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
479
2
480
2
      MachineInstr *LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi))
481
2
                              .addDef(LUiReg)
482
2
                              .addGlobalAddress(GVal);
483
2
      LUi->getOperand(1).setTargetFlags(MipsII::MO_ABS_HI);
484
2
      if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI))
485
0
        return false;
486
2
487
2
      MachineInstr *ADDiu =
488
2
          BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
489
2
              .addDef(I.getOperand(0).getReg())
490
2
              .addUse(LUiReg)
491
2
              .addGlobalAddress(GVal);
492
2
      ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO);
493
2
      if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI))
494
0
        return false;
495
12
    }
496
12
    I.eraseFromParent();
497
12
    return true;
498
12
  }
499
71
  case G_ICMP: {
500
71
    struct Instr {
501
71
      unsigned Opcode;
502
71
      Register Def, LHS, RHS;
503
71
      Instr(unsigned Opcode, Register Def, Register LHS, Register RHS)
504
107
          : Opcode(Opcode), Def(Def), LHS(LHS), RHS(RHS){};
505
71
506
107
      bool hasImm() const {
507
107
        if (Opcode == Mips::SLTiu || 
Opcode == Mips::XORi92
)
508
31
          return true;
509
76
        return false;
510
76
      }
511
71
    };
512
71
513
71
    SmallVector<struct Instr, 2> Instructions;
514
71
    Register ICMPReg = I.getOperand(0).getReg();
515
71
    Register Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
516
71
    Register LHS = I.getOperand(2).getReg();
517
71
    Register RHS = I.getOperand(3).getReg();
518
71
    CmpInst::Predicate Cond =
519
71
        static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
520
71
521
71
    switch (Cond) {
522
71
    case CmpInst::ICMP_EQ: // LHS == RHS -> (LHS ^ RHS) < 1
523
15
      Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
524
15
      Instructions.emplace_back(Mips::SLTiu, ICMPReg, Temp, 1);
525
15
      break;
526
71
    case CmpInst::ICMP_NE: // LHS != RHS -> 0 < (LHS ^ RHS)
527
5
      Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS);
528
5
      Instructions.emplace_back(Mips::SLTu, ICMPReg, Mips::ZERO, Temp);
529
5
      break;
530
71
    case CmpInst::ICMP_UGT: // LHS >  RHS -> RHS < LHS
531
5
      Instructions.emplace_back(Mips::SLTu, ICMPReg, RHS, LHS);
532
5
      break;
533
71
    case CmpInst::ICMP_UGE: // LHS >= RHS -> !(LHS < RHS)
534
5
      Instructions.emplace_back(Mips::SLTu, Temp, LHS, RHS);
535
5
      Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
536
5
      break;
537
71
    case CmpInst::ICMP_ULT: // LHS <  RHS -> LHS < RHS
538
22
      Instructions.emplace_back(Mips::SLTu, ICMPReg, LHS, RHS);
539
22
      break;
540
71
    case CmpInst::ICMP_ULE: // LHS <= RHS -> !(RHS < LHS)
541
5
      Instructions.emplace_back(Mips::SLTu, Temp, RHS, LHS);
542
5
      Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
543
5
      break;
544
71
    case CmpInst::ICMP_SGT: // LHS >  RHS -> RHS < LHS
545
3
      Instructions.emplace_back(Mips::SLT, ICMPReg, RHS, LHS);
546
3
      break;
547
71
    case CmpInst::ICMP_SGE: // LHS >= RHS -> !(LHS < RHS)
548
3
      Instructions.emplace_back(Mips::SLT, Temp, LHS, RHS);
549
3
      Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
550
3
      break;
551
71
    case CmpInst::ICMP_SLT: // LHS <  RHS -> LHS < RHS
552
5
      Instructions.emplace_back(Mips::SLT, ICMPReg, LHS, RHS);
553
5
      break;
554
71
    case CmpInst::ICMP_SLE: // LHS <= RHS -> !(RHS < LHS)
555
3
      Instructions.emplace_back(Mips::SLT, Temp, RHS, LHS);
556
3
      Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1);
557
3
      break;
558
71
    default:
559
0
      return false;
560
71
    }
561
71
562
71
    MachineIRBuilder B(I);
563
107
    for (const struct Instr &Instruction : Instructions) {
564
107
      MachineInstrBuilder MIB = B.buildInstr(
565
107
          Instruction.Opcode, {Instruction.Def}, {Instruction.LHS});
566
107
567
107
      if (Instruction.hasImm())
568
31
        MIB.addImm(Instruction.RHS);
569
76
      else
570
76
        MIB.addUse(Instruction.RHS);
571
107
572
107
      if (!MIB.constrainAllUses(TII, TRI, RBI))
573
0
        return false;
574
107
    }
575
71
576
71
    I.eraseFromParent();
577
71
    return true;
578
71
  }
579
112
  case G_FCMP: {
580
112
    unsigned MipsFCMPCondCode;
581
112
    bool isLogicallyNegated;
582
112
    switch (CmpInst::Predicate Cond = static_cast<CmpInst::Predicate>(
583
112
                I.getOperand(1).getPredicate())) {
584
112
    case CmpInst::FCMP_UNO: // Unordered
585
16
    case CmpInst::FCMP_ORD: // Ordered (OR)
586
16
      MipsFCMPCondCode = Mips::FCOND_UN;
587
16
      isLogicallyNegated = Cond != CmpInst::FCMP_UNO;
588
16
      break;
589
16
    case CmpInst::FCMP_OEQ: // Equal
590
16
    case CmpInst::FCMP_UNE: // Not Equal (NEQ)
591
16
      MipsFCMPCondCode = Mips::FCOND_OEQ;
592
16
      isLogicallyNegated = Cond != CmpInst::FCMP_OEQ;
593
16
      break;
594
16
    case CmpInst::FCMP_UEQ: // Unordered or Equal
595
16
    case CmpInst::FCMP_ONE: // Ordered or Greater Than or Less Than (OGL)
596
16
      MipsFCMPCondCode = Mips::FCOND_UEQ;
597
16
      isLogicallyNegated = Cond != CmpInst::FCMP_UEQ;
598
16
      break;
599
16
    case CmpInst::FCMP_OLT: // Ordered or Less Than
600
16
    case CmpInst::FCMP_UGE: // Unordered or Greater Than or Equal (UGE)
601
16
      MipsFCMPCondCode = Mips::FCOND_OLT;
602
16
      isLogicallyNegated = Cond != CmpInst::FCMP_OLT;
603
16
      break;
604
16
    case CmpInst::FCMP_ULT: // Unordered or Less Than
605
16
    case CmpInst::FCMP_OGE: // Ordered or Greater Than or Equal (OGE)
606
16
      MipsFCMPCondCode = Mips::FCOND_ULT;
607
16
      isLogicallyNegated = Cond != CmpInst::FCMP_ULT;
608
16
      break;
609
16
    case CmpInst::FCMP_OLE: // Ordered or Less Than or Equal
610
16
    case CmpInst::FCMP_UGT: // Unordered or Greater Than (UGT)
611
16
      MipsFCMPCondCode = Mips::FCOND_OLE;
612
16
      isLogicallyNegated = Cond != CmpInst::FCMP_OLE;
613
16
      break;
614
16
    case CmpInst::FCMP_ULE: // Unordered or Less Than or Equal
615
16
    case CmpInst::FCMP_OGT: // Ordered or Greater Than (OGT)
616
16
      MipsFCMPCondCode = Mips::FCOND_ULE;
617
16
      isLogicallyNegated = Cond != CmpInst::FCMP_ULE;
618
16
      break;
619
16
    default:
620
0
      return false;
621
112
    }
622
112
623
112
    // Default compare result in gpr register will be `true`.
624
112
    // We will move `false` (MIPS::Zero) to gpr result when fcmp gives false
625
112
    // using MOVF_I. When orignal predicate (Cond) is logically negated
626
112
    // MipsFCMPCondCode, result is inverted i.e. MOVT_I is used.
627
112
    unsigned MoveOpcode = isLogicallyNegated ? 
Mips::MOVT_I56
:
Mips::MOVF_I56
;
628
112
629
112
    unsigned TrueInReg = MRI.createVirtualRegister(&Mips::GPR32RegClass);
630
112
    BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu))
631
112
        .addDef(TrueInReg)
632
112
        .addUse(Mips::ZERO)
633
112
        .addImm(1);
634
112
635
112
    unsigned Size = MRI.getType(I.getOperand(2).getReg()).getSizeInBits();
636
112
    unsigned FCMPOpcode =
637
112
        Size == 32 ? 
Mips::FCMP_S3256
638
112
                   : 
STI.isFP64bit() 56
?
Mips::FCMP_D6428
:
Mips::FCMP_D3228
;
639
112
    MachineInstr *FCMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FCMPOpcode))
640
112
                             .addUse(I.getOperand(2).getReg())
641
112
                             .addUse(I.getOperand(3).getReg())
642
112
                             .addImm(MipsFCMPCondCode);
643
112
    if (!constrainSelectedInstRegOperands(*FCMP, TII, TRI, RBI))
644
0
      return false;
645
112
646
112
    MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(MoveOpcode))
647
112
                             .addDef(I.getOperand(0).getReg())
648
112
                             .addUse(Mips::ZERO)
649
112
                             .addUse(Mips::FCC0)
650
112
                             .addUse(TrueInReg);
651
112
    if (!constrainSelectedInstRegOperands(*Move, TII, TRI, RBI))
652
0
      return false;
653
112
654
112
    I.eraseFromParent();
655
112
    return true;
656
112
  }
657
112
  default:
658
0
    return false;
659
372
  }
660
372
661
372
  I.eraseFromParent();
662
372
  return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
663
372
}
664
665
namespace llvm {
666
InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &TM,
667
                                                   MipsSubtarget &Subtarget,
668
11.3k
                                                   MipsRegisterBankInfo &RBI) {
669
11.3k
  return new MipsInstructionSelector(TM, Subtarget, RBI);
670
11.3k
}
671
} // end namespace llvm