Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- Thumb2InstrInfo.cpp - Thumb-2 Instruction Information --------------===//
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 the Thumb-2 implementation of the TargetInstrInfo class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "Thumb2InstrInfo.h"
14
#include "ARMMachineFunctionInfo.h"
15
#include "MCTargetDesc/ARMAddressingModes.h"
16
#include "llvm/CodeGen/MachineBasicBlock.h"
17
#include "llvm/CodeGen/MachineFrameInfo.h"
18
#include "llvm/CodeGen/MachineFunction.h"
19
#include "llvm/CodeGen/MachineInstr.h"
20
#include "llvm/CodeGen/MachineInstrBuilder.h"
21
#include "llvm/CodeGen/MachineMemOperand.h"
22
#include "llvm/CodeGen/MachineOperand.h"
23
#include "llvm/CodeGen/MachineRegisterInfo.h"
24
#include "llvm/CodeGen/TargetRegisterInfo.h"
25
#include "llvm/IR/DebugLoc.h"
26
#include "llvm/MC/MCInst.h"
27
#include "llvm/MC/MCInstrDesc.h"
28
#include "llvm/Support/CommandLine.h"
29
#include "llvm/Support/ErrorHandling.h"
30
#include "llvm/Support/MathExtras.h"
31
#include "llvm/Target/TargetMachine.h"
32
#include <cassert>
33
34
using namespace llvm;
35
36
static cl::opt<bool>
37
OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden,
38
           cl::desc("Use old-style Thumb2 if-conversion heuristics"),
39
           cl::init(false));
40
41
Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
42
3.52k
    : ARMBaseInstrInfo(STI) {}
43
44
/// Return the noop instruction to use for a noop.
45
0
void Thumb2InstrInfo::getNoop(MCInst &NopInst) const {
46
0
  NopInst.setOpcode(ARM::tHINT);
47
0
  NopInst.addOperand(MCOperand::createImm(0));
48
0
  NopInst.addOperand(MCOperand::createImm(ARMCC::AL));
49
0
  NopInst.addOperand(MCOperand::createReg(0));
50
0
}
51
52
0
unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {
53
0
  // FIXME
54
0
  return 0;
55
0
}
56
57
void
58
Thumb2InstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
59
4.87k
                                         MachineBasicBlock *NewDest) const {
60
4.87k
  MachineBasicBlock *MBB = Tail->getParent();
61
4.87k
  ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
62
4.87k
  if (!AFI->hasITBlocks() || 
Tail->isBranch()794
) {
63
4.08k
    TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest);
64
4.08k
    return;
65
4.08k
  }
66
794
67
794
  // If the first instruction of Tail is predicated, we may have to update
68
794
  // the IT instruction.
69
794
  unsigned PredReg = 0;
70
794
  ARMCC::CondCodes CC = getInstrPredicate(*Tail, PredReg);
71
794
  MachineBasicBlock::iterator MBBI = Tail;
72
794
  if (CC != ARMCC::AL)
73
0
    // Expecting at least the t2IT instruction before it.
74
0
    --MBBI;
75
794
76
794
  // Actually replace the tail.
77
794
  TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest);
78
794
79
794
  // Fix up IT.
80
794
  if (CC != ARMCC::AL) {
81
0
    MachineBasicBlock::iterator E = MBB->begin();
82
0
    unsigned Count = 4; // At most 4 instructions in an IT block.
83
0
    while (Count && MBBI != E) {
84
0
      if (MBBI->isDebugInstr()) {
85
0
        --MBBI;
86
0
        continue;
87
0
      }
88
0
      if (MBBI->getOpcode() == ARM::t2IT) {
89
0
        unsigned Mask = MBBI->getOperand(1).getImm();
90
0
        if (Count == 4)
91
0
          MBBI->eraseFromParent();
92
0
        else {
93
0
          unsigned MaskOn = 1 << Count;
94
0
          unsigned MaskOff = ~(MaskOn - 1);
95
0
          MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
96
0
        }
97
0
        return;
98
0
      }
99
0
      --MBBI;
100
0
      --Count;
101
0
    }
102
0
103
0
    // Ctrl flow can reach here if branch folding is run before IT block
104
0
    // formation pass.
105
0
  }
