Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- Thumb2InstrInfo.cpp - Thumb-2 Instruction Information --------------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This file contains the Thumb-2 implementation of the TargetInstrInfo class.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "ARMMachineFunctionInfo.h"
15
#include "MCTargetDesc/ARMAddressingModes.h"
16
#include "Thumb2InstrInfo.h"
17
#include "llvm/CodeGen/MachineBasicBlock.h"
18
#include "llvm/CodeGen/MachineFrameInfo.h"
19
#include "llvm/CodeGen/MachineFunction.h"
20
#include "llvm/CodeGen/MachineInstr.h"
21
#include "llvm/CodeGen/MachineInstrBuilder.h"
22
#include "llvm/CodeGen/MachineMemOperand.h"
23
#include "llvm/CodeGen/MachineOperand.h"
24
#include "llvm/CodeGen/MachineRegisterInfo.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 "llvm/Target/TargetRegisterInfo.h"
33
#include <cassert>
34
35
using namespace llvm;
36
37
static cl::opt<bool>
38
OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden,
39
           cl::desc("Use old-style Thumb2 if-conversion heuristics"),
40
           cl::init(false));
41
42
Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
43
2.76k
    : ARMBaseInstrInfo(STI) {}
44
45
/// Return the noop instruction to use for a noop.
46
2
void Thumb2InstrInfo::getNoop(MCInst &NopInst) const {
47
2
  NopInst.setOpcode(ARM::tHINT);
48
2
  NopInst.addOperand(MCOperand::createImm(0));
49
2
  NopInst.addOperand(MCOperand::createImm(ARMCC::AL));
50
2
  NopInst.addOperand(MCOperand::createReg(0));
51
2
}
52
53
0
unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {
54
0
  // FIXME
55
0
  return 0;
56
0
}
57
58
void
59
Thumb2InstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
60
3.46k
                                         MachineBasicBlock *NewDest) const {
61
3.46k
  MachineBasicBlock *MBB = Tail->getParent();
62
3.46k
  ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
63
3.46k
  if (
!AFI->hasITBlocks() || 3.46k
Tail->isBranch()227
) {
64
3.23k
    TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest);
65
3.23k
    return;
66
3.23k
  }
67
227
68
227
  // If the first instruction of Tail is predicated, we may have to update
69
227
  // the IT instruction.
70
227
  unsigned PredReg = 0;
71
227
  ARMCC::CondCodes CC = getInstrPredicate(*Tail, PredReg);
72
227
  MachineBasicBlock::iterator MBBI = Tail;
73
227
  if (CC != ARMCC::AL)
74
227
    // Expecting at least the t2IT instruction before it.
75
0
    --MBBI;
76
227
77
227
  // Actually replace the tail.
78
227
  TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest);
79
227
80
227
  // Fix up IT.
81
227
  if (
CC != ARMCC::AL227
) {
82
0
    MachineBasicBlock::iterator E = MBB->begin();
83
0
    unsigned Count = 4; // At most 4 instructions in an IT block.
84
0
    while (
Count && 0
MBBI != E0
) {
85
0
      if (
MBBI->isDebugValue()0
) {
86
0
        --MBBI;
87
0
        continue;
88
0
      }
89
0
      
if (0
MBBI->getOpcode() == ARM::t2IT0
) {
90
0
        unsigned Mask = MBBI->getOperand(1).getImm();
91
0
        if (Count == 4)
92
0
          MBBI->eraseFromParent();
93
0
        else {
94
0
          unsigned MaskOn = 1 << Count;
95
0
          unsigned MaskOff = ~(MaskOn - 1);
96
0
          MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
97
0
        }
98
0
        return;
99
0
      }
100
0
      --MBBI;
101
0
      --Count;
102
0
    }
103
0
104
0
    // Ctrl flow can reach here if branch folding is run before IT block
105
0
    // formation pass.
106
0
  }
