Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ARMInstructionSelector.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 ARM.
10
/// \todo This should be generated by TableGen.
11
//===----------------------------------------------------------------------===//
12
13
#include "ARMRegisterBankInfo.h"
14
#include "ARMSubtarget.h"
15
#include "ARMTargetMachine.h"
16
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
17
#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
18
#include "llvm/CodeGen/MachineConstantPool.h"
19
#include "llvm/CodeGen/MachineRegisterInfo.h"
20
#include "llvm/Support/Debug.h"
21
22
#define DEBUG_TYPE "arm-isel"
23
24
using namespace llvm;
25
26
namespace {
27
28
#define GET_GLOBALISEL_PREDICATE_BITSET
29
#include "ARMGenGlobalISel.inc"
30
#undef GET_GLOBALISEL_PREDICATE_BITSET
31
32
class ARMInstructionSelector : public InstructionSelector {
33
public:
34
  ARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI,
35
                         const ARMRegisterBankInfo &RBI);
36
37
  bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
38
0
  static const char *getName() { return DEBUG_TYPE; }
39
40
private:
41
  bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
42
43
  struct CmpConstants;
44
  struct InsertInfo;
45
46
  bool selectCmp(CmpConstants Helper, MachineInstrBuilder &MIB,
47
                 MachineRegisterInfo &MRI) const;
48
49
  // Helper for inserting a comparison sequence that sets \p ResReg to either 1
50
  // if \p LHSReg and \p RHSReg are in the relationship defined by \p Cond, or
51
  // \p PrevRes otherwise. In essence, it computes PrevRes OR (LHS Cond RHS).
52
  bool insertComparison(CmpConstants Helper, InsertInfo I, unsigned ResReg,
53
                        ARMCC::CondCodes Cond, unsigned LHSReg, unsigned RHSReg,
54
                        unsigned PrevRes) const;
55
56
  // Set \p DestReg to \p Constant.
57
  void putConstant(InsertInfo I, unsigned DestReg, unsigned Constant) const;
58
59
  bool selectGlobal(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const;
60
  bool selectSelect(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const;
61
  bool selectShift(unsigned ShiftOpc, MachineInstrBuilder &MIB) const;
62
63
  // Check if the types match and both operands have the expected size and
64
  // register bank.
65
  bool validOpRegPair(MachineRegisterInfo &MRI, unsigned LHS, unsigned RHS,
66
                      unsigned ExpectedSize, unsigned ExpectedRegBankID) const;
67
68
  // Check if the register has the expected size and register bank.
69
  bool validReg(MachineRegisterInfo &MRI, unsigned Reg, unsigned ExpectedSize,
70
                unsigned ExpectedRegBankID) const;
71
72
  const ARMBaseInstrInfo &TII;
73
  const ARMBaseRegisterInfo &TRI;
74
  const ARMBaseTargetMachine &TM;
75
  const ARMRegisterBankInfo &RBI;
76
  const ARMSubtarget &STI;
77
78
  // FIXME: This is necessary because DAGISel uses "Subtarget->" and GlobalISel
79
  // uses "STI." in the code generated by TableGen. If we want to reuse some of
80
  // the custom C++ predicates written for DAGISel, we need to have both around.
81
  const ARMSubtarget *Subtarget = &STI;
82
83
  // Store the opcodes that we might need, so we don't have to check what kind
84
  // of subtarget (ARM vs Thumb) we have all the time.
85
  struct OpcodeCache {
86
    unsigned ZEXT16;
87
    unsigned SEXT16;
88
89
    unsigned ZEXT8;
90
    unsigned SEXT8;
91
92
    // Used for implementing ZEXT/SEXT from i1
93
    unsigned AND;
94
    unsigned RSB;
95
96
    unsigned STORE32;
97
    unsigned LOAD32;
98
99
    unsigned STORE16;
100
    unsigned LOAD16;
101
102
    unsigned STORE8;
103
    unsigned LOAD8;
104
105
    unsigned ADDrr;
106
    unsigned ADDri;
107
108
    // Used for G_ICMP
109
    unsigned CMPrr;
110
    unsigned MOVi;
111
    unsigned MOVCCi;
112
113
    // Used for G_SELECT
114
    unsigned MOVCCr;
115
116
    unsigned TSTri;
117
    unsigned Bcc;
118
119
    // Used for G_GLOBAL_VALUE
120
    unsigned MOVi32imm;
121
    unsigned ConstPoolLoad;
122
    unsigned MOV_ga_pcrel;
123
    unsigned LDRLIT_ga_pcrel;
124
    unsigned LDRLIT_ga_abs;
125
126
    OpcodeCache(const ARMSubtarget &STI);
127
  } const Opcodes;
128
129
  // Select the opcode for simple extensions (that translate to a single SXT/UXT
130
  // instruction). Extension operations more complicated than that should not
131
  // invoke this. Returns the original opcode if it doesn't know how to select a
132
  // better one.
133
  unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) const;
134
135
  // Select the opcode for simple loads and stores. Returns the original opcode
136
  // if it doesn't know how to select a better one.
137
  unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
138
                                 unsigned Size) const;
139
140
  void renderVFPF32Imm(MachineInstrBuilder &New, const MachineInstr &Old) const;
141
  void renderVFPF64Imm(MachineInstrBuilder &New, const MachineInstr &Old) const;
142
143
#define GET_GLOBALISEL_PREDICATES_DECL
144
#include "ARMGenGlobalISel.inc"
145
#undef GET_GLOBALISEL_PREDICATES_DECL
146
147
// We declare the temporaries used by selectImpl() in the class to minimize the
148
// cost of constructing placeholder values.
149
#define GET_GLOBALISEL_TEMPORARIES_DECL
150
#include "ARMGenGlobalISel.inc"
151
#undef GET_GLOBALISEL_TEMPORARIES_DECL
152
};
153
} // end anonymous namespace
154
155
namespace llvm {
156
InstructionSelector *
157
createARMInstructionSelector(const ARMBaseTargetMachine &TM,
158
                             const ARMSubtarget &STI,
159
7.46k
                             const ARMRegisterBankInfo &RBI) {
160
7.46k
  return new ARMInstructionSelector(TM, STI, RBI);
161
7.46k
}
162
}
163
164
const unsigned zero_reg = 0;
165
166
#define GET_GLOBALISEL_IMPL
167
#include "ARMGenGlobalISel.inc"
168
#undef GET_GLOBALISEL_IMPL
169
170
ARMInstructionSelector::ARMInstructionSelector(const ARMBaseTargetMachine &TM,
171
                                               const ARMSubtarget &STI,
172
                                               const ARMRegisterBankInfo &RBI)
173
    : InstructionSelector(), TII(*STI.getInstrInfo()),
174
      TRI(*STI.getRegisterInfo()), TM(TM), RBI(RBI), STI(STI), Opcodes(STI),