106
794
}
107
108
bool
109
Thumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB,
110
1.35k
                                     MachineBasicBlock::iterator MBBI) const {
111
1.35k
  while (MBBI->isDebugInstr()) {
112
0
    ++MBBI;
113
0
    if (MBBI == MBB.end())
114
0
      return false;
115
0
  }
116
1.35k
117
1.35k
  unsigned PredReg = 0;
118
1.35k
  return getITInstrPredicate(*MBBI, PredReg) == ARMCC::AL;
119
1.35k
}
120
121
void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
122
                                  MachineBasicBlock::iterator I,
123
                                  const DebugLoc &DL, unsigned DestReg,
124
71.6k
                                  unsigned SrcReg, bool KillSrc) const {
125
71.6k
  // Handle SPR, DPR, and QPR copies.
126
71.6k
  if (!ARM::GPRRegClass.contains(DestReg, SrcReg))
127
4.84k
    return ARMBaseInstrInfo::copyPhysReg(MBB, I, DL, DestReg, SrcReg, KillSrc);
128
66.7k
129
66.7k
  BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)
130
66.7k
      .addReg(SrcReg, getKillRegState(KillSrc))
131
66.7k
      .add(predOps(ARMCC::AL));
132
66.7k
}
133
134
void Thumb2InstrInfo::
135
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
136
                    unsigned SrcReg, bool isKill, int FI,
137
                    const TargetRegisterClass *RC,
138
5.59k
                    const TargetRegisterInfo *TRI) const {
139
5.59k
  DebugLoc DL;
140
5.59k
  if (I != MBB.end()) 
DL = I->getDebugLoc()5.48k
;
141
5.59k
142
5.59k
  MachineFunction &MF = *MBB.getParent();
143
5.59k
  MachineFrameInfo &MFI = MF.getFrameInfo();
144
5.59k
  MachineMemOperand *MMO = MF.getMachineMemOperand(
145
5.59k
      MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
146
5.59k
      MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
147
5.59k
148
5.59k
  if (ARM::GPRRegClass.hasSubClassEq(RC)) {
149
4.83k
    BuildMI(MBB, I, DL, get(ARM::t2STRi12))
150
4.83k
        .addReg(SrcReg, getKillRegState(isKill))
151
4.83k
        .addFrameIndex(FI)
152
4.83k
        .addImm(0)
153
4.83k
        .addMemOperand(MMO)
154
4.83k
        .add(predOps(ARMCC::AL));
155
4.83k
    return;
156
4.83k
  }
157
757
158
757
  if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
159
2
    // Thumb2 STRD expects its dest-registers to be in rGPR. Not a problem for
160
2
    // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
161
2
    // otherwise).
162
2
    if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
163
2
      MachineRegisterInfo *MRI = &MF.getRegInfo();
164
2
      MRI->constrainRegClass(SrcReg, &ARM::GPRPair_with_gsub_1_in_GPRwithAPSRnospRegClass);
165
2
    }
166
2
167
2
    MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2STRDi8));
168
2
    AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill), TRI);
169
2
    AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
170
2
    MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO).add(predOps(ARMCC::AL));
171
2
    return;
172
2
  }
173
755
174
755
  ARMBaseInstrInfo::storeRegToStackSlot(MBB, I, SrcReg, isKill, FI, RC, TRI);
175
755
}
176
177
void Thumb2InstrInfo::
178
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
179
                     unsigned DestReg, int FI,
180
                     const TargetRegisterClass *RC,
181
7.59k
                     const TargetRegisterInfo *TRI) const {
182
7.59k
  MachineFunction &MF = *MBB.getParent();
183
7.59k
  MachineFrameInfo &MFI = MF.getFrameInfo();
184
7.59k
  MachineMemOperand *MMO = MF.getMachineMemOperand(
185
7.59k
      MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
186
7.59k
      MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
187
7.59k
  DebugLoc DL;
188
7.59k
  if (I != MBB.end()) DL = I->getDebugLoc();
189
7.59k
190
7.59k
  if (ARM::GPRRegClass.hasSubClassEq(RC)) {
191
6.57k
    BuildMI(MBB, I, DL, get(ARM::t2LDRi12), DestReg)
192
6.57k
        .addFrameIndex(FI)
193
6.57k
        .addImm(0)
194
6.57k
        .addMemOperand(MMO)
195
6.57k
        .add(predOps(ARMCC::AL));
196
6.57k
    return;
197
6.57k
  }
198
1.02k
199
1.02k
  if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
200
2
    // Thumb2 LDRD expects its dest-registers to be in rGPR. Not a problem for
201
2
    // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
202
2
    // otherwise).
203
2
    if (TargetRegisterInfo::isVirtualRegister(DestReg)) {
204
2
      MachineRegisterInfo *MRI = &MF.getRegInfo();
205
2
      MRI->constrainRegClass(DestReg,
206
2
                             &ARM::GPRPair_with_gsub_1_in_GPRwithAPSRnospRegClass);
207
2
    }
208
2
209
2
    MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2LDRDi8));