107
3.46k
}
108
109
bool
110
Thumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB,
111
788
                                     MachineBasicBlock::iterator MBBI) const {
112
788
  while (
MBBI->isDebugValue()788
) {
113
0
    ++MBBI;
114
0
    if (MBBI == MBB.end())
115
0
      return false;
116
0
  }
117
788
118
788
  unsigned PredReg = 0;
119
788
  return getITInstrPredicate(*MBBI, PredReg) == ARMCC::AL;
120
788
}
121
122
void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
123
                                  MachineBasicBlock::iterator I,
124
                                  const DebugLoc &DL, unsigned DestReg,
125
25.8k
                                  unsigned SrcReg, bool KillSrc) const {
126
25.8k
  // Handle SPR, DPR, and QPR copies.
127
25.8k
  if (!ARM::GPRRegClass.contains(DestReg, SrcReg))
128
3.34k
    return ARMBaseInstrInfo::copyPhysReg(MBB, I, DL, DestReg, SrcReg, KillSrc);
129
22.4k
130
22.4k
  BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)
131
22.4k
      .addReg(SrcReg, getKillRegState(KillSrc))
132
22.4k
      .add(predOps(ARMCC::AL));
133
22.4k
}
134
135
void Thumb2InstrInfo::
136
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
137
                    unsigned SrcReg, bool isKill, int FI,
138
                    const TargetRegisterClass *RC,
139
3.41k
                    const TargetRegisterInfo *TRI) const {
140
3.41k
  DebugLoc DL;
141
3.41k
  if (
I != MBB.end()3.41k
)
DL = I->getDebugLoc()3.34k
;
142
3.41k
143
3.41k
  MachineFunction &MF = *MBB.getParent();
144
3.41k
  MachineFrameInfo &MFI = MF.getFrameInfo();
145
3.41k
  MachineMemOperand *MMO = MF.getMachineMemOperand(
146
3.41k
      MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
147
3.41k
      MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
148
3.41k
149
3.41k
  if (
RC == &ARM::GPRRegClass || 3.41k
RC == &ARM::tGPRRegClass1.74k
||
150
3.41k
      
RC == &ARM::tcGPRRegClass1.72k
||
RC == &ARM::rGPRRegClass1.72k
||
151
3.41k
      
RC == &ARM::GPRnopcRegClass936
) {
152
2.84k
    BuildMI(MBB, I, DL, get(ARM::t2STRi12))
153
2.84k
        .addReg(SrcReg, getKillRegState(isKill))
154
2.84k
        .addFrameIndex(FI)
155
2.84k
        .addImm(0)
156
2.84k
        .addMemOperand(MMO)
157
2.84k
        .add(predOps(ARMCC::AL));
158
2.84k
    return;
159
2.84k
  }
160
575
161
575
  
if (575
ARM::GPRPairRegClass.hasSubClassEq(RC)575
) {
162
3
    // Thumb2 STRD expects its dest-registers to be in rGPR. Not a problem for
163
3
    // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
164
3
    // otherwise).
165
3
    if (
TargetRegisterInfo::isVirtualRegister(SrcReg)3
) {
166
2
      MachineRegisterInfo *MRI = &MF.getRegInfo();
167
2
      MRI->constrainRegClass(SrcReg, &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
168
2
    }
169
3
170
3
    MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2STRDi8));
171
3
    AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill), TRI);
172
3
    AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
173
3
    MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO).add(predOps(ARMCC::AL));
174
3
    return;
175
3
  }
176
572
177
572
  ARMBaseInstrInfo::storeRegToStackSlot(MBB, I, SrcReg, isKill, FI, RC, TRI);
178
572
}
179
180
void Thumb2InstrInfo::
181
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
182
                     unsigned DestReg, int FI,
183
                     const TargetRegisterClass *RC,