175
#define GET_GLOBALISEL_PREDICATES_INIT
176
#include "ARMGenGlobalISel.inc"
177
#undef GET_GLOBALISEL_PREDICATES_INIT
178
#define GET_GLOBALISEL_TEMPORARIES_INIT
179
#include "ARMGenGlobalISel.inc"
180
#undef GET_GLOBALISEL_TEMPORARIES_INIT
181
7.46k
{
182
7.46k
}
183
184
static const TargetRegisterClass *guessRegClass(unsigned Reg,
185
                                                MachineRegisterInfo &MRI,
186
                                                const TargetRegisterInfo &TRI,
187
979
                                                const RegisterBankInfo &RBI) {
188
979
  const RegisterBank *RegBank = RBI.getRegBank(Reg, MRI, TRI);
189
979
  assert(RegBank && "Can't get reg bank for virtual register");
190
979
191
979
  const unsigned Size = MRI.getType(Reg).getSizeInBits();
192
979
  assert((RegBank->getID() == ARM::GPRRegBankID ||
193
979
          RegBank->getID() == ARM::FPRRegBankID) &&
194
979
         "Unsupported reg bank");
195
979
196
979
  if (RegBank->getID() == ARM::FPRRegBankID) {
197
185
    if (Size == 32)
198
98
      return &ARM::SPRRegClass;
199
87
    else if (Size == 64)
200
87
      return &ARM::DPRRegClass;
201
0
    else if (Size == 128)
202
0
      return &ARM::QPRRegClass;
203
0
    else
204
0
      llvm_unreachable("Unsupported destination size");
205
185
  }
206
979
207
979
  
return &ARM::GPRRegClass794
;
208
979
}
209
210
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
211
                       MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
212
1.64k
                       const RegisterBankInfo &RBI) {
213
1.64k
  unsigned DstReg = I.getOperand(0).getReg();
214
1.64k
  if (TargetRegisterInfo::isPhysicalRegister(DstReg))
215
672
    return true;
216
975
217
975
  const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI);
218
975
219
975
  // No need to constrain SrcReg. It will get constrained when
220
975
  // we hit another of its uses or its defs.
221
975
  // Copies do not have constraints.
222
975
  if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
223
0
    LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
224
0
                      << " operand\n");
225
0
    return false;
226
0
  }
227
975
  return true;
228
975
}
229
230
static bool selectMergeValues(MachineInstrBuilder &MIB,
231
                              const ARMBaseInstrInfo &TII,
232
                              MachineRegisterInfo &MRI,
233
                              const TargetRegisterInfo &TRI,
234
12
                              const RegisterBankInfo &RBI) {
235
12
  assert(TII.getSubtarget().hasVFP2Base() && "Can't select merge without VFP");
236
12
237
12
  // We only support G_MERGE_VALUES as a way to stick together two scalar GPRs
238
12
  // into one DPR.
239
12
  unsigned VReg0 = MIB->getOperand(0).getReg();
240
12
  (void)VReg0;
241
12
  assert(MRI.getType(VReg0).getSizeInBits() == 64 &&
242
12
         RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID &&
243
12
         "Unsupported operand for G_MERGE_VALUES");
244
12
  unsigned VReg1 = MIB->getOperand(1).getReg();
245
12
  (void)VReg1;
246
12
  assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
247
12
         RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
248
12
         "Unsupported operand for G_MERGE_VALUES");
249
12
  unsigned VReg2 = MIB->getOperand(2).getReg();
250
12
  (void)VReg2;
251
12
  assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
252
12
         RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
253
12
         "Unsupported operand for G_MERGE_VALUES");
254
12
255
12
  MIB->setDesc(TII.get(ARM::VMOVDRR));
256
12
  MIB.add(predOps(ARMCC::AL));
257
12
258
12
  return true;
259
12
}
260
261
static bool selectUnmergeValues(MachineInstrBuilder &MIB,
262
                                const ARMBaseInstrInfo &TII,
263
                                MachineRegisterInfo &MRI,
264
                                const TargetRegisterInfo &TRI,
265
7
                                const RegisterBankInfo &RBI) {
266
7
  assert(TII.getSubtarget().hasVFP2Base() &&
267
7
         "Can't select unmerge without VFP");
268
7
269
7
  // We only support G_UNMERGE_VALUES as a way to break up one DPR into two
270
7
  // GPRs.
271
7
  unsigned VReg0 = MIB->getOperand(0).getReg();
272
7
  (void)VReg0;
273
7
  assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
274
7
         RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
275
7
         "Unsupported operand for G_UNMERGE_VALUES");
276
7
  unsigned VReg1 = MIB->getOperand(1).getReg();
277
7
  (void)VReg1;
278
7
  assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
279
7
         RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
280
7
         "Unsupported operand for G_UNMERGE_VALUES");
281
7
  unsigned VReg2 = MIB->getOperand(2).getReg();
282
7
  (void)VReg2;
283
7
  assert(MRI.getType(VReg2).getSizeInBits() == 64 &&
284
7
         RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::FPRRegBankID &&
285
7
         "Unsupported operand for G_UNMERGE_VALUES");
286
7
287
7
  MIB->setDesc(TII.get(ARM::VMOVRRD));
288
7
  MIB.add(predOps(ARMCC::AL));
289
7
290
7
  return true;