210
2
    AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead, TRI);
211
2
    AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead, TRI);
212
2
    MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO).add(predOps(ARMCC::AL));
213
2
214
2
    if (TargetRegisterInfo::isPhysicalRegister(DestReg))
215
0
      MIB.addReg(DestReg, RegState::ImplicitDefine);
216
2
    return;
217
2
  }
218
1.02k
219
1.02k
  ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI);
220
1.02k
}
221
222
void Thumb2InstrInfo::expandLoadStackGuard(
223
134
    MachineBasicBlock::iterator MI) const {
224
134
  MachineFunction &MF = *MI->getParent()->getParent();
225
134
  if (MF.getTarget().isPositionIndependent())
226
130
    expandLoadStackGuardBase(MI, ARM::t2MOV_ga_pcrel, ARM::t2LDRi12);
227
4
  else
228
4
    expandLoadStackGuardBase(MI, ARM::t2MOVi32imm, ARM::t2LDRi12);
229
134
}
230
231
void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
232
                                  MachineBasicBlock::iterator &MBBI,
233
                                  const DebugLoc &dl, unsigned DestReg,
234
                                  unsigned BaseReg, int NumBytes,
235
                                  ARMCC::CondCodes Pred, unsigned PredReg,
236
                                  const ARMBaseInstrInfo &TII,