184
4.15k
                     const TargetRegisterInfo *TRI) const {
185
4.15k
  MachineFunction &MF = *MBB.getParent();
186
4.15k
  MachineFrameInfo &MFI = MF.getFrameInfo();
187
4.15k
  MachineMemOperand *MMO = MF.getMachineMemOperand(
188
4.15k
      MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
189
4.15k
      MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
190
4.15k
  DebugLoc DL;
191
4.15k
  if (
I != MBB.end()4.15k
)
DL = I->getDebugLoc()4.15k
;
192
4.15k
193
4.15k
  if (
RC == &ARM::GPRRegClass || 4.15k
RC == &ARM::tGPRRegClass2.17k
||
194
4.15k
      
RC == &ARM::tcGPRRegClass2.17k
||
RC == &ARM::rGPRRegClass2.17k
||
195
4.15k
      
RC == &ARM::GPRnopcRegClass1.24k
) {
196
3.46k
    BuildMI(MBB, I, DL, get(ARM::t2LDRi12), DestReg)
197
3.46k
        .addFrameIndex(FI)
198
3.46k
        .addImm(0)
199
3.46k
        .addMemOperand(MMO)
200
3.46k
        .add(predOps(ARMCC::AL));
201
3.46k
    return;
202
3.46k
  }
203
685
204
685
  
if (685
ARM::GPRPairRegClass.hasSubClassEq(RC)685
) {
205
2
    // Thumb2 LDRD expects its dest-registers to be in rGPR. Not a problem for
206
2
    // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
207
2
    // otherwise).
208
2
    if (
TargetRegisterInfo::isVirtualRegister(DestReg)2
) {
209
2
      MachineRegisterInfo *MRI = &MF.getRegInfo();
210
2
      MRI->constrainRegClass(DestReg,
211
2
                             &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
212
2
    }
213
2
214
2
    MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2LDRDi8));
215
2
    AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead, TRI);
216
2
    AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead, TRI);
217
2
    MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO).add(predOps(ARMCC::AL));
218
2
219
2
    if (TargetRegisterInfo::isPhysicalRegister(DestReg))
220
0
      MIB.addReg(DestReg, RegState::ImplicitDefine);
221
2
    return;
222
2
  }
223
683
224
683
  ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI);
225
683
}
226
227
void Thumb2InstrInfo::expandLoadStackGuard(
228
130
    MachineBasicBlock::iterator MI) const {
229
130
  MachineFunction &MF = *MI->getParent()->getParent();
230
130
  if (MF.getTarget().isPositionIndependent())
231
126
    expandLoadStackGuardBase(MI, ARM::t2MOV_ga_pcrel, ARM::t2LDRi12);
232
130
  else
233
4
    expandLoadStackGuardBase(MI, ARM::t2MOVi32imm, ARM::t2LDRi12);
234
130
}
235
236
void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
237
                                  MachineBasicBlock::iterator &MBBI,
238
                                  const DebugLoc &dl, unsigned DestReg,
239
                                  unsigned BaseReg, int NumBytes,
240
                                  ARMCC::CondCodes Pred, unsigned PredReg,
241
                                  const ARMBaseInstrInfo &TII,