291
7
}
292
293
7.46k
ARMInstructionSelector::OpcodeCache::OpcodeCache(const ARMSubtarget &STI) {
294
7.46k
  bool isThumb = STI.isThumb();
295
7.46k
296
7.46k
  using namespace TargetOpcode;
297
7.46k
298
149k
#define STORE_OPCODE(VAR, OPC) VAR = isThumb ? 
ARM::t285.3k
##OPC :
ARM::OPC63.8k
299
7.46k
  STORE_OPCODE(SEXT16, SXTH);
300
7.46k
  STORE_OPCODE(ZEXT16, UXTH);
301
7.46k
302
7.46k
  STORE_OPCODE(SEXT8, SXTB);
303
7.46k
  STORE_OPCODE(ZEXT8, UXTB);
304
7.46k
305
7.46k
  STORE_OPCODE(AND, ANDri);
306
7.46k
  STORE_OPCODE(RSB, RSBri);
307
7.46k
308
7.46k
  STORE_OPCODE(STORE32, STRi12);
309
7.46k
  STORE_OPCODE(LOAD32, LDRi12);
310
7.46k
311
7.46k
  // LDRH/STRH are special...
312
7.46k
  STORE16 = isThumb ? 
ARM::t2STRHi124.26k
:
ARM::STRH3.19k
;
313
7.46k
  LOAD16 = isThumb ? 
ARM::t2LDRHi124.26k
:
ARM::LDRH3.19k
;
314
7.46k
315
7.46k
  STORE_OPCODE(STORE8, STRBi12);
316
7.46k
  STORE_OPCODE(LOAD8, LDRBi12);
317
7.46k
318
7.46k
  STORE_OPCODE(ADDrr, ADDrr);
319
7.46k
  STORE_OPCODE(ADDri, ADDri);
320
7.46k
321
7.46k
  STORE_OPCODE(CMPrr, CMPrr);
322
7.46k
  STORE_OPCODE(MOVi, MOVi);
323
7.46k
  STORE_OPCODE(MOVCCi, MOVCCi);
324
7.46k
325
7.46k
  STORE_OPCODE(MOVCCr, MOVCCr);
326
7.46k
327
7.46k
  STORE_OPCODE(TSTri, TSTri);
328
7.46k
  STORE_OPCODE(Bcc, Bcc);
329
7.46k
330
7.46k
  STORE_OPCODE(MOVi32imm, MOVi32imm);
331
7.46k
  ConstPoolLoad = isThumb ? 
ARM::t2LDRpci4.26k
:
ARM::LDRi123.19k
;
332
7.46k
  STORE_OPCODE(MOV_ga_pcrel, MOV_ga_pcrel);
333
7.46k
  LDRLIT_ga_pcrel = isThumb ? 
ARM::tLDRLIT_ga_pcrel4.26k
:
ARM::LDRLIT_ga_pcrel3.19k
;
334
7.46k
  LDRLIT_ga_abs = isThumb ? 
ARM::tLDRLIT_ga_abs4.26k
:
ARM::LDRLIT_ga_abs3.19k
;
335
7.46k
#undef MAP_OPCODE
336
7.46k
}
337
338
unsigned ARMInstructionSelector::selectSimpleExtOpc(unsigned Opc,
339
10
                                                    unsigned Size) const {
340
10
  using namespace TargetOpcode;
341
10
342
10
  if (Size != 8 && 
Size != 163
)
343
0
    return Opc;
344
10
345
10
  if (Opc == G_SEXT)
346
5
    return Size == 8 ? 
Opcodes.SEXT84
:
Opcodes.SEXT161
;
347
5
348
5
  if (Opc == G_ZEXT)
349
5
    return Size == 8 ? 
Opcodes.ZEXT83
:
Opcodes.ZEXT162
;
350
0
351
0
  return Opc;
352
0
}
353
354
unsigned ARMInstructionSelector::selectLoadStoreOpCode(unsigned Opc,
355
                                                       unsigned RegBank,
356
269
                                                       unsigned Size) const {
357
269
  bool isStore = Opc == TargetOpcode::G_STORE;
358
269
359
269
  if (RegBank == ARM::GPRRegBankID) {
360
245
    switch (Size) {
361
245
    case 1:
362
16
    case 8:
363
16
      return isStore ? 
Opcodes.STORE811
:
Opcodes.LOAD85
;
364
17
    case 16:
365
17
      return isStore ? 
Opcodes.STORE1615
:
Opcodes.LOAD162
;
366
212
    case 32:
367
212
      return isStore ? 
Opcodes.STORE325
:
Opcodes.LOAD32207
;
368
16
    default:
369
0
      return Opc;
370
24
    }
371
24
  }
372
24
373
24
  if (RegBank == ARM::FPRRegBankID) {
374
24
    switch (Size) {
375
24
    case 32:
376
12
      return isStore ? 
ARM::VSTRS10
:
ARM::VLDRS2
;
377
24
    case 64:
378
12
      return isStore ? 
ARM::VSTRD10
:
ARM::VLDRD2
;
379
24
    default:
380
0
      return Opc;
381
0
    }
382
0
  }
383
0
384
0
  return Opc;
385
0
}
386
387
// When lowering comparisons, we sometimes need to perform two compares instead
388
// of just one. Get the condition codes for both comparisons. If only one is
389
// needed, the second member of the pair is ARMCC::AL.
390
static std::pair<ARMCC::CondCodes, ARMCC::CondCodes>
391
57
getComparePreds(CmpInst::Predicate Pred) {
392
57
  std::pair<ARMCC::CondCodes, ARMCC::CondCodes> Preds = {ARMCC::AL, ARMCC::AL};
393
57
  switch (Pred) {
394
57
  case CmpInst::FCMP_ONE:
395
3
    Preds = {ARMCC::GT, ARMCC::MI};
396
3
    break;
397
57
  case CmpInst::FCMP_UEQ:
398
2
    Preds = {ARMCC::EQ, ARMCC::VS};
399
2
    break;
400
57
  case CmpInst::ICMP_EQ:
401
5
  case CmpInst::FCMP_OEQ:
402
5
    Preds.first = ARMCC::EQ;
403
5
    break;
404
8
  case CmpInst::ICMP_SGT:
405
8
  case CmpInst::FCMP_OGT:
406
8
    Preds.first = ARMCC::GT;
407
8
    break;
408
8
  case CmpInst::ICMP_SGE:
409
4
  case CmpInst::FCMP_OGE:
410
4
    Preds.first = ARMCC::GE;
411
4
    break;
412
4
  case CmpInst::ICMP_UGT:
413
4
  case CmpInst::FCMP_UGT:
414
4
    Preds.first = ARMCC::HI;
415
4
    break;
416
4
  case CmpInst::FCMP_OLT:
417
2
    Preds.first = ARMCC::MI;
418
2
    break;
419
4
  case CmpInst::ICMP_ULE:
420
4
  case CmpInst::FCMP_OLE:
421
4
    Preds.first = ARMCC::LS;
422
4
    break;
423
4
  case CmpInst::FCMP_ORD:
424
2
    Preds.first = ARMCC::VC;
425
2
    break;
426
4
  case CmpInst::FCMP_UNO:
427
2
    Preds.first = ARMCC::VS;
428
2
    break;
429
4
  case CmpInst::FCMP_UGE:
430
2
    Preds.first = ARMCC::PL;
431
2
    break;
432
6
  case CmpInst::ICMP_SLT:
433
6
  case CmpInst::FCMP_ULT:
434
6
    Preds.first = ARMCC::LT;
435
6
    break;
436
6
  case CmpInst::ICMP_SLE:
437
4
  case CmpInst::FCMP_ULE:
438
4
    Preds.first = ARMCC::LE;
439
4
    break;
440
5
  case CmpInst::FCMP_UNE:
441
5
  case CmpInst::ICMP_NE:
442
5
    Preds.first = ARMCC::NE;
443
5
    break;
444
5
  case CmpInst::ICMP_UGE:
445
2
    Preds.first = ARMCC::HS;
446
2
    break;
447
5
  case CmpInst::ICMP_ULT:
448
2
    Preds.first = ARMCC::LO;
449
2
    break;
450
5
  default:
451
0
    break;
452
57
  }
453
57
  assert(Preds.first != ARMCC::AL && "No comparisons needed?");
454
57
  return Preds;
455
57
}
456
457
struct ARMInstructionSelector::CmpConstants {
458
  CmpConstants(unsigned CmpOpcode, unsigned FlagsOpcode, unsigned SelectOpcode,
459
               unsigned OpRegBank, unsigned OpSize)
460
      : ComparisonOpcode(CmpOpcode), ReadFlagsOpcode(FlagsOpcode),
461
        SelectResultOpcode(SelectOpcode), OperandRegBankID(OpRegBank),
462
61
        OperandSize(OpSize) {}
463
464
  // The opcode used for performing the comparison.
465
  const unsigned ComparisonOpcode;
466
467
  // The opcode used for reading the flags set by the comparison. May be
468
  // ARM::INSTRUCTION_LIST_END if we don't need to read the flags.
469
  const unsigned ReadFlagsOpcode;
470
471
  // The opcode used for materializing the result of the comparison.
472
  const unsigned SelectResultOpcode;
473
474
  // The assumed register bank ID for the operands.
475
  const unsigned OperandRegBankID;
476
477
  // The assumed size in bits for the operands.
478
  const unsigned OperandSize;
479
};
480
481
struct ARMInstructionSelector::InsertInfo {
482
  InsertInfo(MachineInstrBuilder &MIB)
483
      : MBB(*MIB->getParent()), InsertBefore(std::next(MIB->getIterator())),
484
61
        DbgLoc(MIB->getDebugLoc()) {}
485
486
  MachineBasicBlock &MBB;
487
  const MachineBasicBlock::instr_iterator InsertBefore;
488
  const DebugLoc &DbgLoc;
489
};
490
491
void ARMInstructionSelector::putConstant(InsertInfo I, unsigned DestReg,
492
61
                                         unsigned Constant) const {
493
61
  (void)BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(Opcodes.MOVi))