237
19.4k
                                  unsigned MIFlags) {
238
19.4k
  if (NumBytes == 0 && 
DestReg != BaseReg1.43k
) {
239
1.43k
    BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
240
1.43k
      .addReg(BaseReg, RegState::Kill)
241
1.43k
      .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
242
1.43k
    return;
243
1.43k
  }
244
18.0k
245
18.0k
  bool isSub = NumBytes < 0;
246
18.0k
  if (isSub) 
NumBytes = -NumBytes5.48k
;
247
18.0k
248
18.0k
  // If profitable, use a movw or movt to materialize the offset.
249
18.0k
  // FIXME: Use the scavenger to grab a scratch register.
250
18.0k
  if (DestReg != ARM::SP && 
DestReg != BaseReg6.65k
&&
251
18.0k
      
NumBytes >= 40966.65k
&&
252
18.0k
      
ARM_AM::getT2SOImmVal(NumBytes) == -1569
) {
253
159
    bool Fits = false;
254
159
    if (NumBytes < 65536) {
255
159
      // Use a movw to materialize the 16-bit constant.
256
159
      BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
257
159
        .addImm(NumBytes)
258
159
        .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
259
159
      Fits = true;
260
159
    } else 
if (0
(NumBytes & 0xffff) == 00
) {
261
0
      // Use a movt to materialize the 32-bit constant.
262
0
      BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
263
0
        .addReg(DestReg)
264
0
        .addImm(NumBytes >> 16)
265
0
        .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
266
0
      Fits = true;
267
0
    }
268
159
269
159
    if (Fits) {
270
159
      if (isSub) {
271
0
        BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
272
0
            .addReg(BaseReg)
273
0
            .addReg(DestReg, RegState::Kill)
274
0
            .add(predOps(Pred, PredReg))
275
0
            .add(condCodeOp())
276
0
            .setMIFlags(MIFlags);
277
159
      } else {
278
159
        // Here we know that DestReg is not SP but we do not
279
159
        // know anything about BaseReg. t2ADDrr is an invalid
280
159
        // instruction is SP is used as the second argument, but
281
159
        // is fine if SP is the first argument. To be sure we
282
159
        // do not generate invalid encoding, put BaseReg first.
283
159
        BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
284
159
            .addReg(BaseReg)
285
159
            .addReg(DestReg, RegState::Kill)
286
159
            .add(predOps(Pred, PredReg))
287
159
            .add(condCodeOp())
288
159
            .setMIFlags(MIFlags);
289
159
      }
290
159
      return;
291
159
    }
292
17.8k
  }
293
17.8k
294
36.2k
  
while (17.8k
NumBytes) {
295
18.3k
    unsigned ThisVal = NumBytes;
296
18.3k
    unsigned Opc = 0;
297
18.3k
    if (DestReg == ARM::SP && 
BaseReg != ARM::SP11.8k
) {
298
0
      // mov sp, rn. Note t2MOVr cannot be used.
299
0
      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
300
0
          .addReg(BaseReg)
301
0
          .setMIFlags(MIFlags)
302
0
          .add(predOps(ARMCC::AL));
303
0
      BaseReg = ARM::SP;
304
0
      continue;
305
0
    }
306
18.3k
307
18.3k
    bool HasCCOut = true;
308
18.3k
    if (BaseReg == ARM::SP) {
309
18.1k
      // sub sp, sp, #imm7
310
18.1k
      if (DestReg == ARM::SP && 
(ThisVal < ((1 << 7)-1) * 4)11.8k
) {
311
9.35k
        assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?");
312
9.35k
        Opc = isSub ? 
ARM::tSUBspi4.57k
:
ARM::tADDspi4.77k
;
313
9.35k
        BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
314
9.35k
            .addReg(BaseReg)
315
9.35k
            .addImm(ThisVal / 4)
316
9.35k
            .setMIFlags(MIFlags)
317
9.35k
            .add(predOps(ARMCC::AL));
318
9.35k
        NumBytes = 0;
319
9.35k
        continue;
320
9.35k
      }
321
8.78k
322
8.78k
      // sub rd, sp, so_imm
323
8.78k
      Opc = isSub ? 
ARM::t2SUBri895
:
ARM::t2ADDri7.89k
;
324
8.78k
      if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
325
8.32k
        NumBytes = 0;
326
8.32k
      } else {
327
466
        // FIXME: Move this to ARMAddressingModes.h?
328
466
        unsigned RotAmt = countLeadingZeros(ThisVal);
329
466
        ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
330
466
        NumBytes &= ~ThisVal;
331
466
        assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
332
466
               "Bit extraction didn't work?");
333
466
      }
334
8.78k
    } else {
335
205
      assert(DestReg != ARM::SP && BaseReg != ARM::SP);
336
205
      Opc = isSub ? ARM::t2SUBri : 
ARM::t2ADDri0
;
337
205
      if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
338
205
        NumBytes = 0;
339
205
      } else 
if (0
ThisVal < 40960
) {
340
0
        Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
341
0
        HasCCOut = false;
342
0
        NumBytes = 0;
343
0
      } else {
344
0
        // FIXME: Move this to ARMAddressingModes.h?
345
0
        unsigned RotAmt = countLeadingZeros(ThisVal);
346
0
        ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
347
0
        NumBytes &= ~ThisVal;
348
0
        assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
349
0
               "Bit extraction didn't work?");
350
0
      }
351
205
    }
352
18.3k
353
18.3k
    // Build the new ADD / SUB.
354
18.3k
    MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
355
8.99k
                                  .addReg(BaseReg, RegState::Kill)
356
8.99k
                                  .addImm(ThisVal)
357
8.99k
                                  .add(predOps(ARMCC::AL))
358
8.99k
                                  .setMIFlags(MIFlags);
359
8.99k
    if (HasCCOut)
360
8.99k
      MIB.add(condCodeOp());
361
8.99k
362
8.99k
    BaseReg = DestReg;
363
8.99k
  }