242
8.01k
                                  unsigned MIFlags) {
243
8.01k
  if (
NumBytes == 0 && 8.01k
DestReg != BaseReg658
) {
244
658
    BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
245
658
      .addReg(BaseReg, RegState::Kill)
246
658
      .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
247
658
    return;
248
658
  }
249
7.36k
250
7.36k
  bool isSub = NumBytes < 0;
251
7.36k
  if (
isSub7.36k
)
NumBytes = -NumBytes2.09k
;
252
7.36k
253
7.36k
  // If profitable, use a movw or movt to materialize the offset.
254
7.36k
  // FIXME: Use the scavenger to grab a scratch register.
255
7.36k
  if (
DestReg != ARM::SP && 7.36k
DestReg != BaseReg3.52k
&&
256
3.52k
      NumBytes >= 4096 &&
257
7.36k
      
ARM_AM::getT2SOImmVal(NumBytes) == -1315
) {
258
66
    bool Fits = false;
259
66
    if (
NumBytes < 6553666
) {
260
66
      // Use a movw to materialize the 16-bit constant.
261
66
      BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
262
66
        .addImm(NumBytes)
263
66
        .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
264
66
      Fits = true;
265
66
    } else 
if (0
(NumBytes & 0xffff) == 00
) {
266
0
      // Use a movt to materialize the 32-bit constant.
267
0
      BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
268
0
        .addReg(DestReg)
269
0
        .addImm(NumBytes >> 16)
270
0
        .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
271
0
      Fits = true;
272
0
    }
273
66
274
66
    if (
Fits66
) {
275
66
      if (
isSub66
) {
276
0
        BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
277
0
            .addReg(BaseReg)
278
0
            .addReg(DestReg, RegState::Kill)
279
0
            .add(predOps(Pred, PredReg))
280
0
            .add(condCodeOp())
281
0
            .setMIFlags(MIFlags);
282
66
      } else {
283
66
        // Here we know that DestReg is not SP but we do not
284
66
        // know anything about BaseReg. t2ADDrr is an invalid
285
66
        // instruction is SP is used as the second argument, but
286
66
        // is fine if SP is the first argument. To be sure we
287
66
        // do not generate invalid encoding, put BaseReg first.
288
66
        BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
289
66
            .addReg(BaseReg)
290
66
            .addReg(DestReg, RegState::Kill)
291
66
            .add(predOps(Pred, PredReg))
292
66
            .add(condCodeOp())
293
66
            .setMIFlags(MIFlags);
294
66
      }
295
66
      return;
296
66
    }
297
7.29k
  }
298
7.29k
299
14.6k
  
while (7.29k
NumBytes14.6k
) {
300
7.32k
    unsigned ThisVal = NumBytes;
301
7.32k
    unsigned Opc = 0;
302
7.32k
    if (
DestReg == ARM::SP && 7.32k
BaseReg != ARM::SP3.86k
) {
303
0
      // mov sp, rn. Note t2MOVr cannot be used.
304
0
      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
305
0
          .addReg(BaseReg)
306
0
          .setMIFlags(MIFlags)
307
0
          .add(predOps(ARMCC::AL));
308
0
      BaseReg = ARM::SP;
309
0
      continue;
310
0
    }
311
7.32k
312
7.32k
    bool HasCCOut = true;
313
7.32k
    if (
BaseReg == ARM::SP7.32k
) {
314
6.86k
      // sub sp, sp, #imm7
315
6.86k
      if (
DestReg == ARM::SP && 6.86k
(ThisVal < ((1 << 7)-1) * 4)3.86k
) {
316
3.73k
        assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?");
317
3.73k
        Opc = isSub ? 
ARM::tSUBspi1.88k
:
ARM::tADDspi1.85k
;
318
3.73k
        BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
319
3.73k
            .addReg(BaseReg)
320
3.73k
            .addImm(ThisVal / 4)
321
3.73k
            .setMIFlags(MIFlags)
322
3.73k
            .add(predOps(ARMCC::AL));
323
3.73k
        NumBytes = 0;
324
3.73k
        continue;
325
3.73k
      }
326
3.13k
327
3.13k
      // sub rd, sp, so_imm
328
3.13k
      
Opc = isSub ? 3.13k
ARM::t2SUBri70
:
ARM::t2ADDri3.06k
;
329
3.13k
      if (
ARM_AM::getT2SOImmVal(NumBytes) != -13.13k
) {
330
3.09k
        NumBytes = 0;
331
3.13k
      } else {
332
32
        // FIXME: Move this to ARMAddressingModes.h?
333
32
        unsigned RotAmt = countLeadingZeros(ThisVal);
334
32
        ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
335
32
        NumBytes &= ~ThisVal;
336
32
        assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
337
32
               "Bit extraction didn't work?");
338
32
      }
339
7.32k
    } else {
340
460
      assert(DestReg != ARM::SP && BaseReg != ARM::SP);
341
460
      Opc = isSub ? 
ARM::t2SUBri158
:
ARM::t2ADDri302
;
342
460
      if (
ARM_AM::getT2SOImmVal(NumBytes) != -1460
) {
343
460
        NumBytes = 0;
344
460
      } else 
if (0
ThisVal < 40960
) {
345
0
        Opc = isSub ? 
ARM::t2SUBri120
:
ARM::t2ADDri120
;
346
0
        HasCCOut = false;
347
0
        NumBytes = 0;
348
0
      } else {
349
0
        // FIXME: Move this to ARMAddressingModes.h?
350
0
        unsigned RotAmt = countLeadingZeros(ThisVal);
351
0
        ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
352
0
        NumBytes &= ~ThisVal;
353
0
        assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
354
0
               "Bit extraction didn't work?");
355
0
      }
356
460
    }