494
61
      .addDef(DestReg)
495
61
      .addImm(Constant)
496
61
      .add(predOps(ARMCC::AL))
497
61
      .add(condCodeOp());
498
61
}
499
500
bool ARMInstructionSelector::validOpRegPair(MachineRegisterInfo &MRI,
501
                                            unsigned LHSReg, unsigned RHSReg,
502
                                            unsigned ExpectedSize,
503
57
                                            unsigned ExpectedRegBankID) const {
504
57
  return MRI.getType(LHSReg) == MRI.getType(RHSReg) &&
505
57
         validReg(MRI, LHSReg, ExpectedSize, ExpectedRegBankID) &&
506
57
         validReg(MRI, RHSReg, ExpectedSize, ExpectedRegBankID);
507
57
}
508
509
bool ARMInstructionSelector::validReg(MachineRegisterInfo &MRI, unsigned Reg,
510
                                      unsigned ExpectedSize,
511
182
                                      unsigned ExpectedRegBankID) const {
512
182
  if (MRI.getType(Reg).getSizeInBits() != ExpectedSize) {
513
0
    LLVM_DEBUG(dbgs() << "Unexpected size for register");
514
0
    return false;
515
0
  }
516
182
517
182
  if (RBI.getRegBank(Reg, MRI, TRI)->getID() != ExpectedRegBankID) {
518
0
    LLVM_DEBUG(dbgs() << "Unexpected register bank for register");
519
0
    return false;
520
0
  }
521
182
522
182
  return true;
523
182
}
524
525
bool ARMInstructionSelector::selectCmp(CmpConstants Helper,
526
                                       MachineInstrBuilder &MIB,
527
61
                                       MachineRegisterInfo &MRI) const {
528
61
  const InsertInfo I(MIB);
529
61
530
61
  auto ResReg = MIB->getOperand(0).getReg();
531
61
  if (!validReg(MRI, ResReg, 1, ARM::GPRRegBankID))
532
0
    return false;
533
61
534
61
  auto Cond =
535
61
      static_cast<CmpInst::Predicate>(MIB->getOperand(1).getPredicate());
536
61
  if (Cond == CmpInst::FCMP_TRUE || 
Cond == CmpInst::FCMP_FALSE59
) {
537
4
    putConstant(I, ResReg, Cond == CmpInst::FCMP_TRUE ? 
12
:
02
);
538
4
    MIB->eraseFromParent();
539
4
    return true;
540
4
  }
541
57
542
57
  auto LHSReg = MIB->getOperand(2).getReg();
543
57
  auto RHSReg = MIB->getOperand(3).getReg();
544
57
  if (!validOpRegPair(MRI, LHSReg, RHSReg, Helper.OperandSize,
545
57
                      Helper.OperandRegBankID))
546
0
    return false;
547
57
548
57
  auto ARMConds = getComparePreds(Cond);
549
57
  auto ZeroReg = MRI.createVirtualRegister(&ARM::GPRRegClass);
550
57
  putConstant(I, ZeroReg, 0);
551
57
552
57
  if (ARMConds.second == ARMCC::AL) {
553
52
    // Simple case, we only need one comparison and we're done.
554
52
    if (!insertComparison(Helper, I, ResReg, ARMConds.first, LHSReg, RHSReg,
555
52
                          ZeroReg))
556
0
      return false;
557
5
  } else {
558
5
    // Not so simple, we need two successive comparisons.
559
5
    auto IntermediateRes = MRI.createVirtualRegister(&ARM::GPRRegClass);
560
5
    if (!insertComparison(Helper, I, IntermediateRes, ARMConds.first, LHSReg,
561
5
                          RHSReg, ZeroReg))
562
0
      return false;
563
5
    if (!insertComparison(Helper, I, ResReg, ARMConds.second, LHSReg, RHSReg,
564
5
                          IntermediateRes))
565
0
      return false;
566
57
  }
567
57
568
57
  MIB->eraseFromParent();
569
57
  return true;
570
57
}
571
572
bool ARMInstructionSelector::insertComparison(CmpConstants Helper, InsertInfo I,
573
                                              unsigned ResReg,
574
                                              ARMCC::CondCodes Cond,
575
                                              unsigned LHSReg, unsigned RHSReg,
576
62
                                              unsigned PrevRes) const {
577
62
  // Perform the comparison.
578
62
  auto CmpI =
579
62
      BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(Helper.ComparisonOpcode))
580
62
          .addUse(LHSReg)
581
62
          .addUse(RHSReg)
582
62
          .add(predOps(ARMCC::AL));
583
62
  if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
584
0
    return false;
585
62
586
62
  // Read the comparison flags (if necessary).
587
62
  if (Helper.ReadFlagsOpcode != ARM::INSTRUCTION_LIST_END) {
588
35
    auto ReadI = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc,
589
35
                         TII.get(Helper.ReadFlagsOpcode))
590
35
                     .add(predOps(ARMCC::AL));
591
35
    if (!constrainSelectedInstRegOperands(*ReadI, TII, TRI, RBI))
592
0
      return false;
593
62
  }
594
62
595
62
  // Select either 1 or the previous result based on the value of the flags.
596
62
  auto Mov1I = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc,
597
62
                       TII.get(Helper.SelectResultOpcode))
598
62
                   .addDef(ResReg)
599
62
                   .addUse(PrevRes)
600
62
                   .addImm(1)
601
62
                   .add(predOps(Cond, ARM::CPSR));