364
17.8k
}
365
366
static unsigned
367
negativeOffsetOpcode(unsigned opcode)
368
588
{
369
588
  switch (opcode) {
370
588
  
case ARM::t2LDRi12: return ARM::t2LDRi8242
;
371
588
  
case ARM::t2LDRHi12: return ARM::t2LDRHi80
;
372
588
  
case ARM::t2LDRBi12: return ARM::t2LDRBi854
;
373
588
  
case ARM::t2LDRSHi12: return ARM::t2LDRSHi80
;
374
588
  
case ARM::t2LDRSBi12: return ARM::t2LDRSBi80
;
375
588
  
case ARM::t2STRi12: return ARM::t2STRi8225
;
376
588
  
case ARM::t2STRBi12: return ARM::t2STRBi867
;
377
588
  
case ARM::t2STRHi12: return ARM::t2STRHi80
;
378
588
  
case ARM::t2PLDi12: return ARM::t2PLDi80
;
379
588
380
588
  case ARM::t2LDRi8:
381
0
  case ARM::t2LDRHi8:
382
0
  case ARM::t2LDRBi8:
383
0
  case ARM::t2LDRSHi8:
384
0
  case ARM::t2LDRSBi8:
385
0
  case ARM::t2STRi8:
386
0
  case ARM::t2STRBi8:
387
0
  case ARM::t2STRHi8:
388
0
  case ARM::t2PLDi8:
389
0
    return opcode;
390
0
391
0
  default:
392
0
    break;
393
0
  }
394
0
395
0
  return 0;
396
0
}
397
398
static unsigned
399
positiveOffsetOpcode(unsigned opcode)
400
38.1k
{
401
38.1k
  switch (opcode) {
402
38.1k
  
case ARM::t2LDRi8: return ARM::t2LDRi120
;
403
38.1k
  
case ARM::t2LDRHi8: return ARM::t2LDRHi120
;
404
38.1k
  
case ARM::t2LDRBi8: return ARM::t2LDRBi120
;
405
38.1k
  
case ARM::t2LDRSHi8: return ARM::t2LDRSHi120
;
406
38.1k
  
case ARM::t2LDRSBi8: return ARM::t2LDRSBi120
;
407
38.1k
  
case ARM::t2STRi8: return ARM::t2STRi120
;
408
38.1k
  
case ARM::t2STRBi8: return ARM::t2STRBi120
;
409
38.1k
  
case ARM::t2STRHi8: return ARM::t2STRHi120
;
410
38.1k
  
case ARM::t2PLDi8: return ARM::t2PLDi120
;
411
38.1k
412
38.1k
  case ARM::t2LDRi12:
413
38.1k
  case ARM::t2LDRHi12:
414
38.1k
  case ARM::t2LDRBi12:
415
38.1k
  case ARM::t2LDRSHi12:
416
38.1k
  case ARM::t2LDRSBi12:
417
38.1k
  case ARM::t2STRi12:
418
38.1k
  case ARM::t2STRBi12:
419
38.1k
  case ARM::t2STRHi12:
420
38.1k
  case ARM::t2PLDi12:
421
38.1k
    return opcode;
422
38.1k
423
38.1k
  default:
424
0
    break;
425
0
  }
426
0
427
0
  return 0;
428
0
}
429
430
static unsigned
431
immediateOffsetOpcode(unsigned opcode)
432
0
{
433
0
  switch (opcode) {
434
0
  case ARM::t2LDRs:   return ARM::t2LDRi12;
435
0
  case ARM::t2LDRHs:  return ARM::t2LDRHi12;
436
0
  case ARM::t2LDRBs:  return ARM::t2LDRBi12;
437
0
  case ARM::t2LDRSHs: return ARM::t2LDRSHi12;
438
0
  case ARM::t2LDRSBs: return ARM::t2LDRSBi12;
439
0
  case ARM::t2STRs:   return ARM::t2STRi12;
440
0
  case ARM::t2STRBs:  return ARM::t2STRBi12;
441
0
  case ARM::t2STRHs:  return ARM::t2STRHi12;
442
0
  case ARM::t2PLDs:   return ARM::t2PLDi12;
443
0
444
0
  case ARM::t2LDRi12:
445
0
  case ARM::t2LDRHi12:
446
0
  case ARM::t2LDRBi12:
447
0
  case ARM::t2LDRSHi12:
448
0
  case ARM::t2LDRSBi12:
449
0
  case ARM::t2STRi12:
450
0
  case ARM::t2STRBi12:
451
0
  case ARM::t2STRHi12:
452
0
  case ARM::t2PLDi12:
453
0
  case ARM::t2LDRi8:
454
0
  case ARM::t2LDRHi8:
455
0
  case ARM::t2LDRBi8:
456
0
  case ARM::t2LDRSHi8:
457
0
  case ARM::t2LDRSBi8:
458
0
  case ARM::t2STRi8:
459
0
  case ARM::t2STRBi8:
460
0
  case ARM::t2STRHi8:
461
0
  case ARM::t2PLDi8:
462
0
    return opcode;
463
0
464
0
  default:
465
0
    break;
466
0
  }
467
0
468
0
  return 0;
469
0
}
470
471
bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
472
                               unsigned FrameReg, int &Offset,