357
7.32k
358
7.32k
    // Build the new ADD / SUB.
359
3.59k
    MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
360
3.59k
                                  .addReg(BaseReg, RegState::Kill)
361
3.59k
                                  .addImm(ThisVal)
362
3.59k
                                  .add(predOps(ARMCC::AL))
363
3.59k
                                  .setMIFlags(MIFlags);
364
3.59k
    if (HasCCOut)
365
3.59k
      MIB.add(condCodeOp());
366
7.32k
367
7.32k
    BaseReg = DestReg;
368
7.32k
  }
369
8.01k
}
370
371
static unsigned
372
negativeOffsetOpcode(unsigned opcode)
373
219
{
374
219
  switch (opcode) {
375
98
  case ARM::t2LDRi12:   return ARM::t2LDRi8;
376
0
  case ARM::t2LDRHi12:  return ARM::t2LDRHi8;
377
0
  case ARM::t2LDRBi12:  return ARM::t2LDRBi8;
378
0
  case ARM::t2LDRSHi12: return ARM::t2LDRSHi8;
379
0
  case ARM::t2LDRSBi12: return ARM::t2LDRSBi8;
380
121
  case ARM::t2STRi12:   return ARM::t2STRi8;
381
0
  case ARM::t2STRBi12:  return ARM::t2STRBi8;
382
0
  case ARM::t2STRHi12:  return ARM::t2STRHi8;
383
0
  case ARM::t2PLDi12:   return ARM::t2PLDi8;
384
219
385
0
  case ARM::t2LDRi8:
386
0
  case ARM::t2LDRHi8:
387
0
  case ARM::t2LDRBi8:
388
0
  case ARM::t2LDRSHi8:
389
0
  case ARM::t2LDRSBi8:
390
0
  case ARM::t2STRi8:
391
0
  case ARM::t2STRBi8:
392
0
  case ARM::t2STRHi8:
393
0
  case ARM::t2PLDi8:
394
0
    return opcode;
395
0
396
0
  default:
397
0
    break;
398
0
  }
399
0
400
0
  return 0;
401
0
}
402
403
static unsigned
404
positiveOffsetOpcode(unsigned opcode)
405
11.4k
{
406
11.4k
  switch (opcode) {
407
0
  case ARM::t2LDRi8:   return ARM::t2LDRi12;
408
0
  case ARM::t2LDRHi8:  return ARM::t2LDRHi12;
409
0
  case ARM::t2LDRBi8:  return ARM::t2LDRBi12;
410
0
  case ARM::t2LDRSHi8: return ARM::t2LDRSHi12;
411
0
  case ARM::t2LDRSBi8: return ARM::t2LDRSBi12;
412
0
  case ARM::t2STRi8:   return ARM::t2STRi12;
413
0
  case ARM::t2STRBi8:  return ARM::t2STRBi12;
414
0
  case ARM::t2STRHi8:  return ARM::t2STRHi12;
415
0
  case ARM::t2PLDi8:   return ARM::t2PLDi12;
416
11.4k
417
11.4k
  case ARM::t2LDRi12:
418
11.4k
  case ARM::t2LDRHi12:
419
11.4k
  case ARM::t2LDRBi12:
420
11.4k
  case ARM::t2LDRSHi12:
421
11.4k
  case ARM::t2LDRSBi12:
422
11.4k
  case ARM::t2STRi12:
423
11.4k
  case ARM::t2STRBi12:
424
11.4k
  case ARM::t2STRHi12:
425
11.4k
  case ARM::t2PLDi12:
426
11.4k
    return opcode;
427
11.4k
428
0
  default:
429
0
    break;
430
0
  }
431
0
432
0
  return 0;
433
0
}
434
435
static unsigned
436
immediateOffsetOpcode(unsigned opcode)
437
0
{
438
0
  switch (opcode) {
439
0
  case ARM::t2LDRs:   return ARM::t2LDRi12;
440
0
  case ARM::t2LDRHs:  return ARM::t2LDRHi12;
441
0
  case ARM::t2LDRBs:  return ARM::t2LDRBi12;
442
0
  case ARM::t2LDRSHs: return ARM::t2LDRSHi12;
443
0
  case ARM::t2LDRSBs: return ARM::t2LDRSBi12;
444
0
  case ARM::t2STRs:   return ARM::t2STRi12;
445
0
  case ARM::t2STRBs:  return ARM::t2STRBi12;
446
0
  case ARM::t2STRHs:  return ARM::t2STRHi12;
447
0
  case ARM::t2PLDs:   return ARM::t2PLDi12;
448
0
449
0
  case ARM::t2LDRi12:
450
0
  case ARM::t2LDRHi12:
451
0
  case ARM::t2LDRBi12:
452
0
  case ARM::t2LDRSHi12:
453
0
  case ARM::t2LDRSBi12:
454
0
  case ARM::t2STRi12:
455
0
  case ARM::t2STRBi12:
456
0
  case ARM::t2STRHi12:
457
0
  case ARM::t2PLDi12:
458
0
  case ARM::t2LDRi8:
459
0
  case ARM::t2LDRHi8:
460
0
  case ARM::t2LDRBi8:
461
0
  case ARM::t2LDRSHi8:
462
0
  case ARM::t2LDRSBi8:
463
0
  case ARM::t2STRi8:
464
0
  case ARM::t2STRBi8:
465
0
  case ARM::t2STRHi8:
466
0
  case ARM::t2PLDi8:
467
0
    return opcode;
468
0
469
0
  default:
470
0
    break;
471
0
  }
472
0
473
0
  return 0;
474
0
}
475
476
bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
477
                               unsigned FrameReg, int &Offset,