602
62
  if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
603
0
    return false;
604
62
605
62
  return true;
606
62
}
607
608
bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB,
609
197
                                          MachineRegisterInfo &MRI) const {
610
197
  if ((STI.isROPI() || 
STI.isRWPI()131
) &&
!STI.isTargetELF()99
) {
611
0
    LLVM_DEBUG(dbgs() << "ROPI and RWPI only supported for ELF\n");
612
0
    return false;
613
0
  }
614
197
615
197
  auto GV = MIB->getOperand(1).getGlobal();
616
197
  if (GV->isThreadLocal()) {
617
5
    LLVM_DEBUG(dbgs() << "TLS variables not supported yet\n");
618
5
    return false;
619
5
  }
620
192
621
192
  auto &MBB = *MIB->getParent();
622
192
  auto &MF = *MBB.getParent();
623
192
624
192
  bool UseMovt = STI.useMovt();
625
192
626
192
  unsigned Size = TM.getPointerSize(0);
627
192
  unsigned Alignment = 4;
628
192
629
192
  auto addOpsForConstantPoolLoad = [&MF, Alignment,
630
192
                                    Size](MachineInstrBuilder &MIB,
631
192
                                          const GlobalValue *GV, bool IsSBREL) {
632
40
    assert((MIB->getOpcode() == ARM::LDRi12 ||
633
40
            MIB->getOpcode() == ARM::t2LDRpci) &&
634
40
           "Unsupported instruction");
635
40
    auto ConstPool = MF.getConstantPool();
636
40
    auto CPIndex =
637
40
        // For SB relative entries we need a target-specific constant pool.
638
40
        // Otherwise, just use a regular constant pool entry.
639
40
        IsSBREL
640
40
            ? ConstPool->getConstantPoolIndex(
641
16
                  ARMConstantPoolConstant::Create(GV, ARMCP::SBREL), Alignment)
642
40
            : 
ConstPool->getConstantPoolIndex(GV, Alignment)24
;
643
40
    MIB.addConstantPoolIndex(CPIndex, /*Offset*/ 0, /*TargetFlags*/ 0)
644
40
        .addMemOperand(MF.getMachineMemOperand(
645
40
            MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
646
40
            Size, Alignment));
647
40
    if (MIB->getOpcode() == ARM::LDRi12)
648
20
      MIB.addImm(0);
649
40
    MIB.add(predOps(ARMCC::AL));
650
40
  };
651
192
652
192
  auto addGOTMemOperand = [this, &MF, Alignment](MachineInstrBuilder &MIB) {
653
32
    MIB.addMemOperand(MF.getMachineMemOperand(
654
32
        MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad,
655
32
        TM.getProgramPointerSize(), Alignment));
656
32
  };
657
192
658
192
  if (TM.isPositionIndependent()) {
659
64
    bool Indirect = STI.isGVIndirectSymbol(GV);
660
64
661
64
    // For ARM mode, we have different pseudoinstructions for direct accesses
662
64
    // and indirect accesses, and the ones for indirect accesses include the
663
64
    // load from GOT. For Thumb mode, we use the same pseudoinstruction for both
664
64
    // direct and indirect accesses, and we need to manually generate the load
665
64
    // from GOT.
666
64
    bool UseOpcodeThatLoads = Indirect && 
!STI.isThumb()32
;
667
64
668
64
    // FIXME: Taking advantage of MOVT for ELF is pretty involved, so we don't
669
64
    // support it yet. See PR28229.
670
64
    unsigned Opc =
671
64
        UseMovt && 
!STI.isTargetELF()32
672
64
            ? 
(UseOpcodeThatLoads 16
?
(unsigned)ARM::MOV_ga_pcrel_ldr4
673
16
                                  : 
Opcodes.MOV_ga_pcrel12
)
674
64
            : 
(UseOpcodeThatLoads 48
?
(unsigned)ARM::LDRLIT_ga_pcrel_ldr12
675
48
                                  : 
Opcodes.LDRLIT_ga_pcrel36
);
676
64
    MIB->setDesc(TII.get(Opc));
677
64
678
64
    int TargetFlags = ARMII::MO_NO_FLAG;
679
64
    if (STI.isTargetDarwin())
680
32
      TargetFlags |= ARMII::MO_NONLAZY;
681
64
    if (STI.isGVInGOT(GV))
682
16
      TargetFlags |= ARMII::MO_GOT;
683
64
    MIB->getOperand(1).setTargetFlags(TargetFlags);
684
64
685
64
    if (Indirect) {
686
32
      if (!UseOpcodeThatLoads) {
687
16
        auto ResultReg = MIB->getOperand(0).getReg();
688
16
        auto AddressReg = MRI.createVirtualRegister(&ARM::GPRRegClass);
689
16
690
16
        MIB->getOperand(0).setReg(AddressReg);
691
16
692
16
        auto InsertBefore = std::next(MIB->getIterator());
693
16
        auto MIBLoad = BuildMI(MBB, InsertBefore, MIB->getDebugLoc(),
694
16
                               TII.get(Opcodes.LOAD32))
695
16
                           .addDef(ResultReg)
696
16
                           .addReg(AddressReg)
697
16
                           .addImm(0)
698
16
                           .add(predOps(ARMCC::AL));
699
16
        addGOTMemOperand(MIBLoad);
700
16
701
16
        if (!constrainSelectedInstRegOperands(*MIBLoad, TII, TRI, RBI))
702
0
          return false;
703
16
      } else {
704
16
        addGOTMemOperand(MIB);
705
16
      }
706
32
    }
707
64
708
64
    return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
709
128
  }
710
128
711
128
  bool isReadOnly = STI.getTargetLowering()->isReadOnly(GV);
712
128
  if (STI.isROPI() && 
isReadOnly64
) {
713
32
    unsigned Opc = UseMovt ? 
Opcodes.MOV_ga_pcrel16
:
Opcodes.LDRLIT_ga_pcrel16
;
714
32
    MIB->setDesc(TII.get(Opc));
715
32
    return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
716
32
  }
717
96
  if (STI.isRWPI() && 
!isReadOnly48
) {
718
32
    auto Offset = MRI.createVirtualRegister(&ARM::GPRRegClass);
719
32
    MachineInstrBuilder OffsetMIB;
720
32
    if (UseMovt) {
721
16
      OffsetMIB = BuildMI(MBB, *MIB, MIB->getDebugLoc(),
722
16
                          TII.get(Opcodes.MOVi32imm), Offset);
723
16
      OffsetMIB.addGlobalAddress(GV, /*Offset*/ 0, ARMII::MO_SBREL);
724
16
    } else {
725
16
      // Load the offset from the constant pool.
726
16
      OffsetMIB = BuildMI(MBB, *MIB, MIB->getDebugLoc(),
727
16
                          TII.get(Opcodes.ConstPoolLoad), Offset);
728
16
      addOpsForConstantPoolLoad(OffsetMIB, GV, /*IsSBREL*/ true);
729
16
    }
730
32
    if (!constrainSelectedInstRegOperands(*OffsetMIB, TII, TRI, RBI))
731
0
      return false;
732
32
733
32
    // Add the offset to the SB register.
734
32
    MIB->setDesc(TII.get(Opcodes.ADDrr));
735
32
    MIB->RemoveOperand(1);
736
32
    MIB.addReg(ARM::R9) // FIXME: don't hardcode R9
737
32
        .addReg(Offset)
738
32
        .add(predOps(ARMCC::AL))
739
32
        .add(condCodeOp());
740
32
741
32
    return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
742
32
  }
743
64
744
64
  if (STI.isTargetELF()) {
745
48
    if (UseMovt) {
746
24
      MIB->setDesc(TII.get(Opcodes.MOVi32imm));
747
24
    } else {
748
24
      // Load the global's address from the constant pool.
749
24
      MIB->setDesc(TII.get(Opcodes.ConstPoolLoad));
750
24
      MIB->RemoveOperand(1);
751
24
      addOpsForConstantPoolLoad(MIB, GV, /*IsSBREL*/ false);
752
24
    }
753
48
  } else 
if (16
STI.isTargetMachO()16
) {
754
16
    if (UseMovt)
755
8
      MIB->setDesc(TII.get(Opcodes.MOVi32imm));
756
8
    else
757
8
      MIB->setDesc(TII.get(Opcodes.LDRLIT_ga_abs));
758
16
  } else {
759
0
    LLVM_DEBUG(dbgs() << "Object format not supported yet\n");
760
0
    return false;
761
0
  }
762
64
763
64
  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
764
64
}
765
766
bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB,
767
6
                                          MachineRegisterInfo &MRI) const {
768
6
  auto &MBB = *MIB->getParent();
769
6
  auto InsertBefore = std::next(MIB->getIterator());
770
6
  auto &DbgLoc = MIB->getDebugLoc();
771
6
772
6
  // Compare the condition to 1.
773
6
  auto CondReg = MIB->getOperand(1).getReg();
774
6
  assert(validReg(MRI, CondReg, 1, ARM::GPRRegBankID) &&
775
6
         "Unsupported types for select operation");
776
6
  auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(Opcodes.TSTri))