473
50.5k
                               const ARMBaseInstrInfo &TII) {
474
50.5k
  unsigned Opcode = MI.getOpcode();
475
50.5k
  const MCInstrDesc &Desc = MI.getDesc();
476
50.5k
  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
477
50.5k
  bool isSub = false;
478
50.5k
479
50.5k
  // Memory operands in inline assembly always use AddrModeT2_i12.
480
50.5k
  if (Opcode == ARM::INLINEASM || Opcode == ARM::INLINEASM_BR)
481
0
    AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
482
50.5k
483
50.5k
  if (Opcode == ARM::t2ADDri || 
Opcode == ARM::t2ADDri1241.0k
) {
484
9.45k
    Offset += MI.getOperand(FrameRegIdx+1).getImm();
485
9.45k
486
9.45k
    unsigned PredReg;
487
9.45k
    if (Offset == 0 && 
getInstrPredicate(MI, PredReg) == ARMCC::AL647
&&
488
9.45k
        
!MI.definesRegister(ARM::CPSR)647
) {
489
646
      // Turn it into a move.
490
646
      MI.setDesc(TII.get(ARM::tMOVr));
491
646
      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
492
646
      // Remove offset and remaining explicit predicate operands.
493
2.58k
      do MI.RemoveOperand(FrameRegIdx+1);
494
2.58k
      while (MI.getNumOperands() > FrameRegIdx+1);
495
646
      MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI);
496
646
      MIB.add(predOps(ARMCC::AL));
497
646
      return true;
498
646
    }
499
8.80k
500
8.80k
    bool HasCCOut = Opcode != ARM::t2ADDri12;
501
8.80k
502
8.80k
    if (Offset < 0) {
503
361
      Offset = -Offset;
504
361
      isSub = true;
505
361
      MI.setDesc(TII.get(ARM::t2SUBri));
506
8.44k
    } else {
507
8.44k
      MI.setDesc(TII.get(ARM::t2ADDri));
508
8.44k
    }
509
8.80k
510
8.80k
    // Common case: small offset, fits into instruction.
511
8.80k
    if (ARM_AM::getT2SOImmVal(Offset) != -1) {
512
8.49k
      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
513
8.49k
      MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
514
8.49k
      // Add cc_out operand if the original instruction did not have one.
515
8.49k
      if (!HasCCOut)
516
0
        MI.addOperand(MachineOperand::CreateReg(0, false));
517
8.49k
      Offset = 0;
518
8.49k
      return true;
519
8.49k
    }
520
309
    // Another common case: imm12.
521
309
    if (Offset < 4096 &&
522
309
        
(293
!HasCCOut293
||
MI.getOperand(MI.getNumOperands()-1).getReg() == 0293
)) {
523
293
      unsigned NewOpc = isSub ? 
ARM::t2SUBri120
: ARM::t2ADDri12;
524
293
      MI.setDesc(TII.get(NewOpc));
525
293
      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
526
293
      MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
527
293
      // Remove the cc_out operand.
528
293
      if (HasCCOut)
529
293
        MI.RemoveOperand(MI.getNumOperands()-1);
530
293
      Offset = 0;
531
293
      return true;
532
293
    }
533
16
534
16
    // Otherwise, extract 8 adjacent bits from the immediate into this
535
16
    // t2ADDri/t2SUBri.
536
16
    unsigned RotAmt = countLeadingZeros<unsigned>(Offset);
537
16
    unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt);
538
16
539
16
    // We will handle these bits from offset, clear them.
540
16
    Offset &= ~ThisImmVal;
541
16
542
16
    assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
543
16
           "Bit extraction didn't work?");
544
16
    MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
545
16
    // Add cc_out operand if the original instruction did not have one.
546
16
    if (!HasCCOut)
547
0
      MI.addOperand(MachineOperand::CreateReg(0, false));