478
15.1k
                               const ARMBaseInstrInfo &TII) {
479
15.1k
  unsigned Opcode = MI.getOpcode();
480
15.1k
  const MCInstrDesc &Desc = MI.getDesc();
481
15.1k
  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
482
15.1k
  bool isSub = false;
483
15.1k
484
15.1k
  // Memory operands in inline assembly always use AddrModeT2_i12.
485
15.1k
  if (Opcode == ARM::INLINEASM)
486
0
    AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
487
15.1k
488
15.1k
  if (
Opcode == ARM::t2ADDri || 15.1k
Opcode == ARM::t2ADDri1213.0k
) {
489
2.02k
    Offset += MI.getOperand(FrameRegIdx+1).getImm();
490
2.02k
491
2.02k
    unsigned PredReg;
492
2.02k
    if (
Offset == 0 && 2.02k
getInstrPredicate(MI, PredReg) == ARMCC::AL228
) {
493
228
      // Turn it into a move.
494
228
      MI.setDesc(TII.get(ARM::tMOVr));
495
228
      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
496
228
      // Remove offset and remaining explicit predicate operands.
497
912
      do MI.RemoveOperand(FrameRegIdx+1);
498
912
      while (MI.getNumOperands() > FrameRegIdx+1);
499
228
      MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI);
500
228
      MIB.add(predOps(ARMCC::AL));
501
228
      return true;
502
228
    }
503
1.79k
504
1.79k
    bool HasCCOut = Opcode != ARM::t2ADDri12;
505
1.79k
506
1.79k
    if (
Offset < 01.79k
) {
507
45
      Offset = -Offset;
508
45
      isSub = true;
509
45
      MI.setDesc(TII.get(ARM::t2SUBri));
510
1.79k
    } else {
511
1.75k
      MI.setDesc(TII.get(ARM::t2ADDri));
512
1.75k
    }
513
1.79k
514
1.79k
    // Common case: small offset, fits into instruction.
515
1.79k
    if (
ARM_AM::getT2SOImmVal(Offset) != -11.79k
) {
516
1.50k
      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
517
1.50k
      MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
518
1.50k
      // Add cc_out operand if the original instruction did not have one.
519
1.50k
      if (!HasCCOut)
520
0
        MI.addOperand(MachineOperand::CreateReg(0, false));
521
1.50k
      Offset = 0;
522
1.50k
      return true;
523
1.50k
    }
524
291
    // Another common case: imm12.
525
291
    
if (291
Offset < 4096 &&
526
291
        
(!HasCCOut || 279
MI.getOperand(MI.getNumOperands()-1).getReg() == 0279
)) {
527
279
      unsigned NewOpc = isSub ? 
ARM::t2SUBri120
:
ARM::t2ADDri12279
;
528
279
      MI.setDesc(TII.get(NewOpc));
529
279
      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
530
279
      MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
531
279
      // Remove the cc_out operand.
532
279
      if (HasCCOut)
533
279
        MI.RemoveOperand(MI.getNumOperands()-1);
534
279
      Offset = 0;
535
279
      return true;
536
279
    }
537
12
538
12
    // Otherwise, extract 8 adjacent bits from the immediate into this
539
12
    // t2ADDri/t2SUBri.
540
12
    unsigned RotAmt = countLeadingZeros<unsigned>(Offset);
541
12
    unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt);