777
6
                  .addUse(CondReg)
778
6
                  .addImm(1)
779
6
                  .add(predOps(ARMCC::AL));
780
6
  if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
781
0
    return false;
782
6
783
6
  // Move a value into the result register based on the result of the
784
6
  // comparison.
785
6
  auto ResReg = MIB->getOperand(0).getReg();
786
6
  auto TrueReg = MIB->getOperand(2).getReg();
787
6
  auto FalseReg = MIB->getOperand(3).getReg();
788
6
  assert(validOpRegPair(MRI, ResReg, TrueReg, 32, ARM::GPRRegBankID) &&
789
6
         validOpRegPair(MRI, TrueReg, FalseReg, 32, ARM::GPRRegBankID) &&
790
6
         "Unsupported types for select operation");
791
6
  auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(Opcodes.MOVCCr))
792
6
                   .addDef(ResReg)
793
6
                   .addUse(TrueReg)
794
6
                   .addUse(FalseReg)
795
6
                   .add(predOps(ARMCC::EQ, ARM::CPSR));
796
6
  if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
797
0
    return false;
798
6
799
6
  MIB->eraseFromParent();
800
6
  return true;
801
6
}
802
803
bool ARMInstructionSelector::selectShift(unsigned ShiftOpc,
804
78
                                         MachineInstrBuilder &MIB) const {
805
78
  assert(!STI.isThumb() && "Unsupported subtarget");
806
78
  MIB->setDesc(TII.get(ARM::MOVsr));
807
78
  MIB.addImm(ShiftOpc);
808
78
  MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
809
78
  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
810
78
}
811
812
void ARMInstructionSelector::renderVFPF32Imm(
813
2
    MachineInstrBuilder &NewInstBuilder, const MachineInstr &OldInst) const {
814
2
  assert(OldInst.getOpcode() == TargetOpcode::G_FCONSTANT &&
815
2
         "Expected G_FCONSTANT");
816
2
817
2
  APFloat FPImmValue = OldInst.getOperand(1).getFPImm()->getValueAPF();
818
2
  int FPImmEncoding = ARM_AM::getFP32Imm(FPImmValue);
819
2
  assert(FPImmEncoding != -1 && "Invalid immediate value");
820
2
821
2
  NewInstBuilder.addImm(FPImmEncoding);
822
2
}
823
824
void ARMInstructionSelector::renderVFPF64Imm(
825
2
    MachineInstrBuilder &NewInstBuilder, const MachineInstr &OldInst) const {
826
2
  assert(OldInst.getOpcode() == TargetOpcode::G_FCONSTANT &&
827
2
         "Expected G_FCONSTANT");
828
2
829
2
  APFloat FPImmValue = OldInst.getOperand(1).getFPImm()->getValueAPF();
830
2
  int FPImmEncoding = ARM_AM::getFP64Imm(FPImmValue);
831
2
  assert(FPImmEncoding != -1 && "Invalid immediate value");
832
2
833
2
  NewInstBuilder.addImm(FPImmEncoding);
834
2
}
835
836
bool ARMInstructionSelector::select(MachineInstr &I,
837
3.44k
                                    CodeGenCoverage &CoverageInfo) const {
838
3.44k
  assert(I.getParent() && "Instruction should be in a basic block!");
839
3.44k
  assert(I.getParent()->getParent() && "Instruction should be in a function!");
840
3.44k
841
3.44k
  auto &MBB = *I.getParent();
842
3.44k
  auto &MF = *MBB.getParent();
843
3.44k
  auto &MRI = MF.getRegInfo();
844
3.44k
845
3.44k
  if (!isPreISelGenericOpcode(I.getOpcode())) {
846
2.32k
    if (I.isCopy())
847
1.57k
      return selectCopy(I, TII, MRI, TRI, RBI);
848
752
849
752
    return true;
850
752
  }
851
1.11k
852
1.11k
  using namespace TargetOpcode;
853
1.11k
854
1.11k
  if (selectImpl(I, CoverageInfo))
855
293
    return true;
856
820
857
820
  MachineInstrBuilder MIB{MF, I};
858
820
  bool isSExt = false;
859
820
860
820
  switch (I.getOpcode()) {
861
820
  case G_SEXT:
862
11
    isSExt = true;
863
11
    LLVM_FALLTHROUGH;
864
80
  case G_ZEXT: {
865
80
    assert(MRI.getType(I.getOperand(0).getReg()).getSizeInBits() <= 32 &&
866
80
           "Unsupported destination size for extension");
867
80
868
80
    LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
869
80
    unsigned SrcSize = SrcTy.getSizeInBits();
870
80
    switch (SrcSize) {
871
80
    case 1: {
872
70
      // ZExt boils down to & 0x1; for SExt we also subtract that from 0
873
70
      I.setDesc(TII.get(Opcodes.AND));
874
70
      MIB.addImm(1).add(predOps(ARMCC::AL)).add(condCodeOp());
875
70
876
70
      if (isSExt) {
877
6
        unsigned SExtResult = I.getOperand(0).getReg();
878
6
879
6
        // Use a new virtual register for the result of the AND
880
6
        unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass);
881
6
        I.getOperand(0).setReg(AndResult);
882
6
883
6
        auto InsertBefore = std::next(I.getIterator());
884
6
        auto SubI =
885
6
            BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(Opcodes.RSB))
886
6
                .addDef(SExtResult)
887
6
                .addUse(AndResult)
888
6
                .addImm(0)
889
6
                .add(predOps(ARMCC::AL))
890
6
                .add(condCodeOp());
891
6
        if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI))
892
0
          return false;
893
70
      }
894
70
      break;
895
70
    }