548
41.0k
  } else {
549
41.0k
    // AddrMode4 and AddrMode6 cannot handle any offset.
550
41.0k
    if (AddrMode == ARMII::AddrMode4 || 
AddrMode == ARMII::AddrMode641.0k
)
551
622
      return false;
552
40.4k
553
40.4k
    // AddrModeT2_so cannot handle any offset. If there is no offset
554
40.4k
    // register then we change to an immediate version.
555
40.4k
    unsigned NewOpc = Opcode;
556
40.4k
    if (AddrMode == ARMII::AddrModeT2_so) {
557
0
      unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg();
558
0
      if (OffsetReg != 0) {
559
0
        MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
560
0
        return Offset == 0;
561
0
      }
562
0
563
0
      MI.RemoveOperand(FrameRegIdx+1);
564
0
      MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
565
0
      NewOpc = immediateOffsetOpcode(Opcode);
566
0
      AddrMode = ARMII::AddrModeT2_i12;
567
0
    }
568
40.4k
569
40.4k
    unsigned NumBits = 0;
570
40.4k
    unsigned Scale = 1;
571
40.4k
    if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) {
572
38.7k
      // i8 supports only negative, and i12 supports only positive, so
573
38.7k
      // based on Offset sign convert Opcode to the appropriate
574
38.7k
      // instruction
575
38.7k
      Offset += MI.getOperand(FrameRegIdx+1).getImm();
576
38.7k
      if (Offset < 0) {
577
588
        NewOpc = negativeOffsetOpcode(Opcode);
578
588
        NumBits = 8;
579
588
        isSub = true;
580
588
        Offset = -Offset;
581
38.1k
      } else {
582
38.1k
        NewOpc = positiveOffsetOpcode(Opcode);
583
38.1k
        NumBits = 12;
584
38.1k
      }
585
38.7k
    } else 
if (1.74k
AddrMode == ARMII::AddrMode51.74k
) {
586
1.68k
      // VFP address mode.
587
1.68k
      const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
588
1.68k
      int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
589
1.68k
      if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
590
0
        InstrOffs *= -1;
591
1.68k
      NumBits = 8;
592
1.68k
      Scale = 4;
593
1.68k
      Offset += InstrOffs * 4;
594
1.68k
      assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
595
1.68k
      if (Offset < 0) {
596
0
        Offset = -Offset;
597
0
        isSub = true;
598
0
      }
599
1.68k
    } else 
if (57
AddrMode == ARMII::AddrMode5FP1657
) {
600
39
      // VFP address mode.
601
39
      const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
602
39
      int InstrOffs = ARM_AM::getAM5FP16Offset(OffOp.getImm());
603
39
      if (ARM_AM::getAM5FP16Op(OffOp.getImm()) == ARM_AM::sub)
604
0
        InstrOffs *= -1;
605
39
      NumBits = 8;
606
39
      Scale = 2;
607
39
      Offset += InstrOffs * 2;
608
39
      assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
609
39
      if (Offset < 0) {
610
1
        Offset = -Offset;
611
1
        isSub = true;
612
1
      }
613
39
    } else 
if (18
AddrMode == ARMII::AddrModeT2_i7s418
||
614
18
               
AddrMode == ARMII::AddrModeT2_i7s216
||
615
18
               
AddrMode == ARMII::AddrModeT2_i714
) {
616
6
      Offset += MI.getOperand(FrameRegIdx + 1).getImm();
617
6
      unsigned OffsetMask;
618
6
      switch (AddrMode) {
619
6
      
case ARMII::AddrModeT2_i7s4: NumBits = 9; OffsetMask = 0x3; break2
;
620
6
      
case ARMII::AddrModeT2_i7s2: NumBits = 8; OffsetMask = 0x1; break2
;
621
6
      
default: NumBits = 7; OffsetMask = 0x0; break2
;
622
6
      }
623
6
      // MCInst operand expects already scaled value.
624
6
      Scale = 1;
625
6
      assert((Offset & OffsetMask) == 0 && "Can't encode this offset!");
626
6
      (void)OffsetMask; // squash unused-variable warning at -NDEBUG
627
12
    } else if (AddrMode == ARMII::AddrModeT2_i8s4) {
628
4
      Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
629
4
      NumBits = 8 + 2;
630
4
      // MCInst operand expects already scaled value.
631
4
      Scale = 1;
632
4
      assert((Offset & 3) == 0 && "Can't encode this offset!");
633
8
    } else if (AddrMode == ARMII::AddrModeT2_ldrex) {
634
8
      Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
635
8
      NumBits = 8; // 8 bits scaled by 4
636
8
      Scale = 4;
637
8
      assert((Offset & 3) == 0 && "Can't encode this offset!");
638
8
    } else {
639
0
      llvm_unreachable("Unsupported addressing mode!");
640
0
    }