542
12
543
12
    // We will handle these bits from offset, clear them.
544
12
    Offset &= ~ThisImmVal;
545
12
546
12
    assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
547
12
           "Bit extraction didn't work?");
548
12
    MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
549
12
    // Add cc_out operand if the original instruction did not have one.
550
12
    if (!HasCCOut)
551
0
      MI.addOperand(MachineOperand::CreateReg(0, false));
552
15.1k
  } else {
553
13.0k
    // AddrMode4 and AddrMode6 cannot handle any offset.
554
13.0k
    if (
AddrMode == ARMII::AddrMode4 || 13.0k
AddrMode == ARMII::AddrMode613.0k
)
555
596
      return false;
556
12.5k
557
12.5k
    // AddrModeT2_so cannot handle any offset. If there is no offset
558
12.5k
    // register then we change to an immediate version.
559
12.5k
    unsigned NewOpc = Opcode;
560
12.5k
    if (
AddrMode == ARMII::AddrModeT2_so12.5k
) {
561
0
      unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg();
562
0
      if (
OffsetReg != 00
) {
563
0
        MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
564
0
        return Offset == 0;
565
0
      }
566
0
567
0
      MI.RemoveOperand(FrameRegIdx+1);
568
0
      MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
569
0
      NewOpc = immediateOffsetOpcode(Opcode);
570
0
      AddrMode = ARMII::AddrModeT2_i12;
571
0
    }
572
12.5k
573
12.5k
    unsigned NumBits = 0;
574
12.5k
    unsigned Scale = 1;
575
12.5k
    if (
AddrMode == ARMII::AddrModeT2_i8 || 12.5k
AddrMode == ARMII::AddrModeT2_i1212.5k
) {
576
11.6k
      // i8 supports only negative, and i12 supports only positive, so
577
11.6k
      // based on Offset sign convert Opcode to the appropriate
578
11.6k
      // instruction
579
11.6k
      Offset += MI.getOperand(FrameRegIdx+1).getImm();
580
11.6k
      if (
Offset < 011.6k
) {
581
219
        NewOpc = negativeOffsetOpcode(Opcode);
582
219
        NumBits = 8;
583
219
        isSub = true;
584
219
        Offset = -Offset;
585
11.6k
      } else {
586
11.4k
        NewOpc = positiveOffsetOpcode(Opcode);
587
11.4k
        NumBits = 12;
588
11.4k
      }
589
12.5k
    } else 
if (813
AddrMode == ARMII::AddrMode5813
) {
590
808
      // VFP address mode.
591
808
      const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
592
808
      int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
593
808
      if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
594
0
        InstrOffs *= -1;
595
808
      NumBits = 8;
596
808
      Scale = 4;
597
808
      Offset += InstrOffs * 4;
598
808
      assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
599
808
      if (
Offset < 0808
) {
600
0
        Offset = -Offset;
601
0
        isSub = true;
602
0
      }
603
813
    } else 
if (5
AddrMode == ARMII::AddrModeT2_i8s45
) {
604
5
      Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
605
5
      NumBits = 10; // 8 bits scaled by 4
606
5
      // MCInst operand expects already scaled value.
607
5
      Scale = 1;
608
5
      assert((Offset & 3) == 0 && "Can't encode this offset!");
609
5
    } else {
610
0
      llvm_unreachable("Unsupported addressing mode!");
611
813
    }
612
12.5k
613
12.5k
    
if (12.5k
NewOpc != Opcode12.5k
)
614
219
      MI.setDesc(TII.get(NewOpc));
615
12.5k
616
12.5k
    MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1);