896
70
    case 8:
897
10
    case 16: {
898
10
      unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
899
10
      if (NewOpc == I.getOpcode())
900
0
        return false;
901
10
      I.setDesc(TII.get(NewOpc));
902
10
      MIB.addImm(0).add(predOps(ARMCC::AL));
903
10
      break;
904
10
    }
905
10
    default:
906
0
      LLVM_DEBUG(dbgs() << "Unsupported source size for extension");
907
0
      return false;
908
80
    }
909
80
    break;
910
80
  }
911
80
  case G_ANYEXT:
912
69
  case G_TRUNC: {
913
69
    // The high bits are undefined, so there's nothing special to do, just
914
69
    // treat it as a copy.
915
69
    auto SrcReg = I.getOperand(1).getReg();
916
69
    auto DstReg = I.getOperand(0).getReg();
917
69
918
69
    const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
919
69
    const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
920
69
921
69
    if (SrcRegBank.getID() == ARM::FPRRegBankID) {
922
2
      // This should only happen in the obscure case where we have put a 64-bit
923
2
      // integer into a D register. Get it out of there and keep only the
924
2
      // interesting part.
925
2
      assert(I.getOpcode() == G_TRUNC && "Unsupported operand for G_ANYEXT");
926
2
      assert(DstRegBank.getID() == ARM::GPRRegBankID &&
927
2
             "Unsupported combination of register banks");
928
2
      assert(MRI.getType(SrcReg).getSizeInBits() == 64 && "Unsupported size");
929
2
      assert(MRI.getType(DstReg).getSizeInBits() <= 32 && "Unsupported size");
930
2
931
2
      unsigned IgnoredBits = MRI.createVirtualRegister(&ARM::GPRRegClass);
932
2
      auto InsertBefore = std::next(I.getIterator());
933
2
      auto MovI =
934
2
          BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::VMOVRRD))
935
2
              .addDef(DstReg)
936
2
              .addDef(IgnoredBits)
937
2
              .addUse(SrcReg)
938
2
              .add(predOps(ARMCC::AL));
939
2
      if (!constrainSelectedInstRegOperands(*MovI, TII, TRI, RBI))
940
0
        return false;
941
2
942
2
      MIB->eraseFromParent();
943
2
      return true;
944
2
    }
945
67
946
67
    if (SrcRegBank.getID() != DstRegBank.getID()) {
947
0
      LLVM_DEBUG(
948
0
          dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n");
949
0
      return false;
950
0
    }
951
67
952
67
    if (SrcRegBank.getID() != ARM::GPRRegBankID) {
953
0
      LLVM_DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n");
954
0
      return false;
955
0
    }
956
67
957
67
    I.setDesc(TII.get(COPY));
958
67
    return selectCopy(I, TII, MRI, TRI, RBI);
959
67
  }
960
67
  case G_CONSTANT: {
961
2
    if (!MRI.getType(I.getOperand(0).getReg()).isPointer()) {
962
0
      // Non-pointer constants should be handled by TableGen.
963
0
      LLVM_DEBUG(dbgs() << "Unsupported constant type\n");
964
0
      return false;
965
0
    }
966
2
967
2
    auto &Val = I.getOperand(1);
968
2
    if (Val.isCImm()) {
969
2
      if (!Val.getCImm()->isZero()) {
970
0
        LLVM_DEBUG(dbgs() << "Unsupported pointer constant value\n");
971
0
        return false;
972
0
      }
973
2
      Val.ChangeToImmediate(0);
974
2
    } else {
975
0
      assert(Val.isImm() && "Unexpected operand for G_CONSTANT");
976
0
      if (Val.getImm() != 0) {
977
0
        LLVM_DEBUG(dbgs() << "Unsupported pointer constant value\n");
978
0
        return false;
979
0
      }
980
2
    }
981
2
982
2
    assert(!STI.isThumb() && "Unsupported subtarget");
983
2
    I.setDesc(TII.get(ARM::MOVi));
984
2
    MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
985
2
    break;
986
2
  }
987
12
  case G_FCONSTANT: {
988
12
    // Load from constant pool
989
12
    unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits() / 8;
990
12
    unsigned Alignment = Size;
991
12
992
12
    assert((Size == 4 || Size == 8) && "Unsupported FP constant type");
993
12
    auto LoadOpcode = Size == 4 ? 
ARM::VLDRS6
:
ARM::VLDRD6
;
994
12
995
12
    auto ConstPool = MF.getConstantPool();
996
12
    auto CPIndex =
997
12
        ConstPool->getConstantPoolIndex(I.getOperand(1).getFPImm(), Alignment);
998
12
    MIB->setDesc(TII.get(LoadOpcode));
999
12
    MIB->RemoveOperand(1);
1000
12
    MIB.addConstantPoolIndex(CPIndex, /*Offset*/ 0, /*TargetFlags*/ 0)
1001
12
        .addMemOperand(
1002
12
            MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF),
1003
12
                                    MachineMemOperand::MOLoad, Size, Alignment))
1004
12
        .addImm(0)
1005
12
        .add(predOps(ARMCC::AL));
1006
12
    break;
1007
2
  }
1008
4
  case G_INTTOPTR:
1009
4
  case G_PTRTOINT: {
1010
4
    auto SrcReg = I.getOperand(1).getReg();
1011
4
    auto DstReg = I.getOperand(0).getReg();
1012
4
1013
4
    const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
1014
4
    const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1015
4
1016
4
    if (SrcRegBank.getID() != DstRegBank.getID()) {
1017
0
      LLVM_DEBUG(
1018
0
          dbgs()
1019
0
          << "G_INTTOPTR/G_PTRTOINT operands on different register banks\n");
1020
0
      return false;
1021
0
    }
1022
4
1023
4
    if (SrcRegBank.getID() != ARM::GPRRegBankID) {
1024
0
      LLVM_DEBUG(
1025
0
          dbgs() << "G_INTTOPTR/G_PTRTOINT on non-GPR not supported yet\n");
1026
0
      return false;
1027
0
    }
1028
4
1029
4
    I.setDesc(TII.get(COPY));
1030
4
    return selectCopy(I, TII, MRI, TRI, RBI);
1031
4
  }