641
40.4k
642
40.4k
    if (NewOpc != Opcode)
643
588
      MI.setDesc(TII.get(NewOpc));
644
40.4k
645
40.4k
    MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1);
646
40.4k
647
40.4k
    // Attempt to fold address computation
648
40.4k
    // Common case: small offset, fits into instruction.
649
40.4k
    int ImmedOffset = Offset / Scale;
650
40.4k
    unsigned Mask = (1 << NumBits) - 1;
651
40.4k
    if ((unsigned)Offset <= Mask * Scale) {
652
39.9k
      // Replace the FrameIndex with fp/sp
653
39.9k
      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
654
39.9k
      if (isSub) {
655
589
        if (AddrMode == ARMII::AddrMode5 || AddrMode == ARMII::AddrMode5FP16)
656
1
          // FIXME: Not consistent.
657
1
          ImmedOffset |= 1 << NumBits;
658
588
        else
659
588
          ImmedOffset = -ImmedOffset;
660
589
      }
661
39.9k
      ImmOp.ChangeToImmediate(ImmedOffset);
662
39.9k
      Offset = 0;
663
39.9k
      return true;
664
39.9k
    }
665
487
666
487
    // Otherwise, offset doesn't fit. Pull in what we can to simplify
667
487
    ImmedOffset = ImmedOffset & Mask;
668
487
    if (isSub) {
669
0
      if (AddrMode == ARMII::AddrMode5 || AddrMode == ARMII::AddrMode5FP16)
670
0
        // FIXME: Not consistent.
671
0
        ImmedOffset |= 1 << NumBits;
672
0
      else {
673
0
        ImmedOffset = -ImmedOffset;
674
0
        if (ImmedOffset == 0)
675
0
          // Change the opcode back if the encoded offset is zero.
676
0
          MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc)));
677
0
      }
678
0
    }
679
487
    ImmOp.ChangeToImmediate(ImmedOffset);
680
487
    Offset &= ~(Mask*Scale);
681
487
  }
682
50.5k
683
50.5k
  
Offset = (isSub) 503
?
-Offset0
:
Offset503
;
684
503
  return Offset == 0;
685
50.5k
}
686
687
ARMCC::CondCodes llvm::getITInstrPredicate(const MachineInstr &MI,
688
698k
                                           unsigned &PredReg) {
689
698k
  unsigned Opc = MI.getOpcode();
690
698k
  if (Opc == ARM::tBcc || 
Opc == ARM::t2Bcc698k
)
691
43.0k
    return ARMCC::AL;
692
655k
  return getInstrPredicate(MI, PredReg);
693
655k
}
694
695
11.4k
int llvm::findFirstVPTPredOperandIdx(const MachineInstr &MI) {
696
11.4k
  const MCInstrDesc &MCID = MI.getDesc();
697
11.4k
698
11.4k
  if (!MCID.OpInfo)
699
12
    return -1;
700
11.4k
701
55.6k
  
for (unsigned i = 0, e = MCID.getNumOperands(); 11.4k
i != e;
++i44.2k
)
702
45.3k
    if (ARM::isVpred(MCID.OpInfo[i].OperandType))
703
1.16k
      return i;
704
11.4k
705
11.4k
  
return -110.2k
;
706
11.4k
}
707
708
ARMVCC::VPTCodes llvm::getVPTInstrPredicate(const MachineInstr &MI,
709
11.4k
                                            unsigned &PredReg) {
710
11.4k
  int PIdx = findFirstVPTPredOperandIdx(MI);
711
11.4k
  if (PIdx == -1) {
712
10.2k
    PredReg = 0;
713
10.2k
    return ARMVCC::None;
714
10.2k
  }
715
1.16k
716
1.16k
  PredReg = MI.getOperand(PIdx+1).getReg();
717
1.16k
  return (ARMVCC::VPTCodes)MI.getOperand(PIdx).getImm();
718
1.16k
}