617
12.5k
618
12.5k
    // Attempt to fold address computation
619
12.5k
    // Common case: small offset, fits into instruction.
620
12.5k
    int ImmedOffset = Offset / Scale;
621
12.5k
    unsigned Mask = (1 << NumBits) - 1;
622
12.5k
    if (
(unsigned)Offset <= Mask * Scale12.5k
) {
623
12.0k
      // Replace the FrameIndex with fp/sp
624
12.0k
      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
625
12.0k
      if (
isSub12.0k
) {
626
219
        if (AddrMode == ARMII::AddrMode5)
627
219
          // FIXME: Not consistent.
628
0
          ImmedOffset |= 1 << NumBits;
629
219
        else
630
219
          ImmedOffset = -ImmedOffset;
631
219
      }
632
12.0k
      ImmOp.ChangeToImmediate(ImmedOffset);
633
12.0k
      Offset = 0;
634
12.0k
      return true;
635
12.0k
    }
636
453
637
453
    // Otherwise, offset doesn't fit. Pull in what we can to simplify
638
453
    ImmedOffset = ImmedOffset & Mask;
639
453
    if (
isSub453
) {
640
0
      if (AddrMode == ARMII::AddrMode5)
641
0
        // FIXME: Not consistent.
642
0
        ImmedOffset |= 1 << NumBits;
643
0
      else {
644
0
        ImmedOffset = -ImmedOffset;
645
0
        if (ImmedOffset == 0)
646
0
          // Change the opcode back if the encoded offset is zero.
647
0
          MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc)));
648
0
      }
649
0
    }
650
13.0k
    ImmOp.ChangeToImmediate(ImmedOffset);
651
13.0k
    Offset &= ~(Mask*Scale);
652
13.0k
  }
653
15.1k
654
465
  
Offset = (isSub) ? 465
-Offset0
:
Offset465
;
655
465
  return Offset == 0;
656
15.1k
}
657
658
ARMCC::CondCodes llvm::getITInstrPredicate(const MachineInstr &MI,
659
302k
                                           unsigned &PredReg) {
660
302k
  unsigned Opc = MI.getOpcode();
661
302k
  if (
Opc == ARM::tBcc || 302k
Opc == ARM::t2Bcc302k
)
662
18.6k
    return ARMCC::AL;
663
284k
  return getInstrPredicate(MI, PredReg);
664
284k
}