1032
6
  case G_SELECT:
1033
6
    return selectSelect(MIB, MRI);
1034
27
  case G_ICMP: {
1035
27
    CmpConstants Helper(Opcodes.CMPrr, ARM::INSTRUCTION_LIST_END,
1036
27
                        Opcodes.MOVCCi, ARM::GPRRegBankID, 32);
1037
27
    return selectCmp(Helper, MIB, MRI);
1038
4
  }
1039
34
  case G_FCMP: {
1040
34
    assert(STI.hasVFP2Base() && "Can't select fcmp without VFP");
1041
34
1042
34
    unsigned OpReg = I.getOperand(2).getReg();
1043
34
    unsigned Size = MRI.getType(OpReg).getSizeInBits();
1044
34
1045
34
    if (Size == 64 && 
!STI.hasFP64()16
) {
1046
0
      LLVM_DEBUG(dbgs() << "Subtarget only supports single precision");
1047
0
      return false;
1048
0
    }
1049
34
    if (Size != 32 && 
Size != 6416
) {
1050
0
      LLVM_DEBUG(dbgs() << "Unsupported size for G_FCMP operand");
1051
0
      return false;
1052
0
    }
1053
34
1054
34
    CmpConstants Helper(Size == 32 ? 
ARM::VCMPS18
:
ARM::VCMPD16
, ARM::FMSTAT,
1055
34
                        Opcodes.MOVCCi, ARM::FPRRegBankID, Size);
1056
34
    return selectCmp(Helper, MIB, MRI);
1057
34
  }
1058
34
  case G_LSHR:
1059
2
    return selectShift(ARM_AM::ShiftOpc::lsr, MIB);
1060
38
  case G_ASHR:
1061
38
    return selectShift(ARM_AM::ShiftOpc::asr, MIB);
1062
38
  case G_SHL: {
1063
38
    return selectShift(ARM_AM::ShiftOpc::lsl, MIB);
1064
34
  }
1065
34
  case G_GEP:
1066
2
    I.setDesc(TII.get(Opcodes.ADDrr));
1067
2
    MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
1068
2
    break;
1069
34
  case G_FRAME_INDEX:
1070
10
    // Add 0 to the given frame index and hope it will eventually be folded into
1071
10
    // the user(s).
1072
10
    I.setDesc(TII.get(Opcodes.ADDri));
1073
10
    MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp());
1074
10
    break;
1075
197
  case G_GLOBAL_VALUE:
1076
197
    return selectGlobal(MIB, MRI);
1077
269
  case G_STORE:
1078
269
  case G_LOAD: {
1079
269
    const auto &MemOp = **I.memoperands_begin();
1080
269
    if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
1081
0
      LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n");
1082
0
      return false;
1083
0
    }
1084
269
1085
269
    unsigned Reg = I.getOperand(0).getReg();
1086
269
    unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID();
1087
269
1088
269
    LLT ValTy = MRI.getType(Reg);
1089
269
    const auto ValSize = ValTy.getSizeInBits();
1090
269
1091
269
    assert((ValSize != 64 || STI.hasVFP2Base()) &&
1092
269
           "Don't know how to load/store 64-bit value without VFP");
1093
269
1094
269
    const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
1095
269
    if (NewOpc == G_LOAD || NewOpc == G_STORE)
1096
0
      return false;
1097
269
1098
269
    if (ValSize == 1 && 
NewOpc == Opcodes.STORE85
) {
1099
2
      // Before storing a 1-bit value, make sure to clear out any unneeded bits.
1100
2
      unsigned OriginalValue = I.getOperand(0).getReg();
1101
2
1102
2
      unsigned ValueToStore = MRI.createVirtualRegister(&ARM::GPRRegClass);
1103
2
      I.getOperand(0).setReg(ValueToStore);
1104
2
1105
2
      auto InsertBefore = I.getIterator();
1106
2
      auto AndI = BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(Opcodes.AND))
1107
2
        .addDef(ValueToStore)
1108
2
        .addUse(OriginalValue)
1109
2
        .addImm(1)
1110
2
        .add(predOps(ARMCC::AL))
1111
2
        .add(condCodeOp());
1112
2
      if (!constrainSelectedInstRegOperands(*AndI, TII, TRI, RBI))
1113
0
        return false;
1114
269
    }
1115
269
1116
269
    I.setDesc(TII.get(NewOpc));
1117
269
1118
269
    if (NewOpc == ARM::LDRH || 
NewOpc == ARM::STRH268
)
1119
9
      // LDRH has a funny addressing mode (there's already a FIXME for it).
1120
9
      MIB.addReg(0);
1121
269
    MIB.addImm(0).add(predOps(ARMCC::AL));
1122
269
    break;
1123
269
  }
1124
269
  case G_MERGE_VALUES: {
1125
12
    if (!selectMergeValues(MIB, TII, MRI, TRI, RBI))
1126
0
      return false;
1127
12
    break;
1128
12
  }
1129
12
  case G_UNMERGE_VALUES: {
1130
7
    if (!selectUnmergeValues(MIB, TII, MRI, TRI, RBI))
1131
0
      return false;
1132
7
    break;
1133
7
  }
1134
7
  case G_BRCOND: {
1135
7
    if (!validReg(MRI, I.getOperand(0).getReg(), 1, ARM::GPRRegBankID)) {
1136
0
      LLVM_DEBUG(dbgs() << "Unsupported condition register for G_BRCOND");
1137
0
      return false;
1138
0
    }
1139
7
1140
7
    // Set the flags.
1141
7
    auto Test =
1142
7
        BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcodes.TSTri))
1143
7
            .addReg(I.getOperand(0).getReg())
1144
7
            .addImm(1)
1145
7
            .add(predOps(ARMCC::AL));
1146
7
    if (!constrainSelectedInstRegOperands(*Test, TII, TRI, RBI))
1147
0
      return false;
1148
7
1149
7
    // Branch conditionally.
1150
7
    auto Branch =
1151
7
        BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcodes.Bcc))
1152
7
            .add(I.getOperand(1))
1153
7
            .add(predOps(ARMCC::NE, ARM::CPSR));
1154
7
    if (!constrainSelectedInstRegOperands(*Branch, TII, TRI, RBI))
1155
0
      return false;
1156
7
    I.eraseFromParent();
1157
7
    return true;
1158
7
  }
1159
7
  case G_PHI: {
1160
4
    I.setDesc(TII.get(PHI));
1161
4
1162
4
    unsigned DstReg = I.getOperand(0).getReg();
1163
4
    const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI);
1164
4
    if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
1165
0
      break;
1166
0
    }
1167
4
1168
4
    return true;
1169
4
  }
1170
4
  default:
1171
0
    return false;
1172
394
  }
1173
394
1174
394
  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1175
394